ActivityManagerService.java revision 9ae46d8ee28cd709d81d2b48c44c47f4e4f485e8
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.ProcessStats;
31import com.android.internal.app.SystemUserHomeActivity;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.vr.VrManagerInternal;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
63
64import android.Manifest;
65import android.app.Activity;
66import android.app.ActivityManager;
67import android.app.ActivityManager.RunningTaskInfo;
68import android.app.ActivityManager.StackId;
69import android.app.ActivityManager.StackInfo;
70import android.app.ActivityManager.TaskThumbnailInfo;
71import android.app.ActivityManagerInternal;
72import android.app.ActivityManagerInternal.SleepToken;
73import android.app.ActivityManagerNative;
74import android.app.ActivityOptions;
75import android.app.ActivityThread;
76import android.app.AlertDialog;
77import android.app.AppGlobals;
78import android.app.AppOpsManager;
79import android.app.ApplicationErrorReport;
80import android.app.ApplicationThreadNative;
81import android.app.BroadcastOptions;
82import android.app.Dialog;
83import android.app.IActivityContainer;
84import android.app.IActivityContainerCallback;
85import android.app.IActivityController;
86import android.app.IAppTask;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.ITaskStackListener;
94import android.app.IUiAutomationConnection;
95import android.app.IUidObserver;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.ProfilerInfo;
102import android.app.admin.DevicePolicyManager;
103import android.app.assist.AssistContent;
104import android.app.assist.AssistStructure;
105import android.app.backup.IBackupManager;
106import android.app.usage.UsageEvents;
107import android.app.usage.UsageStatsManagerInternal;
108import android.appwidget.AppWidgetManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PackageManagerInternal;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.PathPermission;
136import android.content.pm.PermissionInfo;
137import android.content.pm.ProviderInfo;
138import android.content.pm.ResolveInfo;
139import android.content.pm.ServiceInfo;
140import android.content.pm.UserInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.content.res.Resources;
144import android.graphics.Bitmap;
145import android.graphics.Point;
146import android.graphics.Rect;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.BatteryStats;
151import android.os.Binder;
152import android.os.Build;
153import android.os.Bundle;
154import android.os.Debug;
155import android.os.DropBoxManager;
156import android.os.Environment;
157import android.os.FactoryTest;
158import android.os.FileObserver;
159import android.os.FileUtils;
160import android.os.Handler;
161import android.os.IBinder;
162import android.os.IPermissionController;
163import android.os.IProcessInfoService;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.PersistableBundle;
169import android.os.PowerManager;
170import android.os.PowerManagerInternal;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.ResultReceiver;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.Trace;
180import android.os.TransactionTooLargeException;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.os.WorkSource;
185import android.os.storage.IMountService;
186import android.os.storage.MountServiceInternal;
187import android.os.storage.StorageManager;
188import android.provider.Settings;
189import android.service.voice.IVoiceInteractionSession;
190import android.service.voice.VoiceInteractionSession;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.ArrayMap;
194import android.util.ArraySet;
195import android.util.AtomicFile;
196import android.util.DebugUtils;
197import android.util.EventLog;
198import android.util.LocaleList;
199import android.util.Log;
200import android.util.Pair;
201import android.util.PrintWriterPrinter;
202import android.util.Slog;
203import android.util.SparseArray;
204import android.util.TimeUtils;
205import android.util.Xml;
206import android.view.Display;
207import android.view.Gravity;
208import android.view.LayoutInflater;
209import android.view.View;
210import android.view.WindowManager;
211
212import java.io.BufferedInputStream;
213import java.io.BufferedOutputStream;
214import java.io.DataInputStream;
215import java.io.DataOutputStream;
216import java.io.File;
217import java.io.FileDescriptor;
218import java.io.FileInputStream;
219import java.io.FileNotFoundException;
220import java.io.FileOutputStream;
221import java.io.IOException;
222import java.io.InputStreamReader;
223import java.io.PrintWriter;
224import java.io.StringWriter;
225import java.lang.ref.WeakReference;
226import java.nio.charset.StandardCharsets;
227import java.util.ArrayList;
228import java.util.Arrays;
229import java.util.Collections;
230import java.util.Comparator;
231import java.util.HashMap;
232import java.util.HashSet;
233import java.util.Iterator;
234import java.util.List;
235import java.util.Locale;
236import java.util.Map;
237import java.util.Set;
238import java.util.concurrent.atomic.AtomicBoolean;
239import java.util.concurrent.atomic.AtomicLong;
240
241import dalvik.system.VMRuntime;
242import libcore.io.IoUtils;
243import libcore.util.EmptyArray;
244
245import static android.Manifest.permission.INTERACT_ACROSS_USERS;
246import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
247import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
248import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
249import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
250import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
251import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
252import static android.app.ActivityManager.StackId.HOME_STACK_ID;
253import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
254import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
255import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
256import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
257import static android.content.pm.PackageManager.PERMISSION_GRANTED;
258import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
259import static android.provider.Settings.Global.DEBUG_APP;
260import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
261import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
262import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
263import static com.android.internal.util.XmlUtils.readBooleanAttribute;
264import static com.android.internal.util.XmlUtils.readIntAttribute;
265import static com.android.internal.util.XmlUtils.readLongAttribute;
266import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
267import static com.android.internal.util.XmlUtils.writeIntAttribute;
268import static com.android.internal.util.XmlUtils.writeLongAttribute;
269import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
270import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
271import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
272import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
273import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
274import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
275import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
276import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
277import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
278import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
301import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
302import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
303import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
304import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
305import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
306import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
307import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
308import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
309import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
325import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
326import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
327import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
328import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
329import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
330import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
331import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
332import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
333import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
334import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
335import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
336import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
337import static org.xmlpull.v1.XmlPullParser.START_TAG;
338
339public final class ActivityManagerService extends ActivityManagerNative
340        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
341
342    // File that stores last updated system version and called preboot receivers
343    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
344
345    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
346    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
347    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
348    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
349    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
350    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
351    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
352    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
353    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
354    private static final String TAG_LRU = TAG + POSTFIX_LRU;
355    private static final String TAG_MU = TAG + POSTFIX_MU;
356    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
357    private static final String TAG_POWER = TAG + POSTFIX_POWER;
358    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
359    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
360    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
361    private static final String TAG_PSS = TAG + POSTFIX_PSS;
362    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
363    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
364    private static final String TAG_STACK = TAG + POSTFIX_STACK;
365    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
366    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
367    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
368    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
369    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
370
371    /** Control over CPU and battery monitoring */
372    // write battery stats every 30 minutes.
373    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
374    static final boolean MONITOR_CPU_USAGE = true;
375    // don't sample cpu less than every 5 seconds.
376    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
377    // wait possibly forever for next cpu sample.
378    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
379    static final boolean MONITOR_THREAD_CPU_USAGE = false;
380
381    // The flags that are set for all calls we make to the package manager.
382    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
383
384    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
385
386    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
387
388    // Amount of time after a call to stopAppSwitches() during which we will
389    // prevent further untrusted switches from happening.
390    static final long APP_SWITCH_DELAY_TIME = 5*1000;
391
392    // How long we wait for a launched process to attach to the activity manager
393    // before we decide it's never going to come up for real.
394    static final int PROC_START_TIMEOUT = 10*1000;
395    // How long we wait for an attached process to publish its content providers
396    // before we decide it must be hung.
397    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
398
399    // How long we will retain processes hosting content providers in the "last activity"
400    // state before allowing them to drop down to the regular cached LRU list.  This is
401    // to avoid thrashing of provider processes under low memory situations.
402    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
403
404    // How long we wait for a launched process to attach to the activity manager
405    // before we decide it's never going to come up for real, when the process was
406    // started with a wrapper for instrumentation (such as Valgrind) because it
407    // could take much longer than usual.
408    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
409
410    // How long to wait after going idle before forcing apps to GC.
411    static final int GC_TIMEOUT = 5*1000;
412
413    // The minimum amount of time between successive GC requests for a process.
414    static final int GC_MIN_INTERVAL = 60*1000;
415
416    // The minimum amount of time between successive PSS requests for a process.
417    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
418
419    // The minimum amount of time between successive PSS requests for a process
420    // when the request is due to the memory state being lowered.
421    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
422
423    // The rate at which we check for apps using excessive power -- 15 mins.
424    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
425
426    // The minimum sample duration we will allow before deciding we have
427    // enough data on wake locks to start killing things.
428    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
429
430    // The minimum sample duration we will allow before deciding we have
431    // enough data on CPU usage to start killing things.
432    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
433
434    // How long we allow a receiver to run before giving up on it.
435    static final int BROADCAST_FG_TIMEOUT = 10*1000;
436    static final int BROADCAST_BG_TIMEOUT = 60*1000;
437
438    // How long we wait until we timeout on key dispatching.
439    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
440
441    // How long we wait until we timeout on key dispatching during instrumentation.
442    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
443
444    // This is the amount of time an app needs to be running a foreground service before
445    // we will consider it to be doing interaction for usage stats.
446    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
447
448    // Maximum amount of time we will allow to elapse before re-reporting usage stats
449    // interaction with foreground processes.
450    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
451
452    // This is the amount of time we allow an app to settle after it goes into the background,
453    // before we start restricting what it can do.
454    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
455
456    // How long to wait in getAssistContextExtras for the activity and foreground services
457    // to respond with the result.
458    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
459
460    // How long top wait when going through the modern assist (which doesn't need to block
461    // on getting this result before starting to launch its UI).
462    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
463
464    // Maximum number of persisted Uri grants a package is allowed
465    static final int MAX_PERSISTED_URI_GRANTS = 128;
466
467    static final int MY_PID = Process.myPid();
468
469    static final String[] EMPTY_STRING_ARRAY = new String[0];
470
471    // How many bytes to write into the dropbox log before truncating
472    static final int DROPBOX_MAX_SIZE = 256 * 1024;
473
474    // Access modes for handleIncomingUser.
475    static final int ALLOW_NON_FULL = 0;
476    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
477    static final int ALLOW_FULL_ONLY = 2;
478
479    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
480
481    // Delay in notifying task stack change listeners (in millis)
482    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
483
484    // Necessary ApplicationInfo flags to mark an app as persistent
485    private static final int PERSISTENT_MASK =
486            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
487
488
489    // Delay to disable app launch boost
490    static final int APP_BOOST_MESSAGE_DELAY = 3000;
491    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
492    static final int APP_BOOST_TIMEOUT = 2500;
493
494    // Used to indicate that a task is removed it should also be removed from recents.
495    private static final boolean REMOVE_FROM_RECENTS = true;
496    // Used to indicate that an app transition should be animated.
497    static final boolean ANIMATE = true;
498
499    // Determines whether to take full screen screenshots
500    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
501
502    private static native int nativeMigrateToBoost();
503    private static native int nativeMigrateFromBoost();
504    private boolean mIsBoosted = false;
505    private long mBoostStartTime = 0;
506
507    /** All system services */
508    SystemServiceManager mSystemServiceManager;
509
510    private Installer mInstaller;
511
512    /** Run all ActivityStacks through this */
513    ActivityStackSupervisor mStackSupervisor;
514
515    ActivityStarter mActivityStarter;
516
517    /** Task stack change listeners. */
518    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
519            new RemoteCallbackList<ITaskStackListener>();
520
521    public IntentFirewall mIntentFirewall;
522
523    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
524    // default actuion automatically.  Important for devices without direct input
525    // devices.
526    private boolean mShowDialogs = true;
527
528    BroadcastQueue mFgBroadcastQueue;
529    BroadcastQueue mBgBroadcastQueue;
530    // Convenient for easy iteration over the queues. Foreground is first
531    // so that dispatch of foreground broadcasts gets precedence.
532    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
533
534    BroadcastQueue broadcastQueueForIntent(Intent intent) {
535        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
536        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
537                "Broadcast intent " + intent + " on "
538                + (isFg ? "foreground" : "background") + " queue");
539        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
540    }
541
542    /**
543     * Activity we have told the window manager to have key focus.
544     */
545    ActivityRecord mFocusedActivity = null;
546
547    /**
548     * User id of the last activity mFocusedActivity was set to.
549     */
550    private int mLastFocusedUserId;
551
552    /**
553     * If non-null, we are tracking the time the user spends in the currently focused app.
554     */
555    private AppTimeTracker mCurAppTimeTracker;
556
557    /**
558     * List of intents that were used to start the most recent tasks.
559     */
560    private final RecentTasks mRecentTasks;
561
562    /**
563     * For addAppTask: cached of the last activity component that was added.
564     */
565    ComponentName mLastAddedTaskComponent;
566
567    /**
568     * For addAppTask: cached of the last activity uid that was added.
569     */
570    int mLastAddedTaskUid;
571
572    /**
573     * For addAppTask: cached of the last ActivityInfo that was added.
574     */
575    ActivityInfo mLastAddedTaskActivity;
576
577    /**
578     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
579     */
580    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
581
582    /**
583     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
584     */
585    String mDeviceOwnerName;
586
587    final UserController mUserController;
588
589    public class PendingAssistExtras extends Binder implements Runnable {
590        public final ActivityRecord activity;
591        public final Bundle extras;
592        public final Intent intent;
593        public final String hint;
594        public final IResultReceiver receiver;
595        public final int userHandle;
596        public boolean haveResult = false;
597        public Bundle result = null;
598        public AssistStructure structure = null;
599        public AssistContent content = null;
600        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
601                String _hint, IResultReceiver _receiver, int _userHandle) {
602            activity = _activity;
603            extras = _extras;
604            intent = _intent;
605            hint = _hint;
606            receiver = _receiver;
607            userHandle = _userHandle;
608        }
609        @Override
610        public void run() {
611            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
612            synchronized (this) {
613                haveResult = true;
614                notifyAll();
615            }
616            pendingAssistExtrasTimedOut(this);
617        }
618    }
619
620    final ArrayList<PendingAssistExtras> mPendingAssistExtras
621            = new ArrayList<PendingAssistExtras>();
622
623    /**
624     * Process management.
625     */
626    final ProcessList mProcessList = new ProcessList();
627
628    /**
629     * All of the applications we currently have running organized by name.
630     * The keys are strings of the application package name (as
631     * returned by the package manager), and the keys are ApplicationRecord
632     * objects.
633     */
634    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
635
636    /**
637     * Tracking long-term execution of processes to look for abuse and other
638     * bad app behavior.
639     */
640    final ProcessStatsService mProcessStats;
641
642    /**
643     * The currently running isolated processes.
644     */
645    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
646
647    /**
648     * Counter for assigning isolated process uids, to avoid frequently reusing the
649     * same ones.
650     */
651    int mNextIsolatedProcessUid = 0;
652
653    /**
654     * The currently running heavy-weight process, if any.
655     */
656    ProcessRecord mHeavyWeightProcess = null;
657
658    /**
659     * The last time that various processes have crashed.
660     */
661    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
662
663    /**
664     * Information about a process that is currently marked as bad.
665     */
666    static final class BadProcessInfo {
667        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
668            this.time = time;
669            this.shortMsg = shortMsg;
670            this.longMsg = longMsg;
671            this.stack = stack;
672        }
673
674        final long time;
675        final String shortMsg;
676        final String longMsg;
677        final String stack;
678    }
679
680    /**
681     * Set of applications that we consider to be bad, and will reject
682     * incoming broadcasts from (which the user has no control over).
683     * Processes are added to this set when they have crashed twice within
684     * a minimum amount of time; they are removed from it when they are
685     * later restarted (hopefully due to some user action).  The value is the
686     * time it was added to the list.
687     */
688    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
689
690    /**
691     * All of the processes we currently have running organized by pid.
692     * The keys are the pid running the application.
693     *
694     * <p>NOTE: This object is protected by its own lock, NOT the global
695     * activity manager lock!
696     */
697    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
698
699    /**
700     * All of the processes that have been forced to be foreground.  The key
701     * is the pid of the caller who requested it (we hold a death
702     * link on it).
703     */
704    abstract class ForegroundToken implements IBinder.DeathRecipient {
705        int pid;
706        IBinder token;
707    }
708    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
709
710    /**
711     * List of records for processes that someone had tried to start before the
712     * system was ready.  We don't start them at that point, but ensure they
713     * are started by the time booting is complete.
714     */
715    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
716
717    /**
718     * List of persistent applications that are in the process
719     * of being started.
720     */
721    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
722
723    /**
724     * Processes that are being forcibly torn down.
725     */
726    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * List of running applications, sorted by recent usage.
730     * The first entry in the list is the least recently used.
731     */
732    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
733
734    /**
735     * Where in mLruProcesses that the processes hosting activities start.
736     */
737    int mLruProcessActivityStart = 0;
738
739    /**
740     * Where in mLruProcesses that the processes hosting services start.
741     * This is after (lower index) than mLruProcessesActivityStart.
742     */
743    int mLruProcessServiceStart = 0;
744
745    /**
746     * List of processes that should gc as soon as things are idle.
747     */
748    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
749
750    /**
751     * Processes we want to collect PSS data from.
752     */
753    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
754
755    private boolean mBinderTransactionTrackingEnabled = false;
756
757    /**
758     * Last time we requested PSS data of all processes.
759     */
760    long mLastFullPssTime = SystemClock.uptimeMillis();
761
762    /**
763     * If set, the next time we collect PSS data we should do a full collection
764     * with data from native processes and the kernel.
765     */
766    boolean mFullPssPending = false;
767
768    /**
769     * This is the process holding what we currently consider to be
770     * the "home" activity.
771     */
772    ProcessRecord mHomeProcess;
773
774    /**
775     * This is the process holding the activity the user last visited that
776     * is in a different process from the one they are currently in.
777     */
778    ProcessRecord mPreviousProcess;
779
780    /**
781     * The time at which the previous process was last visible.
782     */
783    long mPreviousProcessVisibleTime;
784
785    /**
786     * Track all uids that have actively running processes.
787     */
788    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
789
790    /**
791     * This is for verifying the UID report flow.
792     */
793    static final boolean VALIDATE_UID_STATES = true;
794    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
795
796    /**
797     * Packages that the user has asked to have run in screen size
798     * compatibility mode instead of filling the screen.
799     */
800    final CompatModePackages mCompatModePackages;
801
802    /**
803     * Set of IntentSenderRecord objects that are currently active.
804     */
805    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
806            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
807
808    /**
809     * Fingerprints (hashCode()) of stack traces that we've
810     * already logged DropBox entries for.  Guarded by itself.  If
811     * something (rogue user app) forces this over
812     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
813     */
814    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
815    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
816
817    /**
818     * Strict Mode background batched logging state.
819     *
820     * The string buffer is guarded by itself, and its lock is also
821     * used to determine if another batched write is already
822     * in-flight.
823     */
824    private final StringBuilder mStrictModeBuffer = new StringBuilder();
825
826    /**
827     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
828     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
829     */
830    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
831
832    /**
833     * Resolver for broadcast intents to registered receivers.
834     * Holds BroadcastFilter (subclass of IntentFilter).
835     */
836    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
837            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
838        @Override
839        protected boolean allowFilterResult(
840                BroadcastFilter filter, List<BroadcastFilter> dest) {
841            IBinder target = filter.receiverList.receiver.asBinder();
842            for (int i = dest.size() - 1; i >= 0; i--) {
843                if (dest.get(i).receiverList.receiver.asBinder() == target) {
844                    return false;
845                }
846            }
847            return true;
848        }
849
850        @Override
851        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
852            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
853                    || userId == filter.owningUserId) {
854                return super.newResult(filter, match, userId);
855            }
856            return null;
857        }
858
859        @Override
860        protected BroadcastFilter[] newArray(int size) {
861            return new BroadcastFilter[size];
862        }
863
864        @Override
865        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
866            return packageName.equals(filter.packageName);
867        }
868    };
869
870    /**
871     * State of all active sticky broadcasts per user.  Keys are the action of the
872     * sticky Intent, values are an ArrayList of all broadcasted intents with
873     * that action (which should usually be one).  The SparseArray is keyed
874     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
875     * for stickies that are sent to all users.
876     */
877    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
878            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
879
880    final ActiveServices mServices;
881
882    final static class Association {
883        final int mSourceUid;
884        final String mSourceProcess;
885        final int mTargetUid;
886        final ComponentName mTargetComponent;
887        final String mTargetProcess;
888
889        int mCount;
890        long mTime;
891
892        int mNesting;
893        long mStartTime;
894
895        Association(int sourceUid, String sourceProcess, int targetUid,
896                ComponentName targetComponent, String targetProcess) {
897            mSourceUid = sourceUid;
898            mSourceProcess = sourceProcess;
899            mTargetUid = targetUid;
900            mTargetComponent = targetComponent;
901            mTargetProcess = targetProcess;
902        }
903    }
904
905    /**
906     * When service association tracking is enabled, this is all of the associations we
907     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
908     * -> association data.
909     */
910    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
911            mAssociations = new SparseArray<>();
912    boolean mTrackingAssociations;
913
914    /**
915     * Backup/restore process management
916     */
917    String mBackupAppName = null;
918    BackupRecord mBackupTarget = null;
919
920    final ProviderMap mProviderMap;
921
922    /**
923     * List of content providers who have clients waiting for them.  The
924     * application is currently being launched and the provider will be
925     * removed from this list once it is published.
926     */
927    final ArrayList<ContentProviderRecord> mLaunchingProviders
928            = new ArrayList<ContentProviderRecord>();
929
930    /**
931     * File storing persisted {@link #mGrantedUriPermissions}.
932     */
933    private final AtomicFile mGrantFile;
934
935    /** XML constants used in {@link #mGrantFile} */
936    private static final String TAG_URI_GRANTS = "uri-grants";
937    private static final String TAG_URI_GRANT = "uri-grant";
938    private static final String ATTR_USER_HANDLE = "userHandle";
939    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
940    private static final String ATTR_TARGET_USER_ID = "targetUserId";
941    private static final String ATTR_SOURCE_PKG = "sourcePkg";
942    private static final String ATTR_TARGET_PKG = "targetPkg";
943    private static final String ATTR_URI = "uri";
944    private static final String ATTR_MODE_FLAGS = "modeFlags";
945    private static final String ATTR_CREATED_TIME = "createdTime";
946    private static final String ATTR_PREFIX = "prefix";
947
948    /**
949     * Global set of specific {@link Uri} permissions that have been granted.
950     * This optimized lookup structure maps from {@link UriPermission#targetUid}
951     * to {@link UriPermission#uri} to {@link UriPermission}.
952     */
953    @GuardedBy("this")
954    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
955            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
956
957    public static class GrantUri {
958        public final int sourceUserId;
959        public final Uri uri;
960        public boolean prefix;
961
962        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
963            this.sourceUserId = sourceUserId;
964            this.uri = uri;
965            this.prefix = prefix;
966        }
967
968        @Override
969        public int hashCode() {
970            int hashCode = 1;
971            hashCode = 31 * hashCode + sourceUserId;
972            hashCode = 31 * hashCode + uri.hashCode();
973            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
974            return hashCode;
975        }
976
977        @Override
978        public boolean equals(Object o) {
979            if (o instanceof GrantUri) {
980                GrantUri other = (GrantUri) o;
981                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
982                        && prefix == other.prefix;
983            }
984            return false;
985        }
986
987        @Override
988        public String toString() {
989            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
990            if (prefix) result += " [prefix]";
991            return result;
992        }
993
994        public String toSafeString() {
995            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
996            if (prefix) result += " [prefix]";
997            return result;
998        }
999
1000        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1001            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1002                    ContentProvider.getUriWithoutUserId(uri), false);
1003        }
1004    }
1005
1006    CoreSettingsObserver mCoreSettingsObserver;
1007
1008    /**
1009     * Thread-local storage used to carry caller permissions over through
1010     * indirect content-provider access.
1011     */
1012    private class Identity {
1013        public final IBinder token;
1014        public final int pid;
1015        public final int uid;
1016
1017        Identity(IBinder _token, int _pid, int _uid) {
1018            token = _token;
1019            pid = _pid;
1020            uid = _uid;
1021        }
1022    }
1023
1024    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1025
1026    /**
1027     * All information we have collected about the runtime performance of
1028     * any user id that can impact battery performance.
1029     */
1030    final BatteryStatsService mBatteryStatsService;
1031
1032    /**
1033     * Information about component usage
1034     */
1035    UsageStatsManagerInternal mUsageStatsService;
1036
1037    /**
1038     * Access to DeviceIdleController service.
1039     */
1040    DeviceIdleController.LocalService mLocalDeviceIdleController;
1041
1042    /**
1043     * Information about and control over application operations
1044     */
1045    final AppOpsService mAppOpsService;
1046
1047    /**
1048     * Save recent tasks information across reboots.
1049     */
1050    final TaskPersister mTaskPersister;
1051
1052    /**
1053     * Current configuration information.  HistoryRecord objects are given
1054     * a reference to this object to indicate which configuration they are
1055     * currently running in, so this object must be kept immutable.
1056     */
1057    Configuration mConfiguration = new Configuration();
1058
1059    /**
1060     * Current sequencing integer of the configuration, for skipping old
1061     * configurations.
1062     */
1063    int mConfigurationSeq = 0;
1064
1065    boolean mSuppressResizeConfigChanges = false;
1066
1067    /**
1068     * Hardware-reported OpenGLES version.
1069     */
1070    final int GL_ES_VERSION;
1071
1072    /**
1073     * List of initialization arguments to pass to all processes when binding applications to them.
1074     * For example, references to the commonly used services.
1075     */
1076    HashMap<String, IBinder> mAppBindArgs;
1077
1078    /**
1079     * Temporary to avoid allocations.  Protected by main lock.
1080     */
1081    final StringBuilder mStringBuilder = new StringBuilder(256);
1082
1083    /**
1084     * Used to control how we initialize the service.
1085     */
1086    ComponentName mTopComponent;
1087    String mTopAction = Intent.ACTION_MAIN;
1088    String mTopData;
1089    boolean mProcessesReady = false;
1090    boolean mSystemReady = false;
1091    boolean mBooting = false;
1092    boolean mCallFinishBooting = false;
1093    boolean mBootAnimationComplete = false;
1094    boolean mWaitingUpdate = false;
1095    boolean mDidUpdate = false;
1096    boolean mOnBattery = false;
1097    boolean mLaunchWarningShown = false;
1098
1099    Context mContext;
1100
1101    int mFactoryTest;
1102
1103    boolean mCheckedForSetup;
1104
1105    /**
1106     * The time at which we will allow normal application switches again,
1107     * after a call to {@link #stopAppSwitches()}.
1108     */
1109    long mAppSwitchesAllowedTime;
1110
1111    /**
1112     * This is set to true after the first switch after mAppSwitchesAllowedTime
1113     * is set; any switches after that will clear the time.
1114     */
1115    boolean mDidAppSwitch;
1116
1117    /**
1118     * Last time (in realtime) at which we checked for power usage.
1119     */
1120    long mLastPowerCheckRealtime;
1121
1122    /**
1123     * Last time (in uptime) at which we checked for power usage.
1124     */
1125    long mLastPowerCheckUptime;
1126
1127    /**
1128     * Set while we are wanting to sleep, to prevent any
1129     * activities from being started/resumed.
1130     */
1131    private boolean mSleeping = false;
1132
1133    /**
1134     * The process state used for processes that are running the top activities.
1135     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1136     */
1137    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1138
1139    /**
1140     * Set while we are running a voice interaction.  This overrides
1141     * sleeping while it is active.
1142     */
1143    private IVoiceInteractionSession mRunningVoice;
1144
1145    /**
1146     * For some direct access we need to power manager.
1147     */
1148    PowerManagerInternal mLocalPowerManager;
1149
1150    /**
1151     * We want to hold a wake lock while running a voice interaction session, since
1152     * this may happen with the screen off and we need to keep the CPU running to
1153     * be able to continue to interact with the user.
1154     */
1155    PowerManager.WakeLock mVoiceWakeLock;
1156
1157    /**
1158     * State of external calls telling us if the device is awake or asleep.
1159     */
1160    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1161
1162    /**
1163     * A list of tokens that cause the top activity to be put to sleep.
1164     * They are used by components that may hide and block interaction with underlying
1165     * activities.
1166     */
1167    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1168
1169    static final int LOCK_SCREEN_HIDDEN = 0;
1170    static final int LOCK_SCREEN_LEAVING = 1;
1171    static final int LOCK_SCREEN_SHOWN = 2;
1172    /**
1173     * State of external call telling us if the lock screen is shown.
1174     */
1175    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1176
1177    /**
1178     * Set if we are shutting down the system, similar to sleeping.
1179     */
1180    boolean mShuttingDown = false;
1181
1182    /**
1183     * Current sequence id for oom_adj computation traversal.
1184     */
1185    int mAdjSeq = 0;
1186
1187    /**
1188     * Current sequence id for process LRU updating.
1189     */
1190    int mLruSeq = 0;
1191
1192    /**
1193     * Keep track of the non-cached/empty process we last found, to help
1194     * determine how to distribute cached/empty processes next time.
1195     */
1196    int mNumNonCachedProcs = 0;
1197
1198    /**
1199     * Keep track of the number of cached hidden procs, to balance oom adj
1200     * distribution between those and empty procs.
1201     */
1202    int mNumCachedHiddenProcs = 0;
1203
1204    /**
1205     * Keep track of the number of service processes we last found, to
1206     * determine on the next iteration which should be B services.
1207     */
1208    int mNumServiceProcs = 0;
1209    int mNewNumAServiceProcs = 0;
1210    int mNewNumServiceProcs = 0;
1211
1212    /**
1213     * Allow the current computed overall memory level of the system to go down?
1214     * This is set to false when we are killing processes for reasons other than
1215     * memory management, so that the now smaller process list will not be taken as
1216     * an indication that memory is tighter.
1217     */
1218    boolean mAllowLowerMemLevel = false;
1219
1220    /**
1221     * The last computed memory level, for holding when we are in a state that
1222     * processes are going away for other reasons.
1223     */
1224    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1225
1226    /**
1227     * The last total number of process we have, to determine if changes actually look
1228     * like a shrinking number of process due to lower RAM.
1229     */
1230    int mLastNumProcesses;
1231
1232    /**
1233     * The uptime of the last time we performed idle maintenance.
1234     */
1235    long mLastIdleTime = SystemClock.uptimeMillis();
1236
1237    /**
1238     * Total time spent with RAM that has been added in the past since the last idle time.
1239     */
1240    long mLowRamTimeSinceLastIdle = 0;
1241
1242    /**
1243     * If RAM is currently low, when that horrible situation started.
1244     */
1245    long mLowRamStartTime = 0;
1246
1247    /**
1248     * For reporting to battery stats the current top application.
1249     */
1250    private String mCurResumedPackage = null;
1251    private int mCurResumedUid = -1;
1252
1253    /**
1254     * For reporting to battery stats the apps currently running foreground
1255     * service.  The ProcessMap is package/uid tuples; each of these contain
1256     * an array of the currently foreground processes.
1257     */
1258    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1259            = new ProcessMap<ArrayList<ProcessRecord>>();
1260
1261    /**
1262     * This is set if we had to do a delayed dexopt of an app before launching
1263     * it, to increase the ANR timeouts in that case.
1264     */
1265    boolean mDidDexOpt;
1266
1267    /**
1268     * Set if the systemServer made a call to enterSafeMode.
1269     */
1270    boolean mSafeMode;
1271
1272    /**
1273     * If true, we are running under a test environment so will sample PSS from processes
1274     * much more rapidly to try to collect better data when the tests are rapidly
1275     * running through apps.
1276     */
1277    boolean mTestPssMode = false;
1278
1279    String mDebugApp = null;
1280    boolean mWaitForDebugger = false;
1281    boolean mDebugTransient = false;
1282    String mOrigDebugApp = null;
1283    boolean mOrigWaitForDebugger = false;
1284    boolean mAlwaysFinishActivities = false;
1285    boolean mForceResizableActivities;
1286    boolean mSupportsFreeformWindowManagement;
1287    boolean mSupportsPictureInPicture;
1288    Rect mDefaultPinnedStackBounds;
1289    IActivityController mController = null;
1290    String mProfileApp = null;
1291    ProcessRecord mProfileProc = null;
1292    String mProfileFile;
1293    ParcelFileDescriptor mProfileFd;
1294    int mSamplingInterval = 0;
1295    boolean mAutoStopProfiler = false;
1296    int mProfileType = 0;
1297    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1298    String mMemWatchDumpProcName;
1299    String mMemWatchDumpFile;
1300    int mMemWatchDumpPid;
1301    int mMemWatchDumpUid;
1302    String mTrackAllocationApp = null;
1303
1304    final long[] mTmpLong = new long[1];
1305
1306    static final class ProcessChangeItem {
1307        static final int CHANGE_ACTIVITIES = 1<<0;
1308        static final int CHANGE_PROCESS_STATE = 1<<1;
1309        int changes;
1310        int uid;
1311        int pid;
1312        int processState;
1313        boolean foregroundActivities;
1314    }
1315
1316    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1317    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1318
1319    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1320    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1321
1322    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1323    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1324
1325    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1326    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1327
1328    ArraySet<String> mAppsNotReportingCrashes;
1329
1330    /**
1331     * Runtime CPU use collection thread.  This object's lock is used to
1332     * perform synchronization with the thread (notifying it to run).
1333     */
1334    final Thread mProcessCpuThread;
1335
1336    /**
1337     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1338     * Must acquire this object's lock when accessing it.
1339     * NOTE: this lock will be held while doing long operations (trawling
1340     * through all processes in /proc), so it should never be acquired by
1341     * any critical paths such as when holding the main activity manager lock.
1342     */
1343    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1344            MONITOR_THREAD_CPU_USAGE);
1345    final AtomicLong mLastCpuTime = new AtomicLong(0);
1346    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1347
1348    long mLastWriteTime = 0;
1349
1350    /**
1351     * Used to retain an update lock when the foreground activity is in
1352     * immersive mode.
1353     */
1354    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1355
1356    /**
1357     * Set to true after the system has finished booting.
1358     */
1359    boolean mBooted = false;
1360
1361    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1362    int mProcessLimitOverride = -1;
1363
1364    WindowManagerService mWindowManager;
1365
1366    final ActivityThread mSystemThread;
1367
1368    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1369        final ProcessRecord mApp;
1370        final int mPid;
1371        final IApplicationThread mAppThread;
1372
1373        AppDeathRecipient(ProcessRecord app, int pid,
1374                IApplicationThread thread) {
1375            if (DEBUG_ALL) Slog.v(
1376                TAG, "New death recipient " + this
1377                + " for thread " + thread.asBinder());
1378            mApp = app;
1379            mPid = pid;
1380            mAppThread = thread;
1381        }
1382
1383        @Override
1384        public void binderDied() {
1385            if (DEBUG_ALL) Slog.v(
1386                TAG, "Death received in " + this
1387                + " for thread " + mAppThread.asBinder());
1388            synchronized(ActivityManagerService.this) {
1389                appDiedLocked(mApp, mPid, mAppThread, true);
1390            }
1391        }
1392    }
1393
1394    static final int SHOW_ERROR_UI_MSG = 1;
1395    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1396    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1397    static final int UPDATE_CONFIGURATION_MSG = 4;
1398    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1399    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1400    static final int SERVICE_TIMEOUT_MSG = 12;
1401    static final int UPDATE_TIME_ZONE = 13;
1402    static final int SHOW_UID_ERROR_UI_MSG = 14;
1403    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1404    static final int PROC_START_TIMEOUT_MSG = 20;
1405    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1406    static final int KILL_APPLICATION_MSG = 22;
1407    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1408    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1409    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1410    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1411    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1412    static final int CLEAR_DNS_CACHE_MSG = 28;
1413    static final int UPDATE_HTTP_PROXY_MSG = 29;
1414    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1415    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1416    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1417    static final int REPORT_MEM_USAGE_MSG = 33;
1418    static final int REPORT_USER_SWITCH_MSG = 34;
1419    static final int CONTINUE_USER_SWITCH_MSG = 35;
1420    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1421    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1422    static final int PERSIST_URI_GRANTS_MSG = 38;
1423    static final int REQUEST_ALL_PSS_MSG = 39;
1424    static final int START_PROFILES_MSG = 40;
1425    static final int UPDATE_TIME = 41;
1426    static final int SYSTEM_USER_START_MSG = 42;
1427    static final int SYSTEM_USER_CURRENT_MSG = 43;
1428    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1429    static final int FINISH_BOOTING_MSG = 45;
1430    static final int START_USER_SWITCH_UI_MSG = 46;
1431    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1432    static final int DISMISS_DIALOG_UI_MSG = 48;
1433    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1434    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1435    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1436    static final int DELETE_DUMPHEAP_MSG = 52;
1437    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1438    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1439    static final int REPORT_TIME_TRACKER_MSG = 55;
1440    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1441    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1442    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1443    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1444    static final int IDLE_UIDS_MSG = 60;
1445    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1446    static final int LOG_STACK_STATE = 62;
1447    static final int VR_MODE_CHANGE_MSG = 63;
1448
1449    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1450    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1451    static final int FIRST_COMPAT_MODE_MSG = 300;
1452    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1453
1454    CompatModeDialog mCompatModeDialog;
1455    long mLastMemUsageReportTime = 0;
1456
1457    /**
1458     * Flag whether the current user is a "monkey", i.e. whether
1459     * the UI is driven by a UI automation tool.
1460     */
1461    private boolean mUserIsMonkey;
1462
1463    /** Flag whether the device has a Recents UI */
1464    boolean mHasRecents;
1465
1466    /** The dimensions of the thumbnails in the Recents UI. */
1467    int mThumbnailWidth;
1468    int mThumbnailHeight;
1469
1470    final ServiceThread mHandlerThread;
1471    final MainHandler mHandler;
1472    final UiHandler mUiHandler;
1473
1474    PackageManagerInternal mPackageManagerInt;
1475
1476    final class UiHandler extends Handler {
1477        public UiHandler() {
1478            super(com.android.server.UiThread.get().getLooper(), null, true);
1479        }
1480
1481        @Override
1482        public void handleMessage(Message msg) {
1483            switch (msg.what) {
1484            case SHOW_ERROR_UI_MSG: {
1485                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1486                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1487                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1488                synchronized (ActivityManagerService.this) {
1489                    ProcessRecord proc = (ProcessRecord)data.get("app");
1490                    AppErrorResult res = (AppErrorResult) data.get("result");
1491                    if (proc != null && proc.crashDialog != null) {
1492                        Slog.e(TAG, "App already has crash dialog: " + proc);
1493                        if (res != null) {
1494                            res.set(0);
1495                        }
1496                        return;
1497                    }
1498                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1499                            >= Process.FIRST_APPLICATION_UID
1500                            && proc.pid != MY_PID);
1501                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1502                        isBackground &= (proc.userId != userId);
1503                    }
1504                    if (isBackground && !showBackground) {
1505                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1506                        if (res != null) {
1507                            res.set(0);
1508                        }
1509                        return;
1510                    }
1511                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1512                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1513                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1514                        Dialog d = new AppErrorDialog(mContext,
1515                                ActivityManagerService.this, res, proc);
1516                        d.show();
1517                        proc.crashDialog = d;
1518                    } else {
1519                        // The device is asleep, so just pretend that the user
1520                        // saw a crash dialog and hit "force quit".
1521                        if (res != null) {
1522                            res.set(0);
1523                        }
1524                    }
1525                }
1526
1527                ensureBootCompleted();
1528            } break;
1529            case SHOW_NOT_RESPONDING_UI_MSG: {
1530                synchronized (ActivityManagerService.this) {
1531                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1532                    ProcessRecord proc = (ProcessRecord)data.get("app");
1533                    if (proc != null && proc.anrDialog != null) {
1534                        Slog.e(TAG, "App already has anr dialog: " + proc);
1535                        return;
1536                    }
1537
1538                    Intent intent = new Intent("android.intent.action.ANR");
1539                    if (!mProcessesReady) {
1540                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1541                                | Intent.FLAG_RECEIVER_FOREGROUND);
1542                    }
1543                    broadcastIntentLocked(null, null, intent,
1544                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1545                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1546
1547                    if (mShowDialogs) {
1548                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1549                                mContext, proc, (ActivityRecord)data.get("activity"),
1550                                msg.arg1 != 0);
1551                        d.show();
1552                        proc.anrDialog = d;
1553                    } else {
1554                        // Just kill the app if there is no dialog to be shown.
1555                        killAppAtUsersRequest(proc, null);
1556                    }
1557                }
1558
1559                ensureBootCompleted();
1560            } break;
1561            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1562                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1563                synchronized (ActivityManagerService.this) {
1564                    ProcessRecord proc = (ProcessRecord) data.get("app");
1565                    if (proc == null) {
1566                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1567                        break;
1568                    }
1569                    if (proc.crashDialog != null) {
1570                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1571                        return;
1572                    }
1573                    AppErrorResult res = (AppErrorResult) data.get("result");
1574                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1575                        Dialog d = new StrictModeViolationDialog(mContext,
1576                                ActivityManagerService.this, res, proc);
1577                        d.show();
1578                        proc.crashDialog = d;
1579                    } else {
1580                        // The device is asleep, so just pretend that the user
1581                        // saw a crash dialog and hit "force quit".
1582                        res.set(0);
1583                    }
1584                }
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_FACTORY_ERROR_UI_MSG: {
1588                Dialog d = new FactoryErrorDialog(
1589                    mContext, msg.getData().getCharSequence("msg"));
1590                d.show();
1591                ensureBootCompleted();
1592            } break;
1593            case WAIT_FOR_DEBUGGER_UI_MSG: {
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord app = (ProcessRecord)msg.obj;
1596                    if (msg.arg1 != 0) {
1597                        if (!app.waitedForDebugger) {
1598                            Dialog d = new AppWaitingForDebuggerDialog(
1599                                    ActivityManagerService.this,
1600                                    mContext, app);
1601                            app.waitDialog = d;
1602                            app.waitedForDebugger = true;
1603                            d.show();
1604                        }
1605                    } else {
1606                        if (app.waitDialog != null) {
1607                            app.waitDialog.dismiss();
1608                            app.waitDialog = null;
1609                        }
1610                    }
1611                }
1612            } break;
1613            case SHOW_UID_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1626                if (mShowDialogs) {
1627                    AlertDialog d = new BaseErrorDialog(mContext);
1628                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1629                    d.setCancelable(false);
1630                    d.setTitle(mContext.getText(R.string.android_system_label));
1631                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1632                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1633                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1634                    d.show();
1635                }
1636            } break;
1637            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1638                synchronized (ActivityManagerService.this) {
1639                    ActivityRecord ar = (ActivityRecord) msg.obj;
1640                    if (mCompatModeDialog != null) {
1641                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1642                                ar.info.applicationInfo.packageName)) {
1643                            return;
1644                        }
1645                        mCompatModeDialog.dismiss();
1646                        mCompatModeDialog = null;
1647                    }
1648                    if (ar != null && false) {
1649                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1650                                ar.packageName)) {
1651                            int mode = mCompatModePackages.computeCompatModeLocked(
1652                                    ar.info.applicationInfo);
1653                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655                                mCompatModeDialog = new CompatModeDialog(
1656                                        ActivityManagerService.this, mContext,
1657                                        ar.info.applicationInfo);
1658                                mCompatModeDialog.show();
1659                            }
1660                        }
1661                    }
1662                }
1663                break;
1664            }
1665            case START_USER_SWITCH_UI_MSG: {
1666                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1667                break;
1668            }
1669            case DISMISS_DIALOG_UI_MSG: {
1670                final Dialog d = (Dialog) msg.obj;
1671                d.dismiss();
1672                break;
1673            }
1674            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1675                dispatchProcessesChanged();
1676                break;
1677            }
1678            case DISPATCH_PROCESS_DIED_UI_MSG: {
1679                final int pid = msg.arg1;
1680                final int uid = msg.arg2;
1681                dispatchProcessDied(pid, uid);
1682                break;
1683            }
1684            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1685                dispatchUidsChanged();
1686            } break;
1687            }
1688        }
1689    }
1690
1691    final class MainHandler extends Handler {
1692        public MainHandler(Looper looper) {
1693            super(looper, null, true);
1694        }
1695
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case UPDATE_CONFIGURATION_MSG: {
1700                final ContentResolver resolver = mContext.getContentResolver();
1701                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1702                        msg.arg1);
1703            } break;
1704            case GC_BACKGROUND_PROCESSES_MSG: {
1705                synchronized (ActivityManagerService.this) {
1706                    performAppGcsIfAppropriateLocked();
1707                }
1708            } break;
1709            case SERVICE_TIMEOUT_MSG: {
1710                if (mDidDexOpt) {
1711                    mDidDexOpt = false;
1712                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1713                    nmsg.obj = msg.obj;
1714                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1715                    return;
1716                }
1717                mServices.serviceTimeout((ProcessRecord)msg.obj);
1718            } break;
1719            case UPDATE_TIME_ZONE: {
1720                synchronized (ActivityManagerService.this) {
1721                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1722                        ProcessRecord r = mLruProcesses.get(i);
1723                        if (r.thread != null) {
1724                            try {
1725                                r.thread.updateTimeZone();
1726                            } catch (RemoteException ex) {
1727                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1728                            }
1729                        }
1730                    }
1731                }
1732            } break;
1733            case CLEAR_DNS_CACHE_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1736                        ProcessRecord r = mLruProcesses.get(i);
1737                        if (r.thread != null) {
1738                            try {
1739                                r.thread.clearDnsCache();
1740                            } catch (RemoteException ex) {
1741                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1742                            }
1743                        }
1744                    }
1745                }
1746            } break;
1747            case UPDATE_HTTP_PROXY_MSG: {
1748                ProxyInfo proxy = (ProxyInfo)msg.obj;
1749                String host = "";
1750                String port = "";
1751                String exclList = "";
1752                Uri pacFileUrl = Uri.EMPTY;
1753                if (proxy != null) {
1754                    host = proxy.getHost();
1755                    port = Integer.toString(proxy.getPort());
1756                    exclList = proxy.getExclusionListAsString();
1757                    pacFileUrl = proxy.getPacFileUrl();
1758                }
1759                synchronized (ActivityManagerService.this) {
1760                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1761                        ProcessRecord r = mLruProcesses.get(i);
1762                        if (r.thread != null) {
1763                            try {
1764                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1765                            } catch (RemoteException ex) {
1766                                Slog.w(TAG, "Failed to update http proxy for: " +
1767                                        r.info.processName);
1768                            }
1769                        }
1770                    }
1771                }
1772            } break;
1773            case PROC_START_TIMEOUT_MSG: {
1774                if (mDidDexOpt) {
1775                    mDidDexOpt = false;
1776                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1777                    nmsg.obj = msg.obj;
1778                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1779                    return;
1780                }
1781                ProcessRecord app = (ProcessRecord)msg.obj;
1782                synchronized (ActivityManagerService.this) {
1783                    processStartTimedOutLocked(app);
1784                }
1785            } break;
1786            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1787                ProcessRecord app = (ProcessRecord)msg.obj;
1788                synchronized (ActivityManagerService.this) {
1789                    processContentProviderPublishTimedOutLocked(app);
1790                }
1791            } break;
1792            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1793                synchronized (ActivityManagerService.this) {
1794                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1795                }
1796            } break;
1797            case KILL_APPLICATION_MSG: {
1798                synchronized (ActivityManagerService.this) {
1799                    int appid = msg.arg1;
1800                    boolean restart = (msg.arg2 == 1);
1801                    Bundle bundle = (Bundle)msg.obj;
1802                    String pkg = bundle.getString("pkg");
1803                    String reason = bundle.getString("reason");
1804                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1805                            false, UserHandle.USER_ALL, reason);
1806                }
1807            } break;
1808            case FINALIZE_PENDING_INTENT_MSG: {
1809                ((PendingIntentRecord)msg.obj).completeFinalize();
1810            } break;
1811            case POST_HEAVY_NOTIFICATION_MSG: {
1812                INotificationManager inm = NotificationManager.getService();
1813                if (inm == null) {
1814                    return;
1815                }
1816
1817                ActivityRecord root = (ActivityRecord)msg.obj;
1818                ProcessRecord process = root.app;
1819                if (process == null) {
1820                    return;
1821                }
1822
1823                try {
1824                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1825                    String text = mContext.getString(R.string.heavy_weight_notification,
1826                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1827                    Notification notification = new Notification.Builder(context)
1828                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1829                            .setWhen(0)
1830                            .setOngoing(true)
1831                            .setTicker(text)
1832                            .setColor(mContext.getColor(
1833                                    com.android.internal.R.color.system_notification_accent_color))
1834                            .setContentTitle(text)
1835                            .setContentText(
1836                                    mContext.getText(R.string.heavy_weight_notification_detail))
1837                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1838                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1839                                    new UserHandle(root.userId)))
1840                            .build();
1841                    try {
1842                        int[] outId = new int[1];
1843                        inm.enqueueNotificationWithTag("android", "android", null,
1844                                R.string.heavy_weight_notification,
1845                                notification, outId, root.userId);
1846                    } catch (RuntimeException e) {
1847                        Slog.w(ActivityManagerService.TAG,
1848                                "Error showing notification for heavy-weight app", e);
1849                    } catch (RemoteException e) {
1850                    }
1851                } catch (NameNotFoundException e) {
1852                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1853                }
1854            } break;
1855            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1856                INotificationManager inm = NotificationManager.getService();
1857                if (inm == null) {
1858                    return;
1859                }
1860                try {
1861                    inm.cancelNotificationWithTag("android", null,
1862                            R.string.heavy_weight_notification,  msg.arg1);
1863                } catch (RuntimeException e) {
1864                    Slog.w(ActivityManagerService.TAG,
1865                            "Error canceling notification for service", e);
1866                } catch (RemoteException e) {
1867                }
1868            } break;
1869            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    checkExcessivePowerUsageLocked(true);
1872                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1874                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1875                }
1876            } break;
1877            case REPORT_MEM_USAGE_MSG: {
1878                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1879                Thread thread = new Thread() {
1880                    @Override public void run() {
1881                        reportMemUsage(memInfos);
1882                    }
1883                };
1884                thread.start();
1885                break;
1886            }
1887            case REPORT_USER_SWITCH_MSG: {
1888                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1889                break;
1890            }
1891            case CONTINUE_USER_SWITCH_MSG: {
1892                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1893                break;
1894            }
1895            case USER_SWITCH_TIMEOUT_MSG: {
1896                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1897                break;
1898            }
1899            case IMMERSIVE_MODE_LOCK_MSG: {
1900                final boolean nextState = (msg.arg1 != 0);
1901                if (mUpdateLock.isHeld() != nextState) {
1902                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1903                            "Applying new update lock state '" + nextState
1904                            + "' for " + (ActivityRecord)msg.obj);
1905                    if (nextState) {
1906                        mUpdateLock.acquire();
1907                    } else {
1908                        mUpdateLock.release();
1909                    }
1910                }
1911                break;
1912            }
1913            case PERSIST_URI_GRANTS_MSG: {
1914                writeGrantedUriPermissions();
1915                break;
1916            }
1917            case REQUEST_ALL_PSS_MSG: {
1918                synchronized (ActivityManagerService.this) {
1919                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1920                }
1921                break;
1922            }
1923            case START_PROFILES_MSG: {
1924                synchronized (ActivityManagerService.this) {
1925                    mUserController.startProfilesLocked();
1926                }
1927                break;
1928            }
1929            case UPDATE_TIME: {
1930                synchronized (ActivityManagerService.this) {
1931                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1932                        ProcessRecord r = mLruProcesses.get(i);
1933                        if (r.thread != null) {
1934                            try {
1935                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1936                            } catch (RemoteException ex) {
1937                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1938                            }
1939                        }
1940                    }
1941                }
1942                break;
1943            }
1944            case SYSTEM_USER_START_MSG: {
1945                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1946                        Integer.toString(msg.arg1), msg.arg1);
1947                mSystemServiceManager.startUser(msg.arg1);
1948                break;
1949            }
1950            case SYSTEM_USER_UNLOCK_MSG: {
1951                mSystemServiceManager.unlockUser(msg.arg1);
1952                break;
1953            }
1954            case SYSTEM_USER_CURRENT_MSG: {
1955                mBatteryStatsService.noteEvent(
1956                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1957                        Integer.toString(msg.arg2), msg.arg2);
1958                mBatteryStatsService.noteEvent(
1959                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1960                        Integer.toString(msg.arg1), msg.arg1);
1961                mSystemServiceManager.switchUser(msg.arg1);
1962                break;
1963            }
1964            case ENTER_ANIMATION_COMPLETE_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1967                    if (r != null && r.app != null && r.app.thread != null) {
1968                        try {
1969                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1970                        } catch (RemoteException e) {
1971                        }
1972                    }
1973                }
1974                break;
1975            }
1976            case FINISH_BOOTING_MSG: {
1977                if (msg.arg1 != 0) {
1978                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1979                    finishBooting();
1980                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1981                }
1982                if (msg.arg2 != 0) {
1983                    enableScreenAfterBoot();
1984                }
1985                break;
1986            }
1987            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1988                try {
1989                    Locale l = (Locale) msg.obj;
1990                    IBinder service = ServiceManager.getService("mount");
1991                    IMountService mountService = IMountService.Stub.asInterface(service);
1992                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1993                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1994                } catch (RemoteException e) {
1995                    Log.e(TAG, "Error storing locale for decryption UI", e);
1996                }
1997                break;
1998            }
1999            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    int i = mTaskStackListeners.beginBroadcast();
2002                    while (i > 0) {
2003                        i--;
2004                        try {
2005                            // Make a one-way callback to the listener
2006                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2007                        } catch (RemoteException e){
2008                            // Handled by the RemoteCallbackList
2009                        }
2010                    }
2011                    mTaskStackListeners.finishBroadcast();
2012                }
2013                break;
2014            }
2015            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2016                final int uid = msg.arg1;
2017                final byte[] firstPacket = (byte[]) msg.obj;
2018
2019                synchronized (mPidsSelfLocked) {
2020                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2021                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2022                        if (p.uid == uid) {
2023                            try {
2024                                p.thread.notifyCleartextNetwork(firstPacket);
2025                            } catch (RemoteException ignored) {
2026                            }
2027                        }
2028                    }
2029                }
2030                break;
2031            }
2032            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2033                final String procName;
2034                final int uid;
2035                final long memLimit;
2036                final String reportPackage;
2037                synchronized (ActivityManagerService.this) {
2038                    procName = mMemWatchDumpProcName;
2039                    uid = mMemWatchDumpUid;
2040                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2041                    if (val == null) {
2042                        val = mMemWatchProcesses.get(procName, 0);
2043                    }
2044                    if (val != null) {
2045                        memLimit = val.first;
2046                        reportPackage = val.second;
2047                    } else {
2048                        memLimit = 0;
2049                        reportPackage = null;
2050                    }
2051                }
2052                if (procName == null) {
2053                    return;
2054                }
2055
2056                if (DEBUG_PSS) Slog.d(TAG_PSS,
2057                        "Showing dump heap notification from " + procName + "/" + uid);
2058
2059                INotificationManager inm = NotificationManager.getService();
2060                if (inm == null) {
2061                    return;
2062                }
2063
2064                String text = mContext.getString(R.string.dump_heap_notification, procName);
2065
2066
2067                Intent deleteIntent = new Intent();
2068                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2069                Intent intent = new Intent();
2070                intent.setClassName("android", DumpHeapActivity.class.getName());
2071                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2072                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2073                if (reportPackage != null) {
2074                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2075                }
2076                int userId = UserHandle.getUserId(uid);
2077                Notification notification = new Notification.Builder(mContext)
2078                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2079                        .setWhen(0)
2080                        .setOngoing(true)
2081                        .setAutoCancel(true)
2082                        .setTicker(text)
2083                        .setColor(mContext.getColor(
2084                                com.android.internal.R.color.system_notification_accent_color))
2085                        .setContentTitle(text)
2086                        .setContentText(
2087                                mContext.getText(R.string.dump_heap_notification_detail))
2088                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2089                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2090                                new UserHandle(userId)))
2091                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2092                                deleteIntent, 0, UserHandle.SYSTEM))
2093                        .build();
2094
2095                try {
2096                    int[] outId = new int[1];
2097                    inm.enqueueNotificationWithTag("android", "android", null,
2098                            R.string.dump_heap_notification,
2099                            notification, outId, userId);
2100                } catch (RuntimeException e) {
2101                    Slog.w(ActivityManagerService.TAG,
2102                            "Error showing notification for dump heap", e);
2103                } catch (RemoteException e) {
2104                }
2105            } break;
2106            case DELETE_DUMPHEAP_MSG: {
2107                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2108                        DumpHeapActivity.JAVA_URI,
2109                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2110                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2111                        UserHandle.myUserId());
2112                synchronized (ActivityManagerService.this) {
2113                    mMemWatchDumpFile = null;
2114                    mMemWatchDumpProcName = null;
2115                    mMemWatchDumpPid = -1;
2116                    mMemWatchDumpUid = -1;
2117                }
2118            } break;
2119            case FOREGROUND_PROFILE_CHANGED_MSG: {
2120                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2121            } break;
2122            case REPORT_TIME_TRACKER_MSG: {
2123                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2124                tracker.deliverResult(mContext);
2125            } break;
2126            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2127                mUserController.dispatchUserSwitchComplete(msg.arg1);
2128            } break;
2129            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2130                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2131                try {
2132                    connection.shutdown();
2133                } catch (RemoteException e) {
2134                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2135                }
2136                // Only a UiAutomation can set this flag and now that
2137                // it is finished we make sure it is reset to its default.
2138                mUserIsMonkey = false;
2139            } break;
2140            case APP_BOOST_DEACTIVATE_MSG: {
2141                synchronized(ActivityManagerService.this) {
2142                    if (mIsBoosted) {
2143                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2144                            nativeMigrateFromBoost();
2145                            mIsBoosted = false;
2146                            mBoostStartTime = 0;
2147                        } else {
2148                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2149                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2150                        }
2151                    }
2152                }
2153            } break;
2154            case IDLE_UIDS_MSG: {
2155                idleUids();
2156            } break;
2157            case LOG_STACK_STATE: {
2158                synchronized (ActivityManagerService.this) {
2159                    mStackSupervisor.logStackState();
2160                }
2161            } break;
2162            case VR_MODE_CHANGE_MSG: {
2163                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2164                vrService.setVrMode(msg.arg1 != 0);
2165            } break;
2166            }
2167        }
2168    };
2169
2170    static final int COLLECT_PSS_BG_MSG = 1;
2171
2172    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2173        @Override
2174        public void handleMessage(Message msg) {
2175            switch (msg.what) {
2176            case COLLECT_PSS_BG_MSG: {
2177                long start = SystemClock.uptimeMillis();
2178                MemInfoReader memInfo = null;
2179                synchronized (ActivityManagerService.this) {
2180                    if (mFullPssPending) {
2181                        mFullPssPending = false;
2182                        memInfo = new MemInfoReader();
2183                    }
2184                }
2185                if (memInfo != null) {
2186                    updateCpuStatsNow();
2187                    long nativeTotalPss = 0;
2188                    synchronized (mProcessCpuTracker) {
2189                        final int N = mProcessCpuTracker.countStats();
2190                        for (int j=0; j<N; j++) {
2191                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2192                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2193                                // This is definitely an application process; skip it.
2194                                continue;
2195                            }
2196                            synchronized (mPidsSelfLocked) {
2197                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2198                                    // This is one of our own processes; skip it.
2199                                    continue;
2200                                }
2201                            }
2202                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2203                        }
2204                    }
2205                    memInfo.readMemInfo();
2206                    synchronized (ActivityManagerService.this) {
2207                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2208                                + (SystemClock.uptimeMillis()-start) + "ms");
2209                        final long cachedKb = memInfo.getCachedSizeKb();
2210                        final long freeKb = memInfo.getFreeSizeKb();
2211                        final long zramKb = memInfo.getZramTotalSizeKb();
2212                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2213                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2214                                kernelKb*1024, nativeTotalPss*1024);
2215                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2216                                nativeTotalPss);
2217                    }
2218                }
2219
2220                int num = 0;
2221                long[] tmp = new long[1];
2222                do {
2223                    ProcessRecord proc;
2224                    int procState;
2225                    int pid;
2226                    long lastPssTime;
2227                    synchronized (ActivityManagerService.this) {
2228                        if (mPendingPssProcesses.size() <= 0) {
2229                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2230                                    "Collected PSS of " + num + " processes in "
2231                                    + (SystemClock.uptimeMillis() - start) + "ms");
2232                            mPendingPssProcesses.clear();
2233                            return;
2234                        }
2235                        proc = mPendingPssProcesses.remove(0);
2236                        procState = proc.pssProcState;
2237                        lastPssTime = proc.lastPssTime;
2238                        if (proc.thread != null && procState == proc.setProcState
2239                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2240                                        < SystemClock.uptimeMillis()) {
2241                            pid = proc.pid;
2242                        } else {
2243                            proc = null;
2244                            pid = 0;
2245                        }
2246                    }
2247                    if (proc != null) {
2248                        long pss = Debug.getPss(pid, tmp, null);
2249                        synchronized (ActivityManagerService.this) {
2250                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2251                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2252                                num++;
2253                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2254                                        SystemClock.uptimeMillis());
2255                            }
2256                        }
2257                    }
2258                } while (true);
2259            }
2260            }
2261        }
2262    };
2263
2264    public void setSystemProcess() {
2265        try {
2266            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2267            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2268            ServiceManager.addService("meminfo", new MemBinder(this));
2269            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2270            ServiceManager.addService("dbinfo", new DbBinder(this));
2271            if (MONITOR_CPU_USAGE) {
2272                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2273            }
2274            ServiceManager.addService("permission", new PermissionController(this));
2275            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2276
2277            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2278                    "android", STOCK_PM_FLAGS);
2279            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2280
2281            synchronized (this) {
2282                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2283                app.persistent = true;
2284                app.pid = MY_PID;
2285                app.maxAdj = ProcessList.SYSTEM_ADJ;
2286                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2287                synchronized (mPidsSelfLocked) {
2288                    mPidsSelfLocked.put(app.pid, app);
2289                }
2290                updateLruProcessLocked(app, false, null);
2291                updateOomAdjLocked();
2292            }
2293        } catch (PackageManager.NameNotFoundException e) {
2294            throw new RuntimeException(
2295                    "Unable to find android system package", e);
2296        }
2297    }
2298
2299    public void setWindowManager(WindowManagerService wm) {
2300        mWindowManager = wm;
2301        mStackSupervisor.setWindowManager(wm);
2302        mActivityStarter.setWindowManager(wm);
2303    }
2304
2305    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2306        mUsageStatsService = usageStatsManager;
2307    }
2308
2309    public void startObservingNativeCrashes() {
2310        final NativeCrashListener ncl = new NativeCrashListener(this);
2311        ncl.start();
2312    }
2313
2314    public IAppOpsService getAppOpsService() {
2315        return mAppOpsService;
2316    }
2317
2318    static class MemBinder extends Binder {
2319        ActivityManagerService mActivityManagerService;
2320        MemBinder(ActivityManagerService activityManagerService) {
2321            mActivityManagerService = activityManagerService;
2322        }
2323
2324        @Override
2325        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2326            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2327                    != PackageManager.PERMISSION_GRANTED) {
2328                pw.println("Permission Denial: can't dump meminfo from from pid="
2329                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2330                        + " without permission " + android.Manifest.permission.DUMP);
2331                return;
2332            }
2333
2334            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2335        }
2336    }
2337
2338    static class GraphicsBinder extends Binder {
2339        ActivityManagerService mActivityManagerService;
2340        GraphicsBinder(ActivityManagerService activityManagerService) {
2341            mActivityManagerService = activityManagerService;
2342        }
2343
2344        @Override
2345        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2346            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2347                    != PackageManager.PERMISSION_GRANTED) {
2348                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2349                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2350                        + " without permission " + android.Manifest.permission.DUMP);
2351                return;
2352            }
2353
2354            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2355        }
2356    }
2357
2358    static class DbBinder extends Binder {
2359        ActivityManagerService mActivityManagerService;
2360        DbBinder(ActivityManagerService activityManagerService) {
2361            mActivityManagerService = activityManagerService;
2362        }
2363
2364        @Override
2365        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2366            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2367                    != PackageManager.PERMISSION_GRANTED) {
2368                pw.println("Permission Denial: can't dump dbinfo from from pid="
2369                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2370                        + " without permission " + android.Manifest.permission.DUMP);
2371                return;
2372            }
2373
2374            mActivityManagerService.dumpDbInfo(fd, pw, args);
2375        }
2376    }
2377
2378    static class CpuBinder extends Binder {
2379        ActivityManagerService mActivityManagerService;
2380        CpuBinder(ActivityManagerService activityManagerService) {
2381            mActivityManagerService = activityManagerService;
2382        }
2383
2384        @Override
2385        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2386            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2387                    != PackageManager.PERMISSION_GRANTED) {
2388                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2389                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2390                        + " without permission " + android.Manifest.permission.DUMP);
2391                return;
2392            }
2393
2394            synchronized (mActivityManagerService.mProcessCpuTracker) {
2395                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2396                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2397                        SystemClock.uptimeMillis()));
2398            }
2399        }
2400    }
2401
2402    public static final class Lifecycle extends SystemService {
2403        private final ActivityManagerService mService;
2404
2405        public Lifecycle(Context context) {
2406            super(context);
2407            mService = new ActivityManagerService(context);
2408        }
2409
2410        @Override
2411        public void onStart() {
2412            mService.start();
2413        }
2414
2415        public ActivityManagerService getService() {
2416            return mService;
2417        }
2418    }
2419
2420    // Note: This method is invoked on the main thread but may need to attach various
2421    // handlers to other threads.  So take care to be explicit about the looper.
2422    public ActivityManagerService(Context systemContext) {
2423        mContext = systemContext;
2424        mFactoryTest = FactoryTest.getMode();
2425        mSystemThread = ActivityThread.currentActivityThread();
2426
2427        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2428
2429        mHandlerThread = new ServiceThread(TAG,
2430                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2431        mHandlerThread.start();
2432        mHandler = new MainHandler(mHandlerThread.getLooper());
2433        mUiHandler = new UiHandler();
2434
2435        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2436                "foreground", BROADCAST_FG_TIMEOUT, false);
2437        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2438                "background", BROADCAST_BG_TIMEOUT, true);
2439        mBroadcastQueues[0] = mFgBroadcastQueue;
2440        mBroadcastQueues[1] = mBgBroadcastQueue;
2441
2442        mServices = new ActiveServices(this);
2443        mProviderMap = new ProviderMap(this);
2444
2445        // TODO: Move creation of battery stats service outside of activity manager service.
2446        File dataDir = Environment.getDataDirectory();
2447        File systemDir = new File(dataDir, "system");
2448        systemDir.mkdirs();
2449        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2450        mBatteryStatsService.getActiveStatistics().readLocked();
2451        mBatteryStatsService.scheduleWriteToDisk();
2452        mOnBattery = DEBUG_POWER ? true
2453                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2454        mBatteryStatsService.getActiveStatistics().setCallback(this);
2455
2456        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2457
2458        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2459        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2460                new IAppOpsCallback.Stub() {
2461                    @Override public void opChanged(int op, int uid, String packageName) {
2462                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2463                            if (mAppOpsService.checkOperation(op, uid, packageName)
2464                                    != AppOpsManager.MODE_ALLOWED) {
2465                                runInBackgroundDisabled(uid);
2466                            }
2467                        }
2468                    }
2469                });
2470
2471        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2472
2473        mUserController = new UserController(this);
2474
2475        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2476            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2477
2478        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2479
2480        mConfiguration.setToDefaults();
2481        mConfiguration.setLocales(LocaleList.getDefault());
2482
2483        mConfigurationSeq = mConfiguration.seq = 1;
2484        mProcessCpuTracker.init();
2485
2486        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2487        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2488        mRecentTasks = new RecentTasks(this);
2489        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2490        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2491        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2492
2493        mProcessCpuThread = new Thread("CpuTracker") {
2494            @Override
2495            public void run() {
2496                while (true) {
2497                    try {
2498                        try {
2499                            synchronized(this) {
2500                                final long now = SystemClock.uptimeMillis();
2501                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2502                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2503                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2504                                //        + ", write delay=" + nextWriteDelay);
2505                                if (nextWriteDelay < nextCpuDelay) {
2506                                    nextCpuDelay = nextWriteDelay;
2507                                }
2508                                if (nextCpuDelay > 0) {
2509                                    mProcessCpuMutexFree.set(true);
2510                                    this.wait(nextCpuDelay);
2511                                }
2512                            }
2513                        } catch (InterruptedException e) {
2514                        }
2515                        updateCpuStatsNow();
2516                    } catch (Exception e) {
2517                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2518                    }
2519                }
2520            }
2521        };
2522
2523        Watchdog.getInstance().addMonitor(this);
2524        Watchdog.getInstance().addThread(mHandler);
2525    }
2526
2527    public void setSystemServiceManager(SystemServiceManager mgr) {
2528        mSystemServiceManager = mgr;
2529    }
2530
2531    public void setInstaller(Installer installer) {
2532        mInstaller = installer;
2533    }
2534
2535    private void start() {
2536        Process.removeAllProcessGroups();
2537        mProcessCpuThread.start();
2538
2539        mBatteryStatsService.publish(mContext);
2540        mAppOpsService.publish(mContext);
2541        Slog.d("AppOps", "AppOpsService published");
2542        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2543    }
2544
2545    public void initPowerManagement() {
2546        mStackSupervisor.initPowerManagement();
2547        mBatteryStatsService.initPowerManagement();
2548        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2549        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2550        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2551        mVoiceWakeLock.setReferenceCounted(false);
2552    }
2553
2554    @Override
2555    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2556            throws RemoteException {
2557        if (code == SYSPROPS_TRANSACTION) {
2558            // We need to tell all apps about the system property change.
2559            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2560            synchronized(this) {
2561                final int NP = mProcessNames.getMap().size();
2562                for (int ip=0; ip<NP; ip++) {
2563                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2564                    final int NA = apps.size();
2565                    for (int ia=0; ia<NA; ia++) {
2566                        ProcessRecord app = apps.valueAt(ia);
2567                        if (app.thread != null) {
2568                            procs.add(app.thread.asBinder());
2569                        }
2570                    }
2571                }
2572            }
2573
2574            int N = procs.size();
2575            for (int i=0; i<N; i++) {
2576                Parcel data2 = Parcel.obtain();
2577                try {
2578                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2579                } catch (RemoteException e) {
2580                }
2581                data2.recycle();
2582            }
2583        }
2584        try {
2585            return super.onTransact(code, data, reply, flags);
2586        } catch (RuntimeException e) {
2587            // The activity manager only throws security exceptions, so let's
2588            // log all others.
2589            if (!(e instanceof SecurityException)) {
2590                Slog.wtf(TAG, "Activity Manager Crash", e);
2591            }
2592            throw e;
2593        }
2594    }
2595
2596    void updateCpuStats() {
2597        final long now = SystemClock.uptimeMillis();
2598        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2599            return;
2600        }
2601        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2602            synchronized (mProcessCpuThread) {
2603                mProcessCpuThread.notify();
2604            }
2605        }
2606    }
2607
2608    void updateCpuStatsNow() {
2609        synchronized (mProcessCpuTracker) {
2610            mProcessCpuMutexFree.set(false);
2611            final long now = SystemClock.uptimeMillis();
2612            boolean haveNewCpuStats = false;
2613
2614            if (MONITOR_CPU_USAGE &&
2615                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2616                mLastCpuTime.set(now);
2617                mProcessCpuTracker.update();
2618                if (mProcessCpuTracker.hasGoodLastStats()) {
2619                    haveNewCpuStats = true;
2620                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2621                    //Slog.i(TAG, "Total CPU usage: "
2622                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2623
2624                    // Slog the cpu usage if the property is set.
2625                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2626                        int user = mProcessCpuTracker.getLastUserTime();
2627                        int system = mProcessCpuTracker.getLastSystemTime();
2628                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2629                        int irq = mProcessCpuTracker.getLastIrqTime();
2630                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2631                        int idle = mProcessCpuTracker.getLastIdleTime();
2632
2633                        int total = user + system + iowait + irq + softIrq + idle;
2634                        if (total == 0) total = 1;
2635
2636                        EventLog.writeEvent(EventLogTags.CPU,
2637                                ((user+system+iowait+irq+softIrq) * 100) / total,
2638                                (user * 100) / total,
2639                                (system * 100) / total,
2640                                (iowait * 100) / total,
2641                                (irq * 100) / total,
2642                                (softIrq * 100) / total);
2643                    }
2644                }
2645            }
2646
2647            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2648            synchronized(bstats) {
2649                synchronized(mPidsSelfLocked) {
2650                    if (haveNewCpuStats) {
2651                        if (bstats.startAddingCpuLocked()) {
2652                            int totalUTime = 0;
2653                            int totalSTime = 0;
2654                            final int N = mProcessCpuTracker.countStats();
2655                            for (int i=0; i<N; i++) {
2656                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2657                                if (!st.working) {
2658                                    continue;
2659                                }
2660                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2661                                totalUTime += st.rel_utime;
2662                                totalSTime += st.rel_stime;
2663                                if (pr != null) {
2664                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2665                                    if (ps == null || !ps.isActive()) {
2666                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2667                                                pr.info.uid, pr.processName);
2668                                    }
2669                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2670                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2671                                } else {
2672                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2673                                    if (ps == null || !ps.isActive()) {
2674                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2675                                                bstats.mapUid(st.uid), st.name);
2676                                    }
2677                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2678                                }
2679                            }
2680                            final int userTime = mProcessCpuTracker.getLastUserTime();
2681                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2682                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2683                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2684                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2685                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2686                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2687                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2688                        }
2689                    }
2690                }
2691
2692                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2693                    mLastWriteTime = now;
2694                    mBatteryStatsService.scheduleWriteToDisk();
2695                }
2696            }
2697        }
2698    }
2699
2700    @Override
2701    public void batteryNeedsCpuUpdate() {
2702        updateCpuStatsNow();
2703    }
2704
2705    @Override
2706    public void batteryPowerChanged(boolean onBattery) {
2707        // When plugging in, update the CPU stats first before changing
2708        // the plug state.
2709        updateCpuStatsNow();
2710        synchronized (this) {
2711            synchronized(mPidsSelfLocked) {
2712                mOnBattery = DEBUG_POWER ? true : onBattery;
2713            }
2714        }
2715    }
2716
2717    @Override
2718    public void batterySendBroadcast(Intent intent) {
2719        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2720                AppOpsManager.OP_NONE, null, false, false,
2721                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2722    }
2723
2724    /**
2725     * Initialize the application bind args. These are passed to each
2726     * process when the bindApplication() IPC is sent to the process. They're
2727     * lazily setup to make sure the services are running when they're asked for.
2728     */
2729    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2730        if (mAppBindArgs == null) {
2731            mAppBindArgs = new HashMap<>();
2732
2733            // Isolated processes won't get this optimization, so that we don't
2734            // violate the rules about which services they have access to.
2735            if (!isolated) {
2736                // Setup the application init args
2737                mAppBindArgs.put("package", ServiceManager.getService("package"));
2738                mAppBindArgs.put("window", ServiceManager.getService("window"));
2739                mAppBindArgs.put(Context.ALARM_SERVICE,
2740                        ServiceManager.getService(Context.ALARM_SERVICE));
2741            }
2742        }
2743        return mAppBindArgs;
2744    }
2745
2746    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2747        if (r == null || mFocusedActivity == r) {
2748            return;
2749        }
2750
2751        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2752        final ActivityRecord last = mFocusedActivity;
2753        mFocusedActivity = r;
2754        if (r.task.isApplicationTask()) {
2755            if (mCurAppTimeTracker != r.appTimeTracker) {
2756                // We are switching app tracking.  Complete the current one.
2757                if (mCurAppTimeTracker != null) {
2758                    mCurAppTimeTracker.stop();
2759                    mHandler.obtainMessage(
2760                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2761                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2762                    mCurAppTimeTracker = null;
2763                }
2764                if (r.appTimeTracker != null) {
2765                    mCurAppTimeTracker = r.appTimeTracker;
2766                    startTimeTrackingFocusedActivityLocked();
2767                }
2768            } else {
2769                startTimeTrackingFocusedActivityLocked();
2770            }
2771        } else {
2772            r.appTimeTracker = null;
2773        }
2774        if (r.task.voiceInteractor != null) {
2775            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2776        } else {
2777            finishRunningVoiceLocked();
2778            if (last != null && last.task.voiceSession != null) {
2779                // We had been in a voice interaction session, but now focused has
2780                // move to something different.  Just finish the session, we can't
2781                // return to it and retain the proper state and synchronization with
2782                // the voice interaction service.
2783                finishVoiceTask(last.task.voiceSession);
2784            }
2785        }
2786        if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2787            mWindowManager.setFocusedApp(r.appToken, true);
2788        }
2789        applyUpdateLockStateLocked(r);
2790        applyUpdateVrModeLocked(r);
2791        if (mFocusedActivity.userId != mLastFocusedUserId) {
2792            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2793            mHandler.obtainMessage(
2794                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2795            mLastFocusedUserId = mFocusedActivity.userId;
2796        }
2797
2798        EventLogTags.writeAmFocusedActivity(
2799                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2800                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2801                reason);
2802    }
2803
2804    final void clearFocusedActivity(ActivityRecord r) {
2805        if (mFocusedActivity == r) {
2806            ActivityStack stack = mStackSupervisor.getFocusedStack();
2807            if (stack != null) {
2808                ActivityRecord top = stack.topActivity();
2809                if (top != null && top.userId != mLastFocusedUserId) {
2810                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2811                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2812                                    top.userId, 0));
2813                    mLastFocusedUserId = top.userId;
2814                }
2815            }
2816            mFocusedActivity = null;
2817            EventLogTags.writeAmFocusedActivity(-1, "NULL", "clearFocusedActivity");
2818        }
2819    }
2820
2821    @Override
2822    public void setFocusedStack(int stackId) {
2823        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2824        synchronized (ActivityManagerService.this) {
2825            ActivityStack stack = mStackSupervisor.getStack(stackId);
2826            if (stack != null) {
2827                ActivityRecord r = stack.topRunningActivityLocked();
2828                if (r != null) {
2829                    setFocusedActivityLocked(r, "setFocusedStack");
2830                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2831                }
2832            }
2833        }
2834    }
2835
2836    @Override
2837    public void setFocusedTask(int taskId) {
2838        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2839        long callingId = Binder.clearCallingIdentity();
2840        try {
2841            synchronized (ActivityManagerService.this) {
2842                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2843                if (task != null) {
2844                    ActivityRecord r = task.topRunningActivityLocked();
2845                    if (r != null) {
2846                        setFocusedActivityLocked(r, "setFocusedTask");
2847                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2848                    }
2849                }
2850            }
2851        } finally {
2852            Binder.restoreCallingIdentity(callingId);
2853        }
2854    }
2855
2856    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2857    @Override
2858    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2859        synchronized (ActivityManagerService.this) {
2860            if (listener != null) {
2861                mTaskStackListeners.register(listener);
2862            }
2863        }
2864    }
2865
2866    @Override
2867    public void notifyActivityDrawn(IBinder token) {
2868        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2869        synchronized (this) {
2870            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2871            if (r != null) {
2872                r.task.stack.notifyActivityDrawnLocked(r);
2873            }
2874        }
2875    }
2876
2877    final void applyUpdateLockStateLocked(ActivityRecord r) {
2878        // Modifications to the UpdateLock state are done on our handler, outside
2879        // the activity manager's locks.  The new state is determined based on the
2880        // state *now* of the relevant activity record.  The object is passed to
2881        // the handler solely for logging detail, not to be consulted/modified.
2882        final boolean nextState = r != null && r.immersive;
2883        mHandler.sendMessage(
2884                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2885    }
2886
2887    final void applyUpdateVrModeLocked(ActivityRecord r) {
2888        mHandler.sendMessage(
2889                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2890    }
2891
2892    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2893        Message msg = Message.obtain();
2894        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2895        msg.obj = r.task.askedCompatMode ? null : r;
2896        mUiHandler.sendMessage(msg);
2897    }
2898
2899    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2900            String what, Object obj, ProcessRecord srcApp) {
2901        app.lastActivityTime = now;
2902
2903        if (app.activities.size() > 0) {
2904            // Don't want to touch dependent processes that are hosting activities.
2905            return index;
2906        }
2907
2908        int lrui = mLruProcesses.lastIndexOf(app);
2909        if (lrui < 0) {
2910            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2911                    + what + " " + obj + " from " + srcApp);
2912            return index;
2913        }
2914
2915        if (lrui >= index) {
2916            // Don't want to cause this to move dependent processes *back* in the
2917            // list as if they were less frequently used.
2918            return index;
2919        }
2920
2921        if (lrui >= mLruProcessActivityStart) {
2922            // Don't want to touch dependent processes that are hosting activities.
2923            return index;
2924        }
2925
2926        mLruProcesses.remove(lrui);
2927        if (index > 0) {
2928            index--;
2929        }
2930        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2931                + " in LRU list: " + app);
2932        mLruProcesses.add(index, app);
2933        return index;
2934    }
2935
2936    private static void killProcessGroup(int uid, int pid) {
2937        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2938        Process.killProcessGroup(uid, pid);
2939        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2940    }
2941
2942    final void removeLruProcessLocked(ProcessRecord app) {
2943        int lrui = mLruProcesses.lastIndexOf(app);
2944        if (lrui >= 0) {
2945            if (!app.killed) {
2946                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2947                Process.killProcessQuiet(app.pid);
2948                killProcessGroup(app.info.uid, app.pid);
2949            }
2950            if (lrui <= mLruProcessActivityStart) {
2951                mLruProcessActivityStart--;
2952            }
2953            if (lrui <= mLruProcessServiceStart) {
2954                mLruProcessServiceStart--;
2955            }
2956            mLruProcesses.remove(lrui);
2957        }
2958    }
2959
2960    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2961            ProcessRecord client) {
2962        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2963                || app.treatLikeActivity;
2964        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2965        if (!activityChange && hasActivity) {
2966            // The process has activities, so we are only allowing activity-based adjustments
2967            // to move it.  It should be kept in the front of the list with other
2968            // processes that have activities, and we don't want those to change their
2969            // order except due to activity operations.
2970            return;
2971        }
2972
2973        mLruSeq++;
2974        final long now = SystemClock.uptimeMillis();
2975        app.lastActivityTime = now;
2976
2977        // First a quick reject: if the app is already at the position we will
2978        // put it, then there is nothing to do.
2979        if (hasActivity) {
2980            final int N = mLruProcesses.size();
2981            if (N > 0 && mLruProcesses.get(N-1) == app) {
2982                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2983                return;
2984            }
2985        } else {
2986            if (mLruProcessServiceStart > 0
2987                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2988                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2989                return;
2990            }
2991        }
2992
2993        int lrui = mLruProcesses.lastIndexOf(app);
2994
2995        if (app.persistent && lrui >= 0) {
2996            // We don't care about the position of persistent processes, as long as
2997            // they are in the list.
2998            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2999            return;
3000        }
3001
3002        /* In progress: compute new position first, so we can avoid doing work
3003           if the process is not actually going to move.  Not yet working.
3004        int addIndex;
3005        int nextIndex;
3006        boolean inActivity = false, inService = false;
3007        if (hasActivity) {
3008            // Process has activities, put it at the very tipsy-top.
3009            addIndex = mLruProcesses.size();
3010            nextIndex = mLruProcessServiceStart;
3011            inActivity = true;
3012        } else if (hasService) {
3013            // Process has services, put it at the top of the service list.
3014            addIndex = mLruProcessActivityStart;
3015            nextIndex = mLruProcessServiceStart;
3016            inActivity = true;
3017            inService = true;
3018        } else  {
3019            // Process not otherwise of interest, it goes to the top of the non-service area.
3020            addIndex = mLruProcessServiceStart;
3021            if (client != null) {
3022                int clientIndex = mLruProcesses.lastIndexOf(client);
3023                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3024                        + app);
3025                if (clientIndex >= 0 && addIndex > clientIndex) {
3026                    addIndex = clientIndex;
3027                }
3028            }
3029            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3030        }
3031
3032        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3033                + mLruProcessActivityStart + "): " + app);
3034        */
3035
3036        if (lrui >= 0) {
3037            if (lrui < mLruProcessActivityStart) {
3038                mLruProcessActivityStart--;
3039            }
3040            if (lrui < mLruProcessServiceStart) {
3041                mLruProcessServiceStart--;
3042            }
3043            /*
3044            if (addIndex > lrui) {
3045                addIndex--;
3046            }
3047            if (nextIndex > lrui) {
3048                nextIndex--;
3049            }
3050            */
3051            mLruProcesses.remove(lrui);
3052        }
3053
3054        /*
3055        mLruProcesses.add(addIndex, app);
3056        if (inActivity) {
3057            mLruProcessActivityStart++;
3058        }
3059        if (inService) {
3060            mLruProcessActivityStart++;
3061        }
3062        */
3063
3064        int nextIndex;
3065        if (hasActivity) {
3066            final int N = mLruProcesses.size();
3067            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3068                // Process doesn't have activities, but has clients with
3069                // activities...  move it up, but one below the top (the top
3070                // should always have a real activity).
3071                if (DEBUG_LRU) Slog.d(TAG_LRU,
3072                        "Adding to second-top of LRU activity list: " + app);
3073                mLruProcesses.add(N - 1, app);
3074                // To keep it from spamming the LRU list (by making a bunch of clients),
3075                // we will push down any other entries owned by the app.
3076                final int uid = app.info.uid;
3077                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3078                    ProcessRecord subProc = mLruProcesses.get(i);
3079                    if (subProc.info.uid == uid) {
3080                        // We want to push this one down the list.  If the process after
3081                        // it is for the same uid, however, don't do so, because we don't
3082                        // want them internally to be re-ordered.
3083                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3084                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3085                                    "Pushing uid " + uid + " swapping at " + i + ": "
3086                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3087                            ProcessRecord tmp = mLruProcesses.get(i);
3088                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3089                            mLruProcesses.set(i - 1, tmp);
3090                            i--;
3091                        }
3092                    } else {
3093                        // A gap, we can stop here.
3094                        break;
3095                    }
3096                }
3097            } else {
3098                // Process has activities, put it at the very tipsy-top.
3099                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3100                mLruProcesses.add(app);
3101            }
3102            nextIndex = mLruProcessServiceStart;
3103        } else if (hasService) {
3104            // Process has services, put it at the top of the service list.
3105            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3106            mLruProcesses.add(mLruProcessActivityStart, app);
3107            nextIndex = mLruProcessServiceStart;
3108            mLruProcessActivityStart++;
3109        } else  {
3110            // Process not otherwise of interest, it goes to the top of the non-service area.
3111            int index = mLruProcessServiceStart;
3112            if (client != null) {
3113                // If there is a client, don't allow the process to be moved up higher
3114                // in the list than that client.
3115                int clientIndex = mLruProcesses.lastIndexOf(client);
3116                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3117                        + " when updating " + app);
3118                if (clientIndex <= lrui) {
3119                    // Don't allow the client index restriction to push it down farther in the
3120                    // list than it already is.
3121                    clientIndex = lrui;
3122                }
3123                if (clientIndex >= 0 && index > clientIndex) {
3124                    index = clientIndex;
3125                }
3126            }
3127            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3128            mLruProcesses.add(index, app);
3129            nextIndex = index-1;
3130            mLruProcessActivityStart++;
3131            mLruProcessServiceStart++;
3132        }
3133
3134        // If the app is currently using a content provider or service,
3135        // bump those processes as well.
3136        for (int j=app.connections.size()-1; j>=0; j--) {
3137            ConnectionRecord cr = app.connections.valueAt(j);
3138            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3139                    && cr.binding.service.app != null
3140                    && cr.binding.service.app.lruSeq != mLruSeq
3141                    && !cr.binding.service.app.persistent) {
3142                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3143                        "service connection", cr, app);
3144            }
3145        }
3146        for (int j=app.conProviders.size()-1; j>=0; j--) {
3147            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3148            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3149                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3150                        "provider reference", cpr, app);
3151            }
3152        }
3153    }
3154
3155    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3156        if (uid == Process.SYSTEM_UID) {
3157            // The system gets to run in any process.  If there are multiple
3158            // processes with the same uid, just pick the first (this
3159            // should never happen).
3160            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3161            if (procs == null) return null;
3162            final int procCount = procs.size();
3163            for (int i = 0; i < procCount; i++) {
3164                final int procUid = procs.keyAt(i);
3165                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3166                    // Don't use an app process or different user process for system component.
3167                    continue;
3168                }
3169                return procs.valueAt(i);
3170            }
3171        }
3172        ProcessRecord proc = mProcessNames.get(processName, uid);
3173        if (false && proc != null && !keepIfLarge
3174                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3175                && proc.lastCachedPss >= 4000) {
3176            // Turn this condition on to cause killing to happen regularly, for testing.
3177            if (proc.baseProcessTracker != null) {
3178                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3179            }
3180            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3181        } else if (proc != null && !keepIfLarge
3182                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3183                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3184            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3185            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3186                if (proc.baseProcessTracker != null) {
3187                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3188                }
3189                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3190            }
3191        }
3192        return proc;
3193    }
3194
3195    void notifyPackageUse(String packageName) {
3196        IPackageManager pm = AppGlobals.getPackageManager();
3197        try {
3198            pm.notifyPackageUse(packageName);
3199        } catch (RemoteException e) {
3200        }
3201    }
3202
3203    boolean isNextTransitionForward() {
3204        int transit = mWindowManager.getPendingAppTransition();
3205        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3206                || transit == AppTransition.TRANSIT_TASK_OPEN
3207                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3208    }
3209
3210    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3211            String processName, String abiOverride, int uid, Runnable crashHandler) {
3212        synchronized(this) {
3213            ApplicationInfo info = new ApplicationInfo();
3214            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3215            // For isolated processes, the former contains the parent's uid and the latter the
3216            // actual uid of the isolated process.
3217            // In the special case introduced by this method (which is, starting an isolated
3218            // process directly from the SystemServer without an actual parent app process) the
3219            // closest thing to a parent's uid is SYSTEM_UID.
3220            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3221            // the |isolated| logic in the ProcessRecord constructor.
3222            info.uid = Process.SYSTEM_UID;
3223            info.processName = processName;
3224            info.className = entryPoint;
3225            info.packageName = "android";
3226            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3227                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3228                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3229                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3230                    crashHandler);
3231            return proc != null ? proc.pid : 0;
3232        }
3233    }
3234
3235    final ProcessRecord startProcessLocked(String processName,
3236            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3237            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3238            boolean isolated, boolean keepIfLarge) {
3239        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3240                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3241                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3242                null /* crashHandler */);
3243    }
3244
3245    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3246            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3247            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3248            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3249        long startTime = SystemClock.elapsedRealtime();
3250        ProcessRecord app;
3251        if (!isolated) {
3252            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3253            checkTime(startTime, "startProcess: after getProcessRecord");
3254
3255            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3256                // If we are in the background, then check to see if this process
3257                // is bad.  If so, we will just silently fail.
3258                if (mBadProcesses.get(info.processName, info.uid) != null) {
3259                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3260                            + "/" + info.processName);
3261                    return null;
3262                }
3263            } else {
3264                // When the user is explicitly starting a process, then clear its
3265                // crash count so that we won't make it bad until they see at
3266                // least one crash dialog again, and make the process good again
3267                // if it had been bad.
3268                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3269                        + "/" + info.processName);
3270                mProcessCrashTimes.remove(info.processName, info.uid);
3271                if (mBadProcesses.get(info.processName, info.uid) != null) {
3272                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3273                            UserHandle.getUserId(info.uid), info.uid,
3274                            info.processName);
3275                    mBadProcesses.remove(info.processName, info.uid);
3276                    if (app != null) {
3277                        app.bad = false;
3278                    }
3279                }
3280            }
3281        } else {
3282            // If this is an isolated process, it can't re-use an existing process.
3283            app = null;
3284        }
3285
3286        // app launch boost for big.little configurations
3287        // use cpusets to migrate freshly launched tasks to big cores
3288        synchronized(ActivityManagerService.this) {
3289            nativeMigrateToBoost();
3290            mIsBoosted = true;
3291            mBoostStartTime = SystemClock.uptimeMillis();
3292            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3293            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3294        }
3295
3296        // We don't have to do anything more if:
3297        // (1) There is an existing application record; and
3298        // (2) The caller doesn't think it is dead, OR there is no thread
3299        //     object attached to it so we know it couldn't have crashed; and
3300        // (3) There is a pid assigned to it, so it is either starting or
3301        //     already running.
3302        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3303                + " app=" + app + " knownToBeDead=" + knownToBeDead
3304                + " thread=" + (app != null ? app.thread : null)
3305                + " pid=" + (app != null ? app.pid : -1));
3306        if (app != null && app.pid > 0) {
3307            if (!knownToBeDead || app.thread == null) {
3308                // We already have the app running, or are waiting for it to
3309                // come up (we have a pid but not yet its thread), so keep it.
3310                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3311                // If this is a new package in the process, add the package to the list
3312                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3313                checkTime(startTime, "startProcess: done, added package to proc");
3314                return app;
3315            }
3316
3317            // An application record is attached to a previous process,
3318            // clean it up now.
3319            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3320            checkTime(startTime, "startProcess: bad proc running, killing");
3321            killProcessGroup(app.info.uid, app.pid);
3322            handleAppDiedLocked(app, true, true);
3323            checkTime(startTime, "startProcess: done killing old proc");
3324        }
3325
3326        String hostingNameStr = hostingName != null
3327                ? hostingName.flattenToShortString() : null;
3328
3329        if (app == null) {
3330            checkTime(startTime, "startProcess: creating new process record");
3331            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3332            if (app == null) {
3333                Slog.w(TAG, "Failed making new process record for "
3334                        + processName + "/" + info.uid + " isolated=" + isolated);
3335                return null;
3336            }
3337            app.crashHandler = crashHandler;
3338            checkTime(startTime, "startProcess: done creating new process record");
3339        } else {
3340            // If this is a new package in the process, add the package to the list
3341            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3342            checkTime(startTime, "startProcess: added package to existing proc");
3343        }
3344
3345        // If the system is not ready yet, then hold off on starting this
3346        // process until it is.
3347        if (!mProcessesReady
3348                && !isAllowedWhileBooting(info)
3349                && !allowWhileBooting) {
3350            if (!mProcessesOnHold.contains(app)) {
3351                mProcessesOnHold.add(app);
3352            }
3353            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3354                    "System not ready, putting on hold: " + app);
3355            checkTime(startTime, "startProcess: returning with proc on hold");
3356            return app;
3357        }
3358
3359        checkTime(startTime, "startProcess: stepping in to startProcess");
3360        startProcessLocked(
3361                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3362        checkTime(startTime, "startProcess: done starting proc!");
3363        return (app.pid != 0) ? app : null;
3364    }
3365
3366    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3367        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3368    }
3369
3370    private final void startProcessLocked(ProcessRecord app,
3371            String hostingType, String hostingNameStr) {
3372        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3373                null /* entryPoint */, null /* entryPointArgs */);
3374    }
3375
3376    private final void startProcessLocked(ProcessRecord app, String hostingType,
3377            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3378        long startTime = SystemClock.elapsedRealtime();
3379        if (app.pid > 0 && app.pid != MY_PID) {
3380            checkTime(startTime, "startProcess: removing from pids map");
3381            synchronized (mPidsSelfLocked) {
3382                mPidsSelfLocked.remove(app.pid);
3383                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3384            }
3385            checkTime(startTime, "startProcess: done removing from pids map");
3386            app.setPid(0);
3387        }
3388
3389        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3390                "startProcessLocked removing on hold: " + app);
3391        mProcessesOnHold.remove(app);
3392
3393        checkTime(startTime, "startProcess: starting to update cpu stats");
3394        updateCpuStats();
3395        checkTime(startTime, "startProcess: done updating cpu stats");
3396
3397        try {
3398            try {
3399                final int userId = UserHandle.getUserId(app.uid);
3400                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3401            } catch (RemoteException e) {
3402                throw e.rethrowAsRuntimeException();
3403            }
3404
3405            int uid = app.uid;
3406            int[] gids = null;
3407            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3408            if (!app.isolated) {
3409                int[] permGids = null;
3410                try {
3411                    checkTime(startTime, "startProcess: getting gids from package manager");
3412                    final IPackageManager pm = AppGlobals.getPackageManager();
3413                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3414                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3415                            MountServiceInternal.class);
3416                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3417                            app.info.packageName);
3418                } catch (RemoteException e) {
3419                    throw e.rethrowAsRuntimeException();
3420                }
3421
3422                /*
3423                 * Add shared application and profile GIDs so applications can share some
3424                 * resources like shared libraries and access user-wide resources
3425                 */
3426                if (ArrayUtils.isEmpty(permGids)) {
3427                    gids = new int[2];
3428                } else {
3429                    gids = new int[permGids.length + 2];
3430                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3431                }
3432                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3433                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3434            }
3435            checkTime(startTime, "startProcess: building args");
3436            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3437                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3438                        && mTopComponent != null
3439                        && app.processName.equals(mTopComponent.getPackageName())) {
3440                    uid = 0;
3441                }
3442                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3443                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3444                    uid = 0;
3445                }
3446            }
3447            int debugFlags = 0;
3448            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3449                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3450                // Also turn on CheckJNI for debuggable apps. It's quite
3451                // awkward to turn on otherwise.
3452                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3453            }
3454            // Run the app in safe mode if its manifest requests so or the
3455            // system is booted in safe mode.
3456            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3457                mSafeMode == true) {
3458                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3459            }
3460            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3461                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3462            }
3463            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3464            if ("true".equals(genDebugInfoProperty)) {
3465                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3466            }
3467            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3468                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3469            }
3470            if ("1".equals(SystemProperties.get("debug.assert"))) {
3471                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3472            }
3473
3474            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3475            if (requiredAbi == null) {
3476                requiredAbi = Build.SUPPORTED_ABIS[0];
3477            }
3478
3479            String instructionSet = null;
3480            if (app.info.primaryCpuAbi != null) {
3481                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3482            }
3483
3484            app.gids = gids;
3485            app.requiredAbi = requiredAbi;
3486            app.instructionSet = instructionSet;
3487
3488            // Start the process.  It will either succeed and return a result containing
3489            // the PID of the new process, or else throw a RuntimeException.
3490            boolean isActivityProcess = (entryPoint == null);
3491            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3492            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3493                    app.processName);
3494            checkTime(startTime, "startProcess: asking zygote to start proc");
3495            Process.ProcessStartResult startResult = Process.start(entryPoint,
3496                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3497                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3498                    app.info.dataDir, entryPointArgs);
3499            checkTime(startTime, "startProcess: returned from zygote!");
3500            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3501
3502            if (app.isolated) {
3503                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3504            }
3505            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3506            checkTime(startTime, "startProcess: done updating battery stats");
3507
3508            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3509                    UserHandle.getUserId(uid), startResult.pid, uid,
3510                    app.processName, hostingType,
3511                    hostingNameStr != null ? hostingNameStr : "");
3512
3513            if (app.persistent) {
3514                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3515            }
3516
3517            if (DEBUG_PROCESSES) {
3518                checkTime(startTime, "startProcess: building log message");
3519                StringBuilder buf = mStringBuilder;
3520                buf.setLength(0);
3521                buf.append("Start proc ");
3522                buf.append(startResult.pid);
3523                buf.append(':');
3524                buf.append(app.processName);
3525                buf.append('/');
3526                UserHandle.formatUid(buf, uid);
3527                if (!isActivityProcess) {
3528                    buf.append(" [");
3529                    buf.append(entryPoint);
3530                    buf.append("]");
3531                }
3532                buf.append(" for ");
3533                buf.append(hostingType);
3534                if (hostingNameStr != null) {
3535                    buf.append(" ");
3536                    buf.append(hostingNameStr);
3537                }
3538                Slog.i(TAG, buf.toString());
3539            }
3540            app.setPid(startResult.pid);
3541            app.usingWrapper = startResult.usingWrapper;
3542            app.removed = false;
3543            app.killed = false;
3544            app.killedByAm = false;
3545            checkTime(startTime, "startProcess: starting to update pids map");
3546            synchronized (mPidsSelfLocked) {
3547                this.mPidsSelfLocked.put(startResult.pid, app);
3548                if (isActivityProcess) {
3549                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3550                    msg.obj = app;
3551                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3552                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3553                }
3554            }
3555            checkTime(startTime, "startProcess: done updating pids map");
3556        } catch (RuntimeException e) {
3557            // XXX do better error recovery.
3558            app.setPid(0);
3559            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3560            if (app.isolated) {
3561                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3562            }
3563            Slog.e(TAG, "Failure starting process " + app.processName, e);
3564        }
3565    }
3566
3567    void updateUsageStats(ActivityRecord component, boolean resumed) {
3568        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3569                "updateUsageStats: comp=" + component + "res=" + resumed);
3570        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3571        if (resumed) {
3572            if (mUsageStatsService != null) {
3573                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3574                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3575            }
3576            synchronized (stats) {
3577                stats.noteActivityResumedLocked(component.app.uid);
3578            }
3579        } else {
3580            if (mUsageStatsService != null) {
3581                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3582                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3583            }
3584            synchronized (stats) {
3585                stats.noteActivityPausedLocked(component.app.uid);
3586            }
3587        }
3588    }
3589
3590    Intent getHomeIntent() {
3591        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3592        intent.setComponent(mTopComponent);
3593        intent.addFlags(Intent.FLAG_DEBUG_ENCRYPTION_TRIAGED);
3594        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3595            intent.addCategory(Intent.CATEGORY_HOME);
3596        }
3597        return intent;
3598    }
3599
3600    boolean startHomeActivityLocked(int userId, String reason) {
3601        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3602                && mTopAction == null) {
3603            // We are running in factory test mode, but unable to find
3604            // the factory test app, so just sit around displaying the
3605            // error message and don't try to start anything.
3606            return false;
3607        }
3608        Intent intent = getHomeIntent();
3609        ActivityInfo aInfo =
3610            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3611        if (aInfo != null) {
3612            intent.setComponent(new ComponentName(
3613                    aInfo.applicationInfo.packageName, aInfo.name));
3614            // Don't do this if the home app is currently being
3615            // instrumented.
3616            aInfo = new ActivityInfo(aInfo);
3617            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3618            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3619                    aInfo.applicationInfo.uid, true);
3620            if (app == null || app.instrumentationClass == null) {
3621                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3622                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3623            }
3624        }
3625
3626        return true;
3627    }
3628
3629    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3630        ActivityInfo ai = null;
3631        ComponentName comp = intent.getComponent();
3632        try {
3633            if (comp != null) {
3634                // Factory test.
3635                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3636            } else {
3637                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3638                        intent,
3639                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3640                        flags, userId);
3641
3642                if (info != null) {
3643                    ai = info.activityInfo;
3644                }
3645            }
3646        } catch (RemoteException e) {
3647            // ignore
3648        }
3649
3650        return ai;
3651    }
3652
3653    /**
3654     * Starts the "new version setup screen" if appropriate.
3655     */
3656    void startSetupActivityLocked() {
3657        // Only do this once per boot.
3658        if (mCheckedForSetup) {
3659            return;
3660        }
3661
3662        // We will show this screen if the current one is a different
3663        // version than the last one shown, and we are not running in
3664        // low-level factory test mode.
3665        final ContentResolver resolver = mContext.getContentResolver();
3666        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3667                Settings.Global.getInt(resolver,
3668                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3669            mCheckedForSetup = true;
3670
3671            // See if we should be showing the platform update setup UI.
3672            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3673            List<ResolveInfo> ris = mContext.getPackageManager()
3674                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3675
3676            // We don't allow third party apps to replace this.
3677            ResolveInfo ri = null;
3678            for (int i=0; ris != null && i<ris.size(); i++) {
3679                if ((ris.get(i).activityInfo.applicationInfo.flags
3680                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3681                    ri = ris.get(i);
3682                    break;
3683                }
3684            }
3685
3686            if (ri != null) {
3687                String vers = ri.activityInfo.metaData != null
3688                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3689                        : null;
3690                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3691                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3692                            Intent.METADATA_SETUP_VERSION);
3693                }
3694                String lastVers = Settings.Secure.getString(
3695                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3696                if (vers != null && !vers.equals(lastVers)) {
3697                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3698                    intent.setComponent(new ComponentName(
3699                            ri.activityInfo.packageName, ri.activityInfo.name));
3700                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3701                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3702                            null, 0, 0, 0, null, false, false, null, null, null);
3703                }
3704            }
3705        }
3706    }
3707
3708    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3709        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3710    }
3711
3712    void enforceNotIsolatedCaller(String caller) {
3713        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3714            throw new SecurityException("Isolated process not allowed to call " + caller);
3715        }
3716    }
3717
3718    void enforceShellRestriction(String restriction, int userHandle) {
3719        if (Binder.getCallingUid() == Process.SHELL_UID) {
3720            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3721                throw new SecurityException("Shell does not have permission to access user "
3722                        + userHandle);
3723            }
3724        }
3725    }
3726
3727    @Override
3728    public int getFrontActivityScreenCompatMode() {
3729        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3730        synchronized (this) {
3731            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3732        }
3733    }
3734
3735    @Override
3736    public void setFrontActivityScreenCompatMode(int mode) {
3737        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3738                "setFrontActivityScreenCompatMode");
3739        synchronized (this) {
3740            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3741        }
3742    }
3743
3744    @Override
3745    public int getPackageScreenCompatMode(String packageName) {
3746        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3747        synchronized (this) {
3748            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3749        }
3750    }
3751
3752    @Override
3753    public void setPackageScreenCompatMode(String packageName, int mode) {
3754        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3755                "setPackageScreenCompatMode");
3756        synchronized (this) {
3757            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3758        }
3759    }
3760
3761    @Override
3762    public boolean getPackageAskScreenCompat(String packageName) {
3763        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3764        synchronized (this) {
3765            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3766        }
3767    }
3768
3769    @Override
3770    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3771        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3772                "setPackageAskScreenCompat");
3773        synchronized (this) {
3774            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3775        }
3776    }
3777
3778    private boolean hasUsageStatsPermission(String callingPackage) {
3779        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3780                Binder.getCallingUid(), callingPackage);
3781        if (mode == AppOpsManager.MODE_DEFAULT) {
3782            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3783                    == PackageManager.PERMISSION_GRANTED;
3784        }
3785        return mode == AppOpsManager.MODE_ALLOWED;
3786    }
3787
3788    @Override
3789    public int getPackageProcessState(String packageName, String callingPackage) {
3790        if (!hasUsageStatsPermission(callingPackage)) {
3791            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3792                    "getPackageProcessState");
3793        }
3794
3795        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3796        synchronized (this) {
3797            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3798                final ProcessRecord proc = mLruProcesses.get(i);
3799                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3800                        || procState > proc.setProcState) {
3801                    boolean found = false;
3802                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3803                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3804                            procState = proc.setProcState;
3805                            found = true;
3806                        }
3807                    }
3808                    if (proc.pkgDeps != null && !found) {
3809                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3810                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3811                                procState = proc.setProcState;
3812                                break;
3813                            }
3814                        }
3815                    }
3816                }
3817            }
3818        }
3819        return procState;
3820    }
3821
3822    @Override
3823    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3824        synchronized (this) {
3825            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3826            if (app == null) {
3827                return false;
3828            }
3829            if (app.trimMemoryLevel < level && app.thread != null &&
3830                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3831                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3832                try {
3833                    app.thread.scheduleTrimMemory(level);
3834                    app.trimMemoryLevel = level;
3835                    return true;
3836                } catch (RemoteException e) {
3837                    // Fallthrough to failure case.
3838                }
3839            }
3840        }
3841        return false;
3842    }
3843
3844    private void dispatchProcessesChanged() {
3845        int N;
3846        synchronized (this) {
3847            N = mPendingProcessChanges.size();
3848            if (mActiveProcessChanges.length < N) {
3849                mActiveProcessChanges = new ProcessChangeItem[N];
3850            }
3851            mPendingProcessChanges.toArray(mActiveProcessChanges);
3852            mPendingProcessChanges.clear();
3853            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3854                    "*** Delivering " + N + " process changes");
3855        }
3856
3857        int i = mProcessObservers.beginBroadcast();
3858        while (i > 0) {
3859            i--;
3860            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3861            if (observer != null) {
3862                try {
3863                    for (int j=0; j<N; j++) {
3864                        ProcessChangeItem item = mActiveProcessChanges[j];
3865                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3866                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3867                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3868                                    + item.uid + ": " + item.foregroundActivities);
3869                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3870                                    item.foregroundActivities);
3871                        }
3872                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3873                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3874                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3875                                    + ": " + item.processState);
3876                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3877                        }
3878                    }
3879                } catch (RemoteException e) {
3880                }
3881            }
3882        }
3883        mProcessObservers.finishBroadcast();
3884
3885        synchronized (this) {
3886            for (int j=0; j<N; j++) {
3887                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3888            }
3889        }
3890    }
3891
3892    private void dispatchProcessDied(int pid, int uid) {
3893        int i = mProcessObservers.beginBroadcast();
3894        while (i > 0) {
3895            i--;
3896            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3897            if (observer != null) {
3898                try {
3899                    observer.onProcessDied(pid, uid);
3900                } catch (RemoteException e) {
3901                }
3902            }
3903        }
3904        mProcessObservers.finishBroadcast();
3905    }
3906
3907    private void dispatchUidsChanged() {
3908        int N;
3909        synchronized (this) {
3910            N = mPendingUidChanges.size();
3911            if (mActiveUidChanges.length < N) {
3912                mActiveUidChanges = new UidRecord.ChangeItem[N];
3913            }
3914            for (int i=0; i<N; i++) {
3915                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3916                mActiveUidChanges[i] = change;
3917                if (change.uidRecord != null) {
3918                    change.uidRecord.pendingChange = null;
3919                    change.uidRecord = null;
3920                }
3921            }
3922            mPendingUidChanges.clear();
3923            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3924                    "*** Delivering " + N + " uid changes");
3925        }
3926
3927        if (mLocalPowerManager != null) {
3928            for (int j=0; j<N; j++) {
3929                UidRecord.ChangeItem item = mActiveUidChanges[j];
3930                if (item.change == UidRecord.CHANGE_GONE
3931                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3932                    mLocalPowerManager.uidGone(item.uid);
3933                } else {
3934                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3935                }
3936            }
3937        }
3938
3939        int i = mUidObservers.beginBroadcast();
3940        while (i > 0) {
3941            i--;
3942            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3943            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3944            if (observer != null) {
3945                try {
3946                    for (int j=0; j<N; j++) {
3947                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3948                        final int change = item.change;
3949                        UidRecord validateUid = null;
3950                        if (VALIDATE_UID_STATES && i == 0) {
3951                            validateUid = mValidateUids.get(item.uid);
3952                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3953                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3954                                validateUid = new UidRecord(item.uid);
3955                                mValidateUids.put(item.uid, validateUid);
3956                            }
3957                        }
3958                        if (change == UidRecord.CHANGE_IDLE
3959                                || change == UidRecord.CHANGE_GONE_IDLE) {
3960                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3961                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3962                                        "UID idle uid=" + item.uid);
3963                                observer.onUidIdle(item.uid);
3964                            }
3965                            if (VALIDATE_UID_STATES && i == 0) {
3966                                if (validateUid != null) {
3967                                    validateUid.idle = true;
3968                                }
3969                            }
3970                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3971                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3972                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3973                                        "UID active uid=" + item.uid);
3974                                observer.onUidActive(item.uid);
3975                            }
3976                            if (VALIDATE_UID_STATES && i == 0) {
3977                                validateUid.idle = false;
3978                            }
3979                        }
3980                        if (change == UidRecord.CHANGE_GONE
3981                                || change == UidRecord.CHANGE_GONE_IDLE) {
3982                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3983                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3984                                        "UID gone uid=" + item.uid);
3985                                observer.onUidGone(item.uid);
3986                            }
3987                            if (VALIDATE_UID_STATES && i == 0) {
3988                                if (validateUid != null) {
3989                                    mValidateUids.remove(item.uid);
3990                                }
3991                            }
3992                        } else {
3993                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
3994                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3995                                        "UID CHANGED uid=" + item.uid
3996                                                + ": " + item.processState);
3997                                observer.onUidStateChanged(item.uid, item.processState);
3998                            }
3999                            if (VALIDATE_UID_STATES && i == 0) {
4000                                validateUid.curProcState = validateUid.setProcState
4001                                        = item.processState;
4002                            }
4003                        }
4004                    }
4005                } catch (RemoteException e) {
4006                }
4007            }
4008        }
4009        mUidObservers.finishBroadcast();
4010
4011        synchronized (this) {
4012            for (int j=0; j<N; j++) {
4013                mAvailUidChanges.add(mActiveUidChanges[j]);
4014            }
4015        }
4016    }
4017
4018    @Override
4019    public final int startActivity(IApplicationThread caller, String callingPackage,
4020            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4021            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4022        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4023                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4024                UserHandle.getCallingUserId());
4025    }
4026
4027    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4028        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4029        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4030                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4031                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4032
4033        // TODO: Switch to user app stacks here.
4034        String mimeType = intent.getType();
4035        final Uri data = intent.getData();
4036        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4037            mimeType = getProviderMimeType(data, userId);
4038        }
4039        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4040
4041        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4042        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4043                null, 0, 0, null, null, null, null, false, userId, container, null);
4044    }
4045
4046    @Override
4047    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4048            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4049            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4050        enforceNotIsolatedCaller("startActivity");
4051        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4052                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4053        // TODO: Switch to user app stacks here.
4054        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4055                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4056                profilerInfo, null, null, bOptions, false, userId, null, null);
4057    }
4058
4059    @Override
4060    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4061            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4062            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4063            int userId) {
4064
4065        // This is very dangerous -- it allows you to perform a start activity (including
4066        // permission grants) as any app that may launch one of your own activities.  So
4067        // we will only allow this to be done from activities that are part of the core framework,
4068        // and then only when they are running as the system.
4069        final ActivityRecord sourceRecord;
4070        final int targetUid;
4071        final String targetPackage;
4072        synchronized (this) {
4073            if (resultTo == null) {
4074                throw new SecurityException("Must be called from an activity");
4075            }
4076            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4077            if (sourceRecord == null) {
4078                throw new SecurityException("Called with bad activity token: " + resultTo);
4079            }
4080            if (!sourceRecord.info.packageName.equals("android")) {
4081                throw new SecurityException(
4082                        "Must be called from an activity that is declared in the android package");
4083            }
4084            if (sourceRecord.app == null) {
4085                throw new SecurityException("Called without a process attached to activity");
4086            }
4087            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4088                // This is still okay, as long as this activity is running under the
4089                // uid of the original calling activity.
4090                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4091                    throw new SecurityException(
4092                            "Calling activity in uid " + sourceRecord.app.uid
4093                                    + " must be system uid or original calling uid "
4094                                    + sourceRecord.launchedFromUid);
4095                }
4096            }
4097            if (ignoreTargetSecurity) {
4098                if (intent.getComponent() == null) {
4099                    throw new SecurityException(
4100                            "Component must be specified with ignoreTargetSecurity");
4101                }
4102                if (intent.getSelector() != null) {
4103                    throw new SecurityException(
4104                            "Selector not allowed with ignoreTargetSecurity");
4105                }
4106            }
4107            targetUid = sourceRecord.launchedFromUid;
4108            targetPackage = sourceRecord.launchedFromPackage;
4109        }
4110
4111        if (userId == UserHandle.USER_NULL) {
4112            userId = UserHandle.getUserId(sourceRecord.app.uid);
4113        }
4114
4115        // TODO: Switch to user app stacks here.
4116        try {
4117            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4118                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4119                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4120            return ret;
4121        } catch (SecurityException e) {
4122            // XXX need to figure out how to propagate to original app.
4123            // A SecurityException here is generally actually a fault of the original
4124            // calling activity (such as a fairly granting permissions), so propagate it
4125            // back to them.
4126            /*
4127            StringBuilder msg = new StringBuilder();
4128            msg.append("While launching");
4129            msg.append(intent.toString());
4130            msg.append(": ");
4131            msg.append(e.getMessage());
4132            */
4133            throw e;
4134        }
4135    }
4136
4137    @Override
4138    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4139            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4140            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4141        enforceNotIsolatedCaller("startActivityAndWait");
4142        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4143                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4144        WaitResult res = new WaitResult();
4145        // TODO: Switch to user app stacks here.
4146        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4147                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4148                bOptions, false, userId, null, null);
4149        return res;
4150    }
4151
4152    @Override
4153    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4154            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4155            int startFlags, Configuration config, Bundle bOptions, int userId) {
4156        enforceNotIsolatedCaller("startActivityWithConfig");
4157        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4158                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4159        // TODO: Switch to user app stacks here.
4160        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4161                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4162                null, null, config, bOptions, false, userId, null, null);
4163        return ret;
4164    }
4165
4166    @Override
4167    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4168            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4169            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4170            throws TransactionTooLargeException {
4171        enforceNotIsolatedCaller("startActivityIntentSender");
4172        // Refuse possible leaked file descriptors
4173        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4174            throw new IllegalArgumentException("File descriptors passed in Intent");
4175        }
4176
4177        IIntentSender sender = intent.getTarget();
4178        if (!(sender instanceof PendingIntentRecord)) {
4179            throw new IllegalArgumentException("Bad PendingIntent object");
4180        }
4181
4182        PendingIntentRecord pir = (PendingIntentRecord)sender;
4183
4184        synchronized (this) {
4185            // If this is coming from the currently resumed activity, it is
4186            // effectively saying that app switches are allowed at this point.
4187            final ActivityStack stack = getFocusedStack();
4188            if (stack.mResumedActivity != null &&
4189                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4190                mAppSwitchesAllowedTime = 0;
4191            }
4192        }
4193        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4194                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4195        return ret;
4196    }
4197
4198    @Override
4199    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4200            Intent intent, String resolvedType, IVoiceInteractionSession session,
4201            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4202            Bundle bOptions, int userId) {
4203        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4204                != PackageManager.PERMISSION_GRANTED) {
4205            String msg = "Permission Denial: startVoiceActivity() from pid="
4206                    + Binder.getCallingPid()
4207                    + ", uid=" + Binder.getCallingUid()
4208                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4209            Slog.w(TAG, msg);
4210            throw new SecurityException(msg);
4211        }
4212        if (session == null || interactor == null) {
4213            throw new NullPointerException("null session or interactor");
4214        }
4215        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4216                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4217        // TODO: Switch to user app stacks here.
4218        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4219                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4220                null, bOptions, false, userId, null, null);
4221    }
4222
4223    @Override
4224    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4225        synchronized (this) {
4226            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4227                if (keepAwake) {
4228                    mVoiceWakeLock.acquire();
4229                } else {
4230                    mVoiceWakeLock.release();
4231                }
4232            }
4233        }
4234    }
4235
4236    @Override
4237    public boolean startNextMatchingActivity(IBinder callingActivity,
4238            Intent intent, Bundle bOptions) {
4239        // Refuse possible leaked file descriptors
4240        if (intent != null && intent.hasFileDescriptors() == true) {
4241            throw new IllegalArgumentException("File descriptors passed in Intent");
4242        }
4243        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4244
4245        synchronized (this) {
4246            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4247            if (r == null) {
4248                ActivityOptions.abort(options);
4249                return false;
4250            }
4251            if (r.app == null || r.app.thread == null) {
4252                // The caller is not running...  d'oh!
4253                ActivityOptions.abort(options);
4254                return false;
4255            }
4256            intent = new Intent(intent);
4257            // The caller is not allowed to change the data.
4258            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4259            // And we are resetting to find the next component...
4260            intent.setComponent(null);
4261
4262            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4263
4264            ActivityInfo aInfo = null;
4265            try {
4266                List<ResolveInfo> resolves =
4267                    AppGlobals.getPackageManager().queryIntentActivities(
4268                            intent, r.resolvedType,
4269                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4270                            UserHandle.getCallingUserId());
4271
4272                // Look for the original activity in the list...
4273                final int N = resolves != null ? resolves.size() : 0;
4274                for (int i=0; i<N; i++) {
4275                    ResolveInfo rInfo = resolves.get(i);
4276                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4277                            && rInfo.activityInfo.name.equals(r.info.name)) {
4278                        // We found the current one...  the next matching is
4279                        // after it.
4280                        i++;
4281                        if (i<N) {
4282                            aInfo = resolves.get(i).activityInfo;
4283                        }
4284                        if (debug) {
4285                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4286                                    + "/" + r.info.name);
4287                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4288                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4289                        }
4290                        break;
4291                    }
4292                }
4293            } catch (RemoteException e) {
4294            }
4295
4296            if (aInfo == null) {
4297                // Nobody who is next!
4298                ActivityOptions.abort(options);
4299                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4300                return false;
4301            }
4302
4303            intent.setComponent(new ComponentName(
4304                    aInfo.applicationInfo.packageName, aInfo.name));
4305            intent.setFlags(intent.getFlags()&~(
4306                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4307                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4308                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4309                    Intent.FLAG_ACTIVITY_NEW_TASK));
4310
4311            // Okay now we need to start the new activity, replacing the
4312            // currently running activity.  This is a little tricky because
4313            // we want to start the new one as if the current one is finished,
4314            // but not finish the current one first so that there is no flicker.
4315            // And thus...
4316            final boolean wasFinishing = r.finishing;
4317            r.finishing = true;
4318
4319            // Propagate reply information over to the new activity.
4320            final ActivityRecord resultTo = r.resultTo;
4321            final String resultWho = r.resultWho;
4322            final int requestCode = r.requestCode;
4323            r.resultTo = null;
4324            if (resultTo != null) {
4325                resultTo.removeResultsLocked(r, resultWho, requestCode);
4326            }
4327
4328            final long origId = Binder.clearCallingIdentity();
4329            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4330                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4331                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4332                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4333                    false, false, null, null, null);
4334            Binder.restoreCallingIdentity(origId);
4335
4336            r.finishing = wasFinishing;
4337            if (res != ActivityManager.START_SUCCESS) {
4338                return false;
4339            }
4340            return true;
4341        }
4342    }
4343
4344    @Override
4345    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4346        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4347            String msg = "Permission Denial: startActivityFromRecents called without " +
4348                    START_TASKS_FROM_RECENTS;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352        final long origId = Binder.clearCallingIdentity();
4353        try {
4354            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4355        } finally {
4356            Binder.restoreCallingIdentity(origId);
4357        }
4358    }
4359
4360    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4361        final TaskRecord task;
4362        final int callingUid;
4363        final String callingPackage;
4364        final Intent intent;
4365        final int userId;
4366        synchronized (this) {
4367            if (launchStackId == HOME_STACK_ID) {
4368                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4369                        + taskId + " can't be launch in the home stack.");
4370            }
4371
4372            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4373            if (task == null) {
4374                throw new IllegalArgumentException(
4375                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4376            }
4377
4378            if (launchStackId != INVALID_STACK_ID) {
4379                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4380                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4381                    mWindowManager.setDockedStackCreateState(activityOptions.getDockCreateMode(),
4382                            null /* initialBounds */);
4383                }
4384                if (task.stack.mStackId != launchStackId) {
4385                    mStackSupervisor.moveTaskToStackLocked(
4386                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4387                            ANIMATE);
4388                }
4389            }
4390
4391            if (task.getRootActivity() != null) {
4392                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4393                return ActivityManager.START_TASK_TO_FRONT;
4394            }
4395            callingUid = task.mCallingUid;
4396            callingPackage = task.mCallingPackage;
4397            intent = task.intent;
4398            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4399            userId = task.userId;
4400        }
4401        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4402                bOptions, userId, null, task);
4403    }
4404
4405    final int startActivityInPackage(int uid, String callingPackage,
4406            Intent intent, String resolvedType, IBinder resultTo,
4407            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4408            IActivityContainer container, TaskRecord inTask) {
4409
4410        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4411                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4412
4413        // TODO: Switch to user app stacks here.
4414        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4415                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4416                null, null, null, bOptions, false, userId, container, inTask);
4417        return ret;
4418    }
4419
4420    @Override
4421    public final int startActivities(IApplicationThread caller, String callingPackage,
4422            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4423            int userId) {
4424        enforceNotIsolatedCaller("startActivities");
4425        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4426                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4427        // TODO: Switch to user app stacks here.
4428        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4429                resolvedTypes, resultTo, bOptions, userId);
4430        return ret;
4431    }
4432
4433    final int startActivitiesInPackage(int uid, String callingPackage,
4434            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4435            Bundle bOptions, int userId) {
4436
4437        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4438                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4439        // TODO: Switch to user app stacks here.
4440        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4441                resultTo, bOptions, userId);
4442        return ret;
4443    }
4444
4445    @Override
4446    public void reportActivityFullyDrawn(IBinder token) {
4447        synchronized (this) {
4448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4449            if (r == null) {
4450                return;
4451            }
4452            r.reportFullyDrawnLocked();
4453        }
4454    }
4455
4456    @Override
4457    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4458        synchronized (this) {
4459            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4460            if (r == null) {
4461                return;
4462            }
4463            TaskRecord task = r.task;
4464            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4465                // Fixed screen orientation isn't supported when activities aren't in full screen
4466                // mode.
4467                return;
4468            }
4469            final long origId = Binder.clearCallingIdentity();
4470            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4471            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4472                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4473            if (config != null) {
4474                r.frozenBeforeDestroy = true;
4475                if (!updateConfigurationLocked(config, r, false)) {
4476                    mStackSupervisor.resumeTopActivitiesLocked();
4477                }
4478            }
4479            Binder.restoreCallingIdentity(origId);
4480        }
4481    }
4482
4483    @Override
4484    public int getRequestedOrientation(IBinder token) {
4485        synchronized (this) {
4486            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4487            if (r == null) {
4488                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4489            }
4490            return mWindowManager.getAppOrientation(r.appToken);
4491        }
4492    }
4493
4494    /**
4495     * This is the internal entry point for handling Activity.finish().
4496     *
4497     * @param token The Binder token referencing the Activity we want to finish.
4498     * @param resultCode Result code, if any, from this Activity.
4499     * @param resultData Result data (Intent), if any, from this Activity.
4500     * @param finishTask Whether to finish the task associated with this Activity.
4501     *
4502     * @return Returns true if the activity successfully finished, or false if it is still running.
4503     */
4504    @Override
4505    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4506            int finishTask) {
4507        // Refuse possible leaked file descriptors
4508        if (resultData != null && resultData.hasFileDescriptors() == true) {
4509            throw new IllegalArgumentException("File descriptors passed in Intent");
4510        }
4511
4512        synchronized(this) {
4513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4514            if (r == null) {
4515                return true;
4516            }
4517            // Keep track of the root activity of the task before we finish it
4518            TaskRecord tr = r.task;
4519            ActivityRecord rootR = tr.getRootActivity();
4520            if (rootR == null) {
4521                Slog.w(TAG, "Finishing task with all activities already finished");
4522            }
4523            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4524            // finish.
4525            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4526                    mStackSupervisor.isLastLockedTask(tr)) {
4527                Slog.i(TAG, "Not finishing task in lock task mode");
4528                mStackSupervisor.showLockTaskToast();
4529                return false;
4530            }
4531            if (mController != null) {
4532                // Find the first activity that is not finishing.
4533                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4534                if (next != null) {
4535                    // ask watcher if this is allowed
4536                    boolean resumeOK = true;
4537                    try {
4538                        resumeOK = mController.activityResuming(next.packageName);
4539                    } catch (RemoteException e) {
4540                        mController = null;
4541                        Watchdog.getInstance().setActivityController(null);
4542                    }
4543
4544                    if (!resumeOK) {
4545                        Slog.i(TAG, "Not finishing activity because controller resumed");
4546                        return false;
4547                    }
4548                }
4549            }
4550            final long origId = Binder.clearCallingIdentity();
4551            try {
4552                boolean res;
4553                final boolean finishWithRootActivity =
4554                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4555                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4556                        || (finishWithRootActivity && r == rootR)) {
4557                    // If requested, remove the task that is associated to this activity only if it
4558                    // was the root activity in the task. The result code and data is ignored
4559                    // because we don't support returning them across task boundaries. Also, to
4560                    // keep backwards compatibility we remove the task from recents when finishing
4561                    // task with root activity.
4562                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4563                    if (!res) {
4564                        Slog.i(TAG, "Removing task failed to finish activity");
4565                    }
4566                } else {
4567                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4568                            resultData, "app-request", true);
4569                    if (!res) {
4570                        Slog.i(TAG, "Failed to finish by app-request");
4571                    }
4572                }
4573                return res;
4574            } finally {
4575                Binder.restoreCallingIdentity(origId);
4576            }
4577        }
4578    }
4579
4580    @Override
4581    public final void finishHeavyWeightApp() {
4582        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4583                != PackageManager.PERMISSION_GRANTED) {
4584            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4585                    + Binder.getCallingPid()
4586                    + ", uid=" + Binder.getCallingUid()
4587                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4588            Slog.w(TAG, msg);
4589            throw new SecurityException(msg);
4590        }
4591
4592        synchronized(this) {
4593            if (mHeavyWeightProcess == null) {
4594                return;
4595            }
4596
4597            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4598            for (int i = 0; i < activities.size(); i++) {
4599                ActivityRecord r = activities.get(i);
4600                if (!r.finishing && r.isInStackLocked()) {
4601                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4602                            null, "finish-heavy", true);
4603                }
4604            }
4605
4606            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4607                    mHeavyWeightProcess.userId, 0));
4608            mHeavyWeightProcess = null;
4609        }
4610    }
4611
4612    @Override
4613    public void crashApplication(int uid, int initialPid, String packageName,
4614            String message) {
4615        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4616                != PackageManager.PERMISSION_GRANTED) {
4617            String msg = "Permission Denial: crashApplication() from pid="
4618                    + Binder.getCallingPid()
4619                    + ", uid=" + Binder.getCallingUid()
4620                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4621            Slog.w(TAG, msg);
4622            throw new SecurityException(msg);
4623        }
4624
4625        synchronized(this) {
4626            ProcessRecord proc = null;
4627
4628            // Figure out which process to kill.  We don't trust that initialPid
4629            // still has any relation to current pids, so must scan through the
4630            // list.
4631            synchronized (mPidsSelfLocked) {
4632                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4633                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4634                    if (p.uid != uid) {
4635                        continue;
4636                    }
4637                    if (p.pid == initialPid) {
4638                        proc = p;
4639                        break;
4640                    }
4641                    if (p.pkgList.containsKey(packageName)) {
4642                        proc = p;
4643                    }
4644                }
4645            }
4646
4647            if (proc == null) {
4648                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4649                        + " initialPid=" + initialPid
4650                        + " packageName=" + packageName);
4651                return;
4652            }
4653
4654            if (proc.thread != null) {
4655                if (proc.pid == Process.myPid()) {
4656                    Log.w(TAG, "crashApplication: trying to crash self!");
4657                    return;
4658                }
4659                long ident = Binder.clearCallingIdentity();
4660                try {
4661                    proc.thread.scheduleCrash(message);
4662                } catch (RemoteException e) {
4663                }
4664                Binder.restoreCallingIdentity(ident);
4665            }
4666        }
4667    }
4668
4669    @Override
4670    public final void finishSubActivity(IBinder token, String resultWho,
4671            int requestCode) {
4672        synchronized(this) {
4673            final long origId = Binder.clearCallingIdentity();
4674            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4675            if (r != null) {
4676                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4677            }
4678            Binder.restoreCallingIdentity(origId);
4679        }
4680    }
4681
4682    @Override
4683    public boolean finishActivityAffinity(IBinder token) {
4684        synchronized(this) {
4685            final long origId = Binder.clearCallingIdentity();
4686            try {
4687                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4688                if (r == null) {
4689                    return false;
4690                }
4691
4692                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4693                // can finish.
4694                final TaskRecord task = r.task;
4695                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4696                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4697                    mStackSupervisor.showLockTaskToast();
4698                    return false;
4699                }
4700                return task.stack.finishActivityAffinityLocked(r);
4701            } finally {
4702                Binder.restoreCallingIdentity(origId);
4703            }
4704        }
4705    }
4706
4707    @Override
4708    public void finishVoiceTask(IVoiceInteractionSession session) {
4709        synchronized(this) {
4710            final long origId = Binder.clearCallingIdentity();
4711            try {
4712                mStackSupervisor.finishVoiceTask(session);
4713            } finally {
4714                Binder.restoreCallingIdentity(origId);
4715            }
4716        }
4717
4718    }
4719
4720    @Override
4721    public boolean releaseActivityInstance(IBinder token) {
4722        synchronized(this) {
4723            final long origId = Binder.clearCallingIdentity();
4724            try {
4725                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4726                if (r == null) {
4727                    return false;
4728                }
4729                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4730            } finally {
4731                Binder.restoreCallingIdentity(origId);
4732            }
4733        }
4734    }
4735
4736    @Override
4737    public void releaseSomeActivities(IApplicationThread appInt) {
4738        synchronized(this) {
4739            final long origId = Binder.clearCallingIdentity();
4740            try {
4741                ProcessRecord app = getRecordForAppLocked(appInt);
4742                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4743            } finally {
4744                Binder.restoreCallingIdentity(origId);
4745            }
4746        }
4747    }
4748
4749    @Override
4750    public boolean willActivityBeVisible(IBinder token) {
4751        synchronized(this) {
4752            ActivityStack stack = ActivityRecord.getStackLocked(token);
4753            if (stack != null) {
4754                return stack.willActivityBeVisibleLocked(token);
4755            }
4756            return false;
4757        }
4758    }
4759
4760    @Override
4761    public void overridePendingTransition(IBinder token, String packageName,
4762            int enterAnim, int exitAnim) {
4763        synchronized(this) {
4764            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4765            if (self == null) {
4766                return;
4767            }
4768
4769            final long origId = Binder.clearCallingIdentity();
4770
4771            if (self.state == ActivityState.RESUMED
4772                    || self.state == ActivityState.PAUSING) {
4773                mWindowManager.overridePendingAppTransition(packageName,
4774                        enterAnim, exitAnim, null);
4775            }
4776
4777            Binder.restoreCallingIdentity(origId);
4778        }
4779    }
4780
4781    /**
4782     * Main function for removing an existing process from the activity manager
4783     * as a result of that process going away.  Clears out all connections
4784     * to the process.
4785     */
4786    private final void handleAppDiedLocked(ProcessRecord app,
4787            boolean restarting, boolean allowRestart) {
4788        int pid = app.pid;
4789        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4790        if (!kept && !restarting) {
4791            removeLruProcessLocked(app);
4792            if (pid > 0) {
4793                ProcessList.remove(pid);
4794            }
4795        }
4796
4797        if (mProfileProc == app) {
4798            clearProfilerLocked();
4799        }
4800
4801        // Remove this application's activities from active lists.
4802        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4803
4804        app.activities.clear();
4805
4806        if (app.instrumentationClass != null) {
4807            Slog.w(TAG, "Crash of app " + app.processName
4808                  + " running instrumentation " + app.instrumentationClass);
4809            Bundle info = new Bundle();
4810            info.putString("shortMsg", "Process crashed.");
4811            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4812        }
4813
4814        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4815            // If there was nothing to resume, and we are not already
4816            // restarting this process, but there is a visible activity that
4817            // is hosted by the process...  then make sure all visible
4818            // activities are running, taking care of restarting this
4819            // process.
4820            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4821        }
4822    }
4823
4824    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4825        IBinder threadBinder = thread.asBinder();
4826        // Find the application record.
4827        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4828            ProcessRecord rec = mLruProcesses.get(i);
4829            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4830                return i;
4831            }
4832        }
4833        return -1;
4834    }
4835
4836    final ProcessRecord getRecordForAppLocked(
4837            IApplicationThread thread) {
4838        if (thread == null) {
4839            return null;
4840        }
4841
4842        int appIndex = getLRURecordIndexForAppLocked(thread);
4843        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4844    }
4845
4846    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4847        // If there are no longer any background processes running,
4848        // and the app that died was not running instrumentation,
4849        // then tell everyone we are now low on memory.
4850        boolean haveBg = false;
4851        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4852            ProcessRecord rec = mLruProcesses.get(i);
4853            if (rec.thread != null
4854                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4855                haveBg = true;
4856                break;
4857            }
4858        }
4859
4860        if (!haveBg) {
4861            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4862            if (doReport) {
4863                long now = SystemClock.uptimeMillis();
4864                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4865                    doReport = false;
4866                } else {
4867                    mLastMemUsageReportTime = now;
4868                }
4869            }
4870            final ArrayList<ProcessMemInfo> memInfos
4871                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4872            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4873            long now = SystemClock.uptimeMillis();
4874            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4875                ProcessRecord rec = mLruProcesses.get(i);
4876                if (rec == dyingProc || rec.thread == null) {
4877                    continue;
4878                }
4879                if (doReport) {
4880                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4881                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4882                }
4883                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4884                    // The low memory report is overriding any current
4885                    // state for a GC request.  Make sure to do
4886                    // heavy/important/visible/foreground processes first.
4887                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4888                        rec.lastRequestedGc = 0;
4889                    } else {
4890                        rec.lastRequestedGc = rec.lastLowMemory;
4891                    }
4892                    rec.reportLowMemory = true;
4893                    rec.lastLowMemory = now;
4894                    mProcessesToGc.remove(rec);
4895                    addProcessToGcListLocked(rec);
4896                }
4897            }
4898            if (doReport) {
4899                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4900                mHandler.sendMessage(msg);
4901            }
4902            scheduleAppGcsLocked();
4903        }
4904    }
4905
4906    final void appDiedLocked(ProcessRecord app) {
4907       appDiedLocked(app, app.pid, app.thread, false);
4908    }
4909
4910    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4911            boolean fromBinderDied) {
4912        // First check if this ProcessRecord is actually active for the pid.
4913        synchronized (mPidsSelfLocked) {
4914            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4915            if (curProc != app) {
4916                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4917                return;
4918            }
4919        }
4920
4921        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4922        synchronized (stats) {
4923            stats.noteProcessDiedLocked(app.info.uid, pid);
4924        }
4925
4926        if (!app.killed) {
4927            if (!fromBinderDied) {
4928                Process.killProcessQuiet(pid);
4929            }
4930            killProcessGroup(app.info.uid, pid);
4931            app.killed = true;
4932        }
4933
4934        // Clean up already done if the process has been re-started.
4935        if (app.pid == pid && app.thread != null &&
4936                app.thread.asBinder() == thread.asBinder()) {
4937            boolean doLowMem = app.instrumentationClass == null;
4938            boolean doOomAdj = doLowMem;
4939            if (!app.killedByAm) {
4940                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4941                        + ") has died");
4942                mAllowLowerMemLevel = true;
4943            } else {
4944                // Note that we always want to do oom adj to update our state with the
4945                // new number of procs.
4946                mAllowLowerMemLevel = false;
4947                doLowMem = false;
4948            }
4949            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4950            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4951                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4952            handleAppDiedLocked(app, false, true);
4953
4954            if (doOomAdj) {
4955                updateOomAdjLocked();
4956            }
4957            if (doLowMem) {
4958                doLowMemReportIfNeededLocked(app);
4959            }
4960        } else if (app.pid != pid) {
4961            // A new process has already been started.
4962            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4963                    + ") has died and restarted (pid " + app.pid + ").");
4964            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4965        } else if (DEBUG_PROCESSES) {
4966            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4967                    + thread.asBinder());
4968        }
4969    }
4970
4971    /**
4972     * If a stack trace dump file is configured, dump process stack traces.
4973     * @param clearTraces causes the dump file to be erased prior to the new
4974     *    traces being written, if true; when false, the new traces will be
4975     *    appended to any existing file content.
4976     * @param firstPids of dalvik VM processes to dump stack traces for first
4977     * @param lastPids of dalvik VM processes to dump stack traces for last
4978     * @param nativeProcs optional list of native process names to dump stack crawls
4979     * @return file containing stack traces, or null if no dump file is configured
4980     */
4981    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4982            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4983        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4984        if (tracesPath == null || tracesPath.length() == 0) {
4985            return null;
4986        }
4987
4988        File tracesFile = new File(tracesPath);
4989        try {
4990            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4991            tracesFile.createNewFile();
4992            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4993        } catch (IOException e) {
4994            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4995            return null;
4996        }
4997
4998        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4999        return tracesFile;
5000    }
5001
5002    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5003            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5004        // Use a FileObserver to detect when traces finish writing.
5005        // The order of traces is considered important to maintain for legibility.
5006        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5007            @Override
5008            public synchronized void onEvent(int event, String path) { notify(); }
5009        };
5010
5011        try {
5012            observer.startWatching();
5013
5014            // First collect all of the stacks of the most important pids.
5015            if (firstPids != null) {
5016                try {
5017                    int num = firstPids.size();
5018                    for (int i = 0; i < num; i++) {
5019                        synchronized (observer) {
5020                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5021                            observer.wait(200);  // Wait for write-close, give up after 200msec
5022                        }
5023                    }
5024                } catch (InterruptedException e) {
5025                    Slog.wtf(TAG, e);
5026                }
5027            }
5028
5029            // Next collect the stacks of the native pids
5030            if (nativeProcs != null) {
5031                int[] pids = Process.getPidsForCommands(nativeProcs);
5032                if (pids != null) {
5033                    for (int pid : pids) {
5034                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5035                    }
5036                }
5037            }
5038
5039            // Lastly, measure CPU usage.
5040            if (processCpuTracker != null) {
5041                processCpuTracker.init();
5042                System.gc();
5043                processCpuTracker.update();
5044                try {
5045                    synchronized (processCpuTracker) {
5046                        processCpuTracker.wait(500); // measure over 1/2 second.
5047                    }
5048                } catch (InterruptedException e) {
5049                }
5050                processCpuTracker.update();
5051
5052                // We'll take the stack crawls of just the top apps using CPU.
5053                final int N = processCpuTracker.countWorkingStats();
5054                int numProcs = 0;
5055                for (int i=0; i<N && numProcs<5; i++) {
5056                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5057                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5058                        numProcs++;
5059                        try {
5060                            synchronized (observer) {
5061                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5062                                observer.wait(200);  // Wait for write-close, give up after 200msec
5063                            }
5064                        } catch (InterruptedException e) {
5065                            Slog.wtf(TAG, e);
5066                        }
5067
5068                    }
5069                }
5070            }
5071        } finally {
5072            observer.stopWatching();
5073        }
5074    }
5075
5076    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5077        if (true || IS_USER_BUILD) {
5078            return;
5079        }
5080        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5081        if (tracesPath == null || tracesPath.length() == 0) {
5082            return;
5083        }
5084
5085        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5086        StrictMode.allowThreadDiskWrites();
5087        try {
5088            final File tracesFile = new File(tracesPath);
5089            final File tracesDir = tracesFile.getParentFile();
5090            final File tracesTmp = new File(tracesDir, "__tmp__");
5091            try {
5092                if (tracesFile.exists()) {
5093                    tracesTmp.delete();
5094                    tracesFile.renameTo(tracesTmp);
5095                }
5096                StringBuilder sb = new StringBuilder();
5097                Time tobj = new Time();
5098                tobj.set(System.currentTimeMillis());
5099                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5100                sb.append(": ");
5101                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5102                sb.append(" since ");
5103                sb.append(msg);
5104                FileOutputStream fos = new FileOutputStream(tracesFile);
5105                fos.write(sb.toString().getBytes());
5106                if (app == null) {
5107                    fos.write("\n*** No application process!".getBytes());
5108                }
5109                fos.close();
5110                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5111            } catch (IOException e) {
5112                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5113                return;
5114            }
5115
5116            if (app != null) {
5117                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5118                firstPids.add(app.pid);
5119                dumpStackTraces(tracesPath, firstPids, null, null, null);
5120            }
5121
5122            File lastTracesFile = null;
5123            File curTracesFile = null;
5124            for (int i=9; i>=0; i--) {
5125                String name = String.format(Locale.US, "slow%02d.txt", i);
5126                curTracesFile = new File(tracesDir, name);
5127                if (curTracesFile.exists()) {
5128                    if (lastTracesFile != null) {
5129                        curTracesFile.renameTo(lastTracesFile);
5130                    } else {
5131                        curTracesFile.delete();
5132                    }
5133                }
5134                lastTracesFile = curTracesFile;
5135            }
5136            tracesFile.renameTo(curTracesFile);
5137            if (tracesTmp.exists()) {
5138                tracesTmp.renameTo(tracesFile);
5139            }
5140        } finally {
5141            StrictMode.setThreadPolicy(oldPolicy);
5142        }
5143    }
5144
5145    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5146            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5147        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5148        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5149
5150        if (mController != null) {
5151            try {
5152                // 0 == continue, -1 = kill process immediately
5153                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5154                if (res < 0 && app.pid != MY_PID) {
5155                    app.kill("anr", true);
5156                }
5157            } catch (RemoteException e) {
5158                mController = null;
5159                Watchdog.getInstance().setActivityController(null);
5160            }
5161        }
5162
5163        long anrTime = SystemClock.uptimeMillis();
5164        if (MONITOR_CPU_USAGE) {
5165            updateCpuStatsNow();
5166        }
5167
5168        synchronized (this) {
5169            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5170            if (mShuttingDown) {
5171                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5172                return;
5173            } else if (app.notResponding) {
5174                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5175                return;
5176            } else if (app.crashing) {
5177                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5178                return;
5179            }
5180
5181            // In case we come through here for the same app before completing
5182            // this one, mark as anring now so we will bail out.
5183            app.notResponding = true;
5184
5185            // Log the ANR to the event log.
5186            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5187                    app.processName, app.info.flags, annotation);
5188
5189            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5190            firstPids.add(app.pid);
5191
5192            int parentPid = app.pid;
5193            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5194            if (parentPid != app.pid) firstPids.add(parentPid);
5195
5196            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5197
5198            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5199                ProcessRecord r = mLruProcesses.get(i);
5200                if (r != null && r.thread != null) {
5201                    int pid = r.pid;
5202                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5203                        if (r.persistent) {
5204                            firstPids.add(pid);
5205                        } else {
5206                            lastPids.put(pid, Boolean.TRUE);
5207                        }
5208                    }
5209                }
5210            }
5211        }
5212
5213        // Log the ANR to the main log.
5214        StringBuilder info = new StringBuilder();
5215        info.setLength(0);
5216        info.append("ANR in ").append(app.processName);
5217        if (activity != null && activity.shortComponentName != null) {
5218            info.append(" (").append(activity.shortComponentName).append(")");
5219        }
5220        info.append("\n");
5221        info.append("PID: ").append(app.pid).append("\n");
5222        if (annotation != null) {
5223            info.append("Reason: ").append(annotation).append("\n");
5224        }
5225        if (parent != null && parent != activity) {
5226            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5227        }
5228
5229        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5230
5231        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5232                NATIVE_STACKS_OF_INTEREST);
5233
5234        String cpuInfo = null;
5235        if (MONITOR_CPU_USAGE) {
5236            updateCpuStatsNow();
5237            synchronized (mProcessCpuTracker) {
5238                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5239            }
5240            info.append(processCpuTracker.printCurrentLoad());
5241            info.append(cpuInfo);
5242        }
5243
5244        info.append(processCpuTracker.printCurrentState(anrTime));
5245
5246        Slog.e(TAG, info.toString());
5247        if (tracesFile == null) {
5248            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5249            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5250        }
5251
5252        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5253                cpuInfo, tracesFile, null);
5254
5255        if (mController != null) {
5256            try {
5257                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5258                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5259                if (res != 0) {
5260                    if (res < 0 && app.pid != MY_PID) {
5261                        app.kill("anr", true);
5262                    } else {
5263                        synchronized (this) {
5264                            mServices.scheduleServiceTimeoutLocked(app);
5265                        }
5266                    }
5267                    return;
5268                }
5269            } catch (RemoteException e) {
5270                mController = null;
5271                Watchdog.getInstance().setActivityController(null);
5272            }
5273        }
5274
5275        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5276        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5277                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5278
5279        synchronized (this) {
5280            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5281
5282            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5283                app.kill("bg anr", true);
5284                return;
5285            }
5286
5287            // Set the app's notResponding state, and look up the errorReportReceiver
5288            makeAppNotRespondingLocked(app,
5289                    activity != null ? activity.shortComponentName : null,
5290                    annotation != null ? "ANR " + annotation : "ANR",
5291                    info.toString());
5292
5293            // Bring up the infamous App Not Responding dialog
5294            Message msg = Message.obtain();
5295            HashMap<String, Object> map = new HashMap<String, Object>();
5296            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5297            msg.obj = map;
5298            msg.arg1 = aboveSystem ? 1 : 0;
5299            map.put("app", app);
5300            if (activity != null) {
5301                map.put("activity", activity);
5302            }
5303
5304            mUiHandler.sendMessage(msg);
5305        }
5306    }
5307
5308    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5309        if (!mLaunchWarningShown) {
5310            mLaunchWarningShown = true;
5311            mUiHandler.post(new Runnable() {
5312                @Override
5313                public void run() {
5314                    synchronized (ActivityManagerService.this) {
5315                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5316                        d.show();
5317                        mUiHandler.postDelayed(new Runnable() {
5318                            @Override
5319                            public void run() {
5320                                synchronized (ActivityManagerService.this) {
5321                                    d.dismiss();
5322                                    mLaunchWarningShown = false;
5323                                }
5324                            }
5325                        }, 4000);
5326                    }
5327                }
5328            });
5329        }
5330    }
5331
5332    @Override
5333    public boolean clearApplicationUserData(final String packageName,
5334            final IPackageDataObserver observer, int userId) {
5335        enforceNotIsolatedCaller("clearApplicationUserData");
5336        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5337            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5338        }
5339        int uid = Binder.getCallingUid();
5340        int pid = Binder.getCallingPid();
5341        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5342                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5343        long callingId = Binder.clearCallingIdentity();
5344        try {
5345            IPackageManager pm = AppGlobals.getPackageManager();
5346            int pkgUid = -1;
5347            synchronized(this) {
5348                try {
5349                    pkgUid = pm.getPackageUid(packageName, userId);
5350                } catch (RemoteException e) {
5351                }
5352                if (pkgUid == -1) {
5353                    Slog.w(TAG, "Invalid packageName: " + packageName);
5354                    if (observer != null) {
5355                        try {
5356                            observer.onRemoveCompleted(packageName, false);
5357                        } catch (RemoteException e) {
5358                            Slog.i(TAG, "Observer no longer exists.");
5359                        }
5360                    }
5361                    return false;
5362                }
5363                if (uid == pkgUid || checkComponentPermission(
5364                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5365                        pid, uid, -1, true)
5366                        == PackageManager.PERMISSION_GRANTED) {
5367                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5368                } else {
5369                    throw new SecurityException("PID " + pid + " does not have permission "
5370                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5371                                    + " of package " + packageName);
5372                }
5373
5374                // Remove all tasks match the cleared application package and user
5375                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5376                    final TaskRecord tr = mRecentTasks.get(i);
5377                    final String taskPackageName =
5378                            tr.getBaseIntent().getComponent().getPackageName();
5379                    if (tr.userId != userId) continue;
5380                    if (!taskPackageName.equals(packageName)) continue;
5381                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5382                }
5383            }
5384
5385            try {
5386                // Clear application user data
5387                pm.clearApplicationUserData(packageName, observer, userId);
5388
5389                synchronized(this) {
5390                    // Remove all permissions granted from/to this package
5391                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5392                }
5393
5394                // Remove all zen rules created by this package; revoke it's zen access.
5395                INotificationManager inm = NotificationManager.getService();
5396                inm.removeAutomaticZenRules(packageName);
5397                inm.setNotificationPolicyAccessGranted(packageName, false);
5398
5399                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5400                        Uri.fromParts("package", packageName, null));
5401                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5402                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5403                        null, null, 0, null, null, null, null, false, false, userId);
5404            } catch (RemoteException e) {
5405            }
5406        } finally {
5407            Binder.restoreCallingIdentity(callingId);
5408        }
5409        return true;
5410    }
5411
5412    @Override
5413    public void killBackgroundProcesses(final String packageName, int userId) {
5414        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5415                != PackageManager.PERMISSION_GRANTED &&
5416                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5417                        != PackageManager.PERMISSION_GRANTED) {
5418            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5419                    + Binder.getCallingPid()
5420                    + ", uid=" + Binder.getCallingUid()
5421                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5422            Slog.w(TAG, msg);
5423            throw new SecurityException(msg);
5424        }
5425
5426        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5427                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5428        long callingId = Binder.clearCallingIdentity();
5429        try {
5430            IPackageManager pm = AppGlobals.getPackageManager();
5431            synchronized(this) {
5432                int appId = -1;
5433                try {
5434                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5435                } catch (RemoteException e) {
5436                }
5437                if (appId == -1) {
5438                    Slog.w(TAG, "Invalid packageName: " + packageName);
5439                    return;
5440                }
5441                killPackageProcessesLocked(packageName, appId, userId,
5442                        ProcessList.SERVICE_ADJ, false, true, true, false, true, "kill background");
5443            }
5444        } finally {
5445            Binder.restoreCallingIdentity(callingId);
5446        }
5447    }
5448
5449    @Override
5450    public void killAllBackgroundProcesses() {
5451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5452                != PackageManager.PERMISSION_GRANTED) {
5453            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5454                    + Binder.getCallingPid()
5455                    + ", uid=" + Binder.getCallingUid()
5456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5457            Slog.w(TAG, msg);
5458            throw new SecurityException(msg);
5459        }
5460
5461        long callingId = Binder.clearCallingIdentity();
5462        try {
5463            synchronized(this) {
5464                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5465                final int NP = mProcessNames.getMap().size();
5466                for (int ip=0; ip<NP; ip++) {
5467                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5468                    final int NA = apps.size();
5469                    for (int ia=0; ia<NA; ia++) {
5470                        ProcessRecord app = apps.valueAt(ia);
5471                        if (app.persistent) {
5472                            // we don't kill persistent processes
5473                            continue;
5474                        }
5475                        if (app.removed) {
5476                            procs.add(app);
5477                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5478                            app.removed = true;
5479                            procs.add(app);
5480                        }
5481                    }
5482                }
5483
5484                int N = procs.size();
5485                for (int i=0; i<N; i++) {
5486                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5487                }
5488                mAllowLowerMemLevel = true;
5489                updateOomAdjLocked();
5490                doLowMemReportIfNeededLocked(null);
5491            }
5492        } finally {
5493            Binder.restoreCallingIdentity(callingId);
5494        }
5495    }
5496
5497    @Override
5498    public void forceStopPackage(final String packageName, int userId) {
5499        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5500                != PackageManager.PERMISSION_GRANTED) {
5501            String msg = "Permission Denial: forceStopPackage() from pid="
5502                    + Binder.getCallingPid()
5503                    + ", uid=" + Binder.getCallingUid()
5504                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5505            Slog.w(TAG, msg);
5506            throw new SecurityException(msg);
5507        }
5508        final int callingPid = Binder.getCallingPid();
5509        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5510                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5511        long callingId = Binder.clearCallingIdentity();
5512        try {
5513            IPackageManager pm = AppGlobals.getPackageManager();
5514            synchronized(this) {
5515                int[] users = userId == UserHandle.USER_ALL
5516                        ? mUserController.getUsers() : new int[] { userId };
5517                for (int user : users) {
5518                    int pkgUid = -1;
5519                    try {
5520                        pkgUid = pm.getPackageUid(packageName, user);
5521                    } catch (RemoteException e) {
5522                    }
5523                    if (pkgUid == -1) {
5524                        Slog.w(TAG, "Invalid packageName: " + packageName);
5525                        continue;
5526                    }
5527                    try {
5528                        pm.setPackageStoppedState(packageName, true, user);
5529                    } catch (RemoteException e) {
5530                    } catch (IllegalArgumentException e) {
5531                        Slog.w(TAG, "Failed trying to unstop package "
5532                                + packageName + ": " + e);
5533                    }
5534                    if (mUserController.isUserRunningLocked(user, 0)) {
5535                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5536                    }
5537                }
5538            }
5539        } finally {
5540            Binder.restoreCallingIdentity(callingId);
5541        }
5542    }
5543
5544    @Override
5545    public void addPackageDependency(String packageName) {
5546        synchronized (this) {
5547            int callingPid = Binder.getCallingPid();
5548            if (callingPid == Process.myPid()) {
5549                //  Yeah, um, no.
5550                return;
5551            }
5552            ProcessRecord proc;
5553            synchronized (mPidsSelfLocked) {
5554                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5555            }
5556            if (proc != null) {
5557                if (proc.pkgDeps == null) {
5558                    proc.pkgDeps = new ArraySet<String>(1);
5559                }
5560                proc.pkgDeps.add(packageName);
5561            }
5562        }
5563    }
5564
5565    /*
5566     * The pkg name and app id have to be specified.
5567     */
5568    @Override
5569    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5570        if (pkg == null) {
5571            return;
5572        }
5573        // Make sure the uid is valid.
5574        if (appid < 0) {
5575            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5576            return;
5577        }
5578        int callerUid = Binder.getCallingUid();
5579        // Only the system server can kill an application
5580        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5581            // Post an aysnc message to kill the application
5582            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5583            msg.arg1 = appid;
5584            msg.arg2 = 0;
5585            Bundle bundle = new Bundle();
5586            bundle.putString("pkg", pkg);
5587            bundle.putString("reason", reason);
5588            msg.obj = bundle;
5589            mHandler.sendMessage(msg);
5590        } else {
5591            throw new SecurityException(callerUid + " cannot kill pkg: " +
5592                    pkg);
5593        }
5594    }
5595
5596    @Override
5597    public void closeSystemDialogs(String reason) {
5598        enforceNotIsolatedCaller("closeSystemDialogs");
5599
5600        final int pid = Binder.getCallingPid();
5601        final int uid = Binder.getCallingUid();
5602        final long origId = Binder.clearCallingIdentity();
5603        try {
5604            synchronized (this) {
5605                // Only allow this from foreground processes, so that background
5606                // applications can't abuse it to prevent system UI from being shown.
5607                if (uid >= Process.FIRST_APPLICATION_UID) {
5608                    ProcessRecord proc;
5609                    synchronized (mPidsSelfLocked) {
5610                        proc = mPidsSelfLocked.get(pid);
5611                    }
5612                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5613                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5614                                + " from background process " + proc);
5615                        return;
5616                    }
5617                }
5618                closeSystemDialogsLocked(reason);
5619            }
5620        } finally {
5621            Binder.restoreCallingIdentity(origId);
5622        }
5623    }
5624
5625    void closeSystemDialogsLocked(String reason) {
5626        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5627        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5628                | Intent.FLAG_RECEIVER_FOREGROUND);
5629        if (reason != null) {
5630            intent.putExtra("reason", reason);
5631        }
5632        mWindowManager.closeSystemDialogs(reason);
5633
5634        mStackSupervisor.closeSystemDialogsLocked();
5635
5636        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5637                AppOpsManager.OP_NONE, null, false, false,
5638                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5639    }
5640
5641    @Override
5642    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5643        enforceNotIsolatedCaller("getProcessMemoryInfo");
5644        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5645        for (int i=pids.length-1; i>=0; i--) {
5646            ProcessRecord proc;
5647            int oomAdj;
5648            synchronized (this) {
5649                synchronized (mPidsSelfLocked) {
5650                    proc = mPidsSelfLocked.get(pids[i]);
5651                    oomAdj = proc != null ? proc.setAdj : 0;
5652                }
5653            }
5654            infos[i] = new Debug.MemoryInfo();
5655            Debug.getMemoryInfo(pids[i], infos[i]);
5656            if (proc != null) {
5657                synchronized (this) {
5658                    if (proc.thread != null && proc.setAdj == oomAdj) {
5659                        // Record this for posterity if the process has been stable.
5660                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5661                                infos[i].getTotalUss(), false, proc.pkgList);
5662                    }
5663                }
5664            }
5665        }
5666        return infos;
5667    }
5668
5669    @Override
5670    public long[] getProcessPss(int[] pids) {
5671        enforceNotIsolatedCaller("getProcessPss");
5672        long[] pss = new long[pids.length];
5673        for (int i=pids.length-1; i>=0; i--) {
5674            ProcessRecord proc;
5675            int oomAdj;
5676            synchronized (this) {
5677                synchronized (mPidsSelfLocked) {
5678                    proc = mPidsSelfLocked.get(pids[i]);
5679                    oomAdj = proc != null ? proc.setAdj : 0;
5680                }
5681            }
5682            long[] tmpUss = new long[1];
5683            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5684            if (proc != null) {
5685                synchronized (this) {
5686                    if (proc.thread != null && proc.setAdj == oomAdj) {
5687                        // Record this for posterity if the process has been stable.
5688                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5689                    }
5690                }
5691            }
5692        }
5693        return pss;
5694    }
5695
5696    @Override
5697    public void killApplicationProcess(String processName, int uid) {
5698        if (processName == null) {
5699            return;
5700        }
5701
5702        int callerUid = Binder.getCallingUid();
5703        // Only the system server can kill an application
5704        if (callerUid == Process.SYSTEM_UID) {
5705            synchronized (this) {
5706                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5707                if (app != null && app.thread != null) {
5708                    try {
5709                        app.thread.scheduleSuicide();
5710                    } catch (RemoteException e) {
5711                        // If the other end already died, then our work here is done.
5712                    }
5713                } else {
5714                    Slog.w(TAG, "Process/uid not found attempting kill of "
5715                            + processName + " / " + uid);
5716                }
5717            }
5718        } else {
5719            throw new SecurityException(callerUid + " cannot kill app process: " +
5720                    processName);
5721        }
5722    }
5723
5724    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5725        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5726                false, true, false, false, UserHandle.getUserId(uid), reason);
5727        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5728                Uri.fromParts("package", packageName, null));
5729        if (!mProcessesReady) {
5730            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5731                    | Intent.FLAG_RECEIVER_FOREGROUND);
5732        }
5733        intent.putExtra(Intent.EXTRA_UID, uid);
5734        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5735        broadcastIntentLocked(null, null, intent,
5736                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5737                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5738    }
5739
5740
5741    private final boolean killPackageProcessesLocked(String packageName, int appId,
5742            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5743            boolean doit, boolean evenPersistent, boolean killPackageApp, String reason) {
5744        ArrayList<ProcessRecord> procs = new ArrayList<>();
5745
5746        // Remove all processes this package may have touched: all with the
5747        // same UID (except for the system or root user), and all whose name
5748        // matches the package name.
5749        final int NP = mProcessNames.getMap().size();
5750        for (int ip=0; ip<NP; ip++) {
5751            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5752            final int NA = apps.size();
5753            for (int ia=0; ia<NA; ia++) {
5754                ProcessRecord app = apps.valueAt(ia);
5755                if (app.persistent && !evenPersistent) {
5756                    // we don't kill persistent processes
5757                    continue;
5758                }
5759                if (app.removed) {
5760                    if (doit) {
5761                        procs.add(app);
5762                    }
5763                    continue;
5764                }
5765
5766                // Skip process if it doesn't meet our oom adj requirement.
5767                if (app.setAdj < minOomAdj) {
5768                    continue;
5769                }
5770
5771                // If no package is specified, we call all processes under the
5772                // give user id.
5773                if (packageName == null) {
5774                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5775                        continue;
5776                    }
5777                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5778                        continue;
5779                    }
5780                // Package has been specified, we want to hit all processes
5781                // that match it.  We need to qualify this by the processes
5782                // that are running under the specified app and user ID.
5783                } else {
5784                    final boolean isDep = app.pkgDeps != null
5785                            && app.pkgDeps.contains(packageName);
5786                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5787                        continue;
5788                    }
5789                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5790                        continue;
5791                    }
5792                    if ((!killPackageApp || !app.pkgList.containsKey(packageName)) && !isDep) {
5793                        continue;
5794                    }
5795                }
5796
5797                // Process has passed all conditions, kill it!
5798                if (!doit) {
5799                    return true;
5800                }
5801                app.removed = true;
5802                procs.add(app);
5803            }
5804        }
5805
5806        int N = procs.size();
5807        for (int i=0; i<N; i++) {
5808            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5809        }
5810        updateOomAdjLocked();
5811        return N > 0;
5812    }
5813
5814    private void cleanupDisabledPackageComponentsLocked(
5815            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5816
5817        Set<String> disabledClasses = null;
5818        boolean packageDisabled = false;
5819        IPackageManager pm = AppGlobals.getPackageManager();
5820
5821        if (changedClasses == null) {
5822            // Nothing changed...
5823            return;
5824        }
5825
5826        // Determine enable/disable state of the package and its components.
5827        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5828        for (int i = changedClasses.length - 1; i >= 0; i--) {
5829            final String changedClass = changedClasses[i];
5830
5831            if (changedClass.equals(packageName)) {
5832                try {
5833                    // Entire package setting changed
5834                    enabled = pm.getApplicationEnabledSetting(packageName,
5835                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5836                } catch (Exception e) {
5837                    // No such package/component; probably racing with uninstall.  In any
5838                    // event it means we have nothing further to do here.
5839                    return;
5840                }
5841                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5842                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5843                if (packageDisabled) {
5844                    // Entire package is disabled.
5845                    // No need to continue to check component states.
5846                    disabledClasses = null;
5847                    break;
5848                }
5849            } else {
5850                try {
5851                    enabled = pm.getComponentEnabledSetting(
5852                            new ComponentName(packageName, changedClass),
5853                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5854                } catch (Exception e) {
5855                    // As above, probably racing with uninstall.
5856                    return;
5857                }
5858                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5859                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5860                    if (disabledClasses == null) {
5861                        disabledClasses = new ArraySet<>(changedClasses.length);
5862                    }
5863                    disabledClasses.add(changedClass);
5864                }
5865            }
5866        }
5867
5868        if (!packageDisabled && disabledClasses == null) {
5869            // Nothing to do here...
5870            return;
5871        }
5872
5873        // Clean-up disabled activities.
5874        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5875                packageName, disabledClasses, true, false, userId) && mBooted) {
5876            mStackSupervisor.resumeTopActivitiesLocked();
5877            mStackSupervisor.scheduleIdleLocked();
5878        }
5879
5880        // Clean-up disabled tasks
5881        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5882
5883        // Clean-up disabled services.
5884        mServices.bringDownDisabledPackageServicesLocked(
5885                packageName, disabledClasses, userId, false, killProcess, true);
5886
5887        // Clean-up disabled providers.
5888        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5889        mProviderMap.collectPackageProvidersLocked(
5890                packageName, disabledClasses, true, false, userId, providers);
5891        for (int i = providers.size() - 1; i >= 0; i--) {
5892            removeDyingProviderLocked(null, providers.get(i), true);
5893        }
5894
5895        // Clean-up disabled broadcast receivers.
5896        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5897            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5898                    packageName, disabledClasses, userId, true);
5899        }
5900
5901    }
5902
5903    final boolean forceStopPackageLocked(String packageName, int appId,
5904            boolean callerWillRestart, boolean purgeCache, boolean doit,
5905            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5906        int i;
5907
5908        if (userId == UserHandle.USER_ALL && packageName == null) {
5909            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5910        }
5911
5912        if (appId < 0 && packageName != null) {
5913            try {
5914                appId = UserHandle.getAppId(
5915                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5916            } catch (RemoteException e) {
5917            }
5918        }
5919
5920        if (doit) {
5921            if (packageName != null) {
5922                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5923                        + " user=" + userId + ": " + reason);
5924            } else {
5925                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5926            }
5927
5928            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5929            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5930                SparseArray<Long> ba = pmap.valueAt(ip);
5931                for (i = ba.size() - 1; i >= 0; i--) {
5932                    boolean remove = false;
5933                    final int entUid = ba.keyAt(i);
5934                    if (packageName != null) {
5935                        if (userId == UserHandle.USER_ALL) {
5936                            if (UserHandle.getAppId(entUid) == appId) {
5937                                remove = true;
5938                            }
5939                        } else {
5940                            if (entUid == UserHandle.getUid(userId, appId)) {
5941                                remove = true;
5942                            }
5943                        }
5944                    } else if (UserHandle.getUserId(entUid) == userId) {
5945                        remove = true;
5946                    }
5947                    if (remove) {
5948                        ba.removeAt(i);
5949                    }
5950                }
5951                if (ba.size() == 0) {
5952                    pmap.removeAt(ip);
5953                }
5954            }
5955        }
5956
5957        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5958                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, true,
5959                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5960
5961        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5962                packageName, null, doit, evenPersistent, userId)) {
5963            if (!doit) {
5964                return true;
5965            }
5966            didSomething = true;
5967        }
5968
5969        if (mServices.bringDownDisabledPackageServicesLocked(
5970                packageName, null, userId, evenPersistent, true, doit)) {
5971            if (!doit) {
5972                return true;
5973            }
5974            didSomething = true;
5975        }
5976
5977        if (packageName == null) {
5978            // Remove all sticky broadcasts from this user.
5979            mStickyBroadcasts.remove(userId);
5980        }
5981
5982        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5983        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5984                userId, providers)) {
5985            if (!doit) {
5986                return true;
5987            }
5988            didSomething = true;
5989        }
5990        for (i = providers.size() - 1; i >= 0; i--) {
5991            removeDyingProviderLocked(null, providers.get(i), true);
5992        }
5993
5994        // Remove transient permissions granted from/to this package/user
5995        removeUriPermissionsForPackageLocked(packageName, userId, false);
5996
5997        if (doit) {
5998            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5999                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6000                        packageName, null, userId, doit);
6001            }
6002        }
6003
6004        if (packageName == null || uninstalling) {
6005            // Remove pending intents.  For now we only do this when force
6006            // stopping users, because we have some problems when doing this
6007            // for packages -- app widgets are not currently cleaned up for
6008            // such packages, so they can be left with bad pending intents.
6009            if (mIntentSenderRecords.size() > 0) {
6010                Iterator<WeakReference<PendingIntentRecord>> it
6011                        = mIntentSenderRecords.values().iterator();
6012                while (it.hasNext()) {
6013                    WeakReference<PendingIntentRecord> wpir = it.next();
6014                    if (wpir == null) {
6015                        it.remove();
6016                        continue;
6017                    }
6018                    PendingIntentRecord pir = wpir.get();
6019                    if (pir == null) {
6020                        it.remove();
6021                        continue;
6022                    }
6023                    if (packageName == null) {
6024                        // Stopping user, remove all objects for the user.
6025                        if (pir.key.userId != userId) {
6026                            // Not the same user, skip it.
6027                            continue;
6028                        }
6029                    } else {
6030                        if (UserHandle.getAppId(pir.uid) != appId) {
6031                            // Different app id, skip it.
6032                            continue;
6033                        }
6034                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6035                            // Different user, skip it.
6036                            continue;
6037                        }
6038                        if (!pir.key.packageName.equals(packageName)) {
6039                            // Different package, skip it.
6040                            continue;
6041                        }
6042                    }
6043                    if (!doit) {
6044                        return true;
6045                    }
6046                    didSomething = true;
6047                    it.remove();
6048                    pir.canceled = true;
6049                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6050                        pir.key.activity.pendingResults.remove(pir.ref);
6051                    }
6052                }
6053            }
6054        }
6055
6056        if (doit) {
6057            if (purgeCache && packageName != null) {
6058                AttributeCache ac = AttributeCache.instance();
6059                if (ac != null) {
6060                    ac.removePackage(packageName);
6061                }
6062            }
6063            if (mBooted) {
6064                mStackSupervisor.resumeTopActivitiesLocked();
6065                mStackSupervisor.scheduleIdleLocked();
6066            }
6067        }
6068
6069        return didSomething;
6070    }
6071
6072    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6073        ProcessRecord old = mProcessNames.remove(name, uid);
6074        if (old != null) {
6075            old.uidRecord.numProcs--;
6076            if (old.uidRecord.numProcs == 0) {
6077                // No more processes using this uid, tell clients it is gone.
6078                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6079                        "No more processes in " + old.uidRecord);
6080                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6081                mActiveUids.remove(uid);
6082                mBatteryStatsService.noteUidProcessState(uid,
6083                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6084            }
6085            old.uidRecord = null;
6086        }
6087        mIsolatedProcesses.remove(uid);
6088        return old;
6089    }
6090
6091    private final void addProcessNameLocked(ProcessRecord proc) {
6092        // We shouldn't already have a process under this name, but just in case we
6093        // need to clean up whatever may be there now.
6094        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6095        if (old == proc && proc.persistent) {
6096            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6097            Slog.w(TAG, "Re-adding persistent process " + proc);
6098        } else if (old != null) {
6099            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6100        }
6101        UidRecord uidRec = mActiveUids.get(proc.uid);
6102        if (uidRec == null) {
6103            uidRec = new UidRecord(proc.uid);
6104            // This is the first appearance of the uid, report it now!
6105            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6106                    "Creating new process uid: " + uidRec);
6107            mActiveUids.put(proc.uid, uidRec);
6108            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6109            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6110        }
6111        proc.uidRecord = uidRec;
6112        uidRec.numProcs++;
6113        mProcessNames.put(proc.processName, proc.uid, proc);
6114        if (proc.isolated) {
6115            mIsolatedProcesses.put(proc.uid, proc);
6116        }
6117    }
6118
6119    private final boolean removeProcessLocked(ProcessRecord app,
6120            boolean callerWillRestart, boolean allowRestart, String reason) {
6121        final String name = app.processName;
6122        final int uid = app.uid;
6123        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6124            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6125
6126        removeProcessNameLocked(name, uid);
6127        if (mHeavyWeightProcess == app) {
6128            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6129                    mHeavyWeightProcess.userId, 0));
6130            mHeavyWeightProcess = null;
6131        }
6132        boolean needRestart = false;
6133        if (app.pid > 0 && app.pid != MY_PID) {
6134            int pid = app.pid;
6135            synchronized (mPidsSelfLocked) {
6136                mPidsSelfLocked.remove(pid);
6137                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6138            }
6139            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6140            if (app.isolated) {
6141                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6142            }
6143            boolean willRestart = false;
6144            if (app.persistent && !app.isolated) {
6145                if (!callerWillRestart) {
6146                    willRestart = true;
6147                } else {
6148                    needRestart = true;
6149                }
6150            }
6151            app.kill(reason, true);
6152            handleAppDiedLocked(app, willRestart, allowRestart);
6153            if (willRestart) {
6154                removeLruProcessLocked(app);
6155                addAppLocked(app.info, false, null /* ABI override */);
6156            }
6157        } else {
6158            mRemovedProcesses.add(app);
6159        }
6160
6161        return needRestart;
6162    }
6163
6164    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6165        cleanupAppInLaunchingProvidersLocked(app, true);
6166        removeProcessLocked(app, false, true, "timeout publishing content providers");
6167    }
6168
6169    private final void processStartTimedOutLocked(ProcessRecord app) {
6170        final int pid = app.pid;
6171        boolean gone = false;
6172        synchronized (mPidsSelfLocked) {
6173            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6174            if (knownApp != null && knownApp.thread == null) {
6175                mPidsSelfLocked.remove(pid);
6176                gone = true;
6177            }
6178        }
6179
6180        if (gone) {
6181            Slog.w(TAG, "Process " + app + " failed to attach");
6182            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6183                    pid, app.uid, app.processName);
6184            removeProcessNameLocked(app.processName, app.uid);
6185            if (mHeavyWeightProcess == app) {
6186                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6187                        mHeavyWeightProcess.userId, 0));
6188                mHeavyWeightProcess = null;
6189            }
6190            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6191            if (app.isolated) {
6192                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6193            }
6194            // Take care of any launching providers waiting for this process.
6195            cleanupAppInLaunchingProvidersLocked(app, true);
6196            // Take care of any services that are waiting for the process.
6197            mServices.processStartTimedOutLocked(app);
6198            app.kill("start timeout", true);
6199            removeLruProcessLocked(app);
6200            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6201                Slog.w(TAG, "Unattached app died before backup, skipping");
6202                try {
6203                    IBackupManager bm = IBackupManager.Stub.asInterface(
6204                            ServiceManager.getService(Context.BACKUP_SERVICE));
6205                    bm.agentDisconnected(app.info.packageName);
6206                } catch (RemoteException e) {
6207                    // Can't happen; the backup manager is local
6208                }
6209            }
6210            if (isPendingBroadcastProcessLocked(pid)) {
6211                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6212                skipPendingBroadcastLocked(pid);
6213            }
6214        } else {
6215            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6216        }
6217    }
6218
6219    private final boolean attachApplicationLocked(IApplicationThread thread,
6220            int pid) {
6221
6222        // Find the application record that is being attached...  either via
6223        // the pid if we are running in multiple processes, or just pull the
6224        // next app record if we are emulating process with anonymous threads.
6225        ProcessRecord app;
6226        if (pid != MY_PID && pid >= 0) {
6227            synchronized (mPidsSelfLocked) {
6228                app = mPidsSelfLocked.get(pid);
6229            }
6230        } else {
6231            app = null;
6232        }
6233
6234        if (app == null) {
6235            Slog.w(TAG, "No pending application record for pid " + pid
6236                    + " (IApplicationThread " + thread + "); dropping process");
6237            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6238            if (pid > 0 && pid != MY_PID) {
6239                Process.killProcessQuiet(pid);
6240                //TODO: killProcessGroup(app.info.uid, pid);
6241            } else {
6242                try {
6243                    thread.scheduleExit();
6244                } catch (Exception e) {
6245                    // Ignore exceptions.
6246                }
6247            }
6248            return false;
6249        }
6250
6251        // If this application record is still attached to a previous
6252        // process, clean it up now.
6253        if (app.thread != null) {
6254            handleAppDiedLocked(app, true, true);
6255        }
6256
6257        // Tell the process all about itself.
6258
6259        if (DEBUG_ALL) Slog.v(
6260                TAG, "Binding process pid " + pid + " to record " + app);
6261
6262        final String processName = app.processName;
6263        try {
6264            AppDeathRecipient adr = new AppDeathRecipient(
6265                    app, pid, thread);
6266            thread.asBinder().linkToDeath(adr, 0);
6267            app.deathRecipient = adr;
6268        } catch (RemoteException e) {
6269            app.resetPackageList(mProcessStats);
6270            startProcessLocked(app, "link fail", processName);
6271            return false;
6272        }
6273
6274        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6275
6276        app.makeActive(thread, mProcessStats);
6277        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6278        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6279        app.forcingToForeground = null;
6280        updateProcessForegroundLocked(app, false, false);
6281        app.hasShownUi = false;
6282        app.debugging = false;
6283        app.cached = false;
6284        app.killedByAm = false;
6285
6286        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6287
6288        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6289        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6290
6291        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6292            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6293            msg.obj = app;
6294            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6295        }
6296
6297        if (!normalMode) {
6298            Slog.i(TAG, "Launching preboot mode app: " + app);
6299        }
6300
6301        if (DEBUG_ALL) Slog.v(
6302            TAG, "New app record " + app
6303            + " thread=" + thread.asBinder() + " pid=" + pid);
6304        try {
6305            int testMode = IApplicationThread.DEBUG_OFF;
6306            if (mDebugApp != null && mDebugApp.equals(processName)) {
6307                testMode = mWaitForDebugger
6308                    ? IApplicationThread.DEBUG_WAIT
6309                    : IApplicationThread.DEBUG_ON;
6310                app.debugging = true;
6311                if (mDebugTransient) {
6312                    mDebugApp = mOrigDebugApp;
6313                    mWaitForDebugger = mOrigWaitForDebugger;
6314                }
6315            }
6316            String profileFile = app.instrumentationProfileFile;
6317            ParcelFileDescriptor profileFd = null;
6318            int samplingInterval = 0;
6319            boolean profileAutoStop = false;
6320            if (mProfileApp != null && mProfileApp.equals(processName)) {
6321                mProfileProc = app;
6322                profileFile = mProfileFile;
6323                profileFd = mProfileFd;
6324                samplingInterval = mSamplingInterval;
6325                profileAutoStop = mAutoStopProfiler;
6326            }
6327            boolean enableTrackAllocation = false;
6328            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6329                enableTrackAllocation = true;
6330                mTrackAllocationApp = null;
6331            }
6332
6333            // If the app is being launched for restore or full backup, set it up specially
6334            boolean isRestrictedBackupMode = false;
6335            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6336                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6337                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6338                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6339            }
6340
6341            notifyPackageUse(app.instrumentationInfo != null
6342                    ? app.instrumentationInfo.packageName
6343                    : app.info.packageName);
6344            if (app.instrumentationClass != null) {
6345                notifyPackageUse(app.instrumentationClass.getPackageName());
6346            }
6347            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6348                    + processName + " with config " + mConfiguration);
6349            ApplicationInfo appInfo = app.instrumentationInfo != null
6350                    ? app.instrumentationInfo : app.info;
6351            app.compat = compatibilityInfoForPackageLocked(appInfo);
6352            if (profileFd != null) {
6353                profileFd = profileFd.dup();
6354            }
6355            ProfilerInfo profilerInfo = profileFile == null ? null
6356                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6357            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6358                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6359                    app.instrumentationUiAutomationConnection, testMode,
6360                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6361                    isRestrictedBackupMode || !normalMode, app.persistent,
6362                    new Configuration(mConfiguration), app.compat,
6363                    getCommonServicesLocked(app.isolated),
6364                    mCoreSettingsObserver.getCoreSettingsLocked());
6365            updateLruProcessLocked(app, false, null);
6366            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6367        } catch (Exception e) {
6368            // todo: Yikes!  What should we do?  For now we will try to
6369            // start another process, but that could easily get us in
6370            // an infinite loop of restarting processes...
6371            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6372
6373            app.resetPackageList(mProcessStats);
6374            app.unlinkDeathRecipient();
6375            startProcessLocked(app, "bind fail", processName);
6376            return false;
6377        }
6378
6379        // Remove this record from the list of starting applications.
6380        mPersistentStartingProcesses.remove(app);
6381        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6382                "Attach application locked removing on hold: " + app);
6383        mProcessesOnHold.remove(app);
6384
6385        boolean badApp = false;
6386        boolean didSomething = false;
6387
6388        // See if the top visible activity is waiting to run in this process...
6389        if (normalMode) {
6390            try {
6391                if (mStackSupervisor.attachApplicationLocked(app)) {
6392                    didSomething = true;
6393                }
6394            } catch (Exception e) {
6395                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6396                badApp = true;
6397            }
6398        }
6399
6400        // Find any services that should be running in this process...
6401        if (!badApp) {
6402            try {
6403                didSomething |= mServices.attachApplicationLocked(app, processName);
6404            } catch (Exception e) {
6405                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6406                badApp = true;
6407            }
6408        }
6409
6410        // Check if a next-broadcast receiver is in this process...
6411        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6412            try {
6413                didSomething |= sendPendingBroadcastsLocked(app);
6414            } catch (Exception e) {
6415                // If the app died trying to launch the receiver we declare it 'bad'
6416                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6417                badApp = true;
6418            }
6419        }
6420
6421        // Check whether the next backup agent is in this process...
6422        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6423            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6424                    "New app is backup target, launching agent for " + app);
6425            notifyPackageUse(mBackupTarget.appInfo.packageName);
6426            try {
6427                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6428                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6429                        mBackupTarget.backupMode);
6430            } catch (Exception e) {
6431                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6432                badApp = true;
6433            }
6434        }
6435
6436        if (badApp) {
6437            app.kill("error during init", true);
6438            handleAppDiedLocked(app, false, true);
6439            return false;
6440        }
6441
6442        if (!didSomething) {
6443            updateOomAdjLocked();
6444        }
6445
6446        return true;
6447    }
6448
6449    @Override
6450    public final void attachApplication(IApplicationThread thread) {
6451        synchronized (this) {
6452            int callingPid = Binder.getCallingPid();
6453            final long origId = Binder.clearCallingIdentity();
6454            attachApplicationLocked(thread, callingPid);
6455            Binder.restoreCallingIdentity(origId);
6456        }
6457    }
6458
6459    @Override
6460    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6461        final long origId = Binder.clearCallingIdentity();
6462        synchronized (this) {
6463            ActivityStack stack = ActivityRecord.getStackLocked(token);
6464            if (stack != null) {
6465                ActivityRecord r =
6466                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6467                if (stopProfiling) {
6468                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6469                        try {
6470                            mProfileFd.close();
6471                        } catch (IOException e) {
6472                        }
6473                        clearProfilerLocked();
6474                    }
6475                }
6476            }
6477        }
6478        Binder.restoreCallingIdentity(origId);
6479    }
6480
6481    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6482        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6483                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6484    }
6485
6486    void enableScreenAfterBoot() {
6487        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6488                SystemClock.uptimeMillis());
6489        mWindowManager.enableScreenAfterBoot();
6490
6491        synchronized (this) {
6492            updateEventDispatchingLocked();
6493        }
6494    }
6495
6496    @Override
6497    public void showBootMessage(final CharSequence msg, final boolean always) {
6498        if (Binder.getCallingUid() != Process.myUid()) {
6499            // These days only the core system can call this, so apps can't get in
6500            // the way of what we show about running them.
6501        }
6502        mWindowManager.showBootMessage(msg, always);
6503    }
6504
6505    @Override
6506    public void keyguardWaitingForActivityDrawn() {
6507        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6508        final long token = Binder.clearCallingIdentity();
6509        try {
6510            synchronized (this) {
6511                if (DEBUG_LOCKSCREEN) logLockScreen("");
6512                mWindowManager.keyguardWaitingForActivityDrawn();
6513                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6514                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6515                    updateSleepIfNeededLocked();
6516                }
6517            }
6518        } finally {
6519            Binder.restoreCallingIdentity(token);
6520        }
6521    }
6522
6523    @Override
6524    public void keyguardGoingAway(boolean disableWindowAnimations,
6525            boolean keyguardGoingToNotificationShade) {
6526        enforceNotIsolatedCaller("keyguardGoingAway");
6527        final long token = Binder.clearCallingIdentity();
6528        try {
6529            synchronized (this) {
6530                if (DEBUG_LOCKSCREEN) logLockScreen("");
6531                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6532                        keyguardGoingToNotificationShade);
6533                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6534                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6535                    updateSleepIfNeededLocked();
6536                }
6537            }
6538        } finally {
6539            Binder.restoreCallingIdentity(token);
6540        }
6541    }
6542
6543    final void finishBooting() {
6544        synchronized (this) {
6545            if (!mBootAnimationComplete) {
6546                mCallFinishBooting = true;
6547                return;
6548            }
6549            mCallFinishBooting = false;
6550        }
6551
6552        ArraySet<String> completedIsas = new ArraySet<String>();
6553        for (String abi : Build.SUPPORTED_ABIS) {
6554            Process.establishZygoteConnectionForAbi(abi);
6555            final String instructionSet = VMRuntime.getInstructionSet(abi);
6556            if (!completedIsas.contains(instructionSet)) {
6557                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6558                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6559                }
6560                completedIsas.add(instructionSet);
6561            }
6562        }
6563
6564        IntentFilter pkgFilter = new IntentFilter();
6565        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6566        pkgFilter.addDataScheme("package");
6567        mContext.registerReceiver(new BroadcastReceiver() {
6568            @Override
6569            public void onReceive(Context context, Intent intent) {
6570                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6571                if (pkgs != null) {
6572                    for (String pkg : pkgs) {
6573                        synchronized (ActivityManagerService.this) {
6574                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6575                                    0, "query restart")) {
6576                                setResultCode(Activity.RESULT_OK);
6577                                return;
6578                            }
6579                        }
6580                    }
6581                }
6582            }
6583        }, pkgFilter);
6584
6585        IntentFilter dumpheapFilter = new IntentFilter();
6586        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6587        mContext.registerReceiver(new BroadcastReceiver() {
6588            @Override
6589            public void onReceive(Context context, Intent intent) {
6590                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6591                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6592                } else {
6593                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6594                }
6595            }
6596        }, dumpheapFilter);
6597
6598        // Let system services know.
6599        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6600
6601        synchronized (this) {
6602            // Ensure that any processes we had put on hold are now started
6603            // up.
6604            final int NP = mProcessesOnHold.size();
6605            if (NP > 0) {
6606                ArrayList<ProcessRecord> procs =
6607                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6608                for (int ip=0; ip<NP; ip++) {
6609                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6610                            + procs.get(ip));
6611                    startProcessLocked(procs.get(ip), "on-hold", null);
6612                }
6613            }
6614
6615            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6616                // Start looking for apps that are abusing wake locks.
6617                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6618                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6619                // Tell anyone interested that we are done booting!
6620                SystemProperties.set("sys.boot_completed", "1");
6621
6622                // And trigger dev.bootcomplete if we are not showing encryption progress
6623                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6624                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6625                    SystemProperties.set("dev.bootcomplete", "1");
6626                }
6627                mUserController.sendBootCompletedLocked(
6628                        new IIntentReceiver.Stub() {
6629                            @Override
6630                            public void performReceive(Intent intent, int resultCode,
6631                                    String data, Bundle extras, boolean ordered,
6632                                    boolean sticky, int sendingUser) {
6633                                synchronized (ActivityManagerService.this) {
6634                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6635                                            true, false);
6636                                }
6637                            }
6638                        });
6639                scheduleStartProfilesLocked();
6640            }
6641        }
6642    }
6643
6644    @Override
6645    public void bootAnimationComplete() {
6646        final boolean callFinishBooting;
6647        synchronized (this) {
6648            callFinishBooting = mCallFinishBooting;
6649            mBootAnimationComplete = true;
6650        }
6651        if (callFinishBooting) {
6652            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6653            finishBooting();
6654            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6655        }
6656    }
6657
6658    final void ensureBootCompleted() {
6659        boolean booting;
6660        boolean enableScreen;
6661        synchronized (this) {
6662            booting = mBooting;
6663            mBooting = false;
6664            enableScreen = !mBooted;
6665            mBooted = true;
6666        }
6667
6668        if (booting) {
6669            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6670            finishBooting();
6671            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6672        }
6673
6674        if (enableScreen) {
6675            enableScreenAfterBoot();
6676        }
6677    }
6678
6679    @Override
6680    public final void activityResumed(IBinder token) {
6681        final long origId = Binder.clearCallingIdentity();
6682        synchronized(this) {
6683            ActivityStack stack = ActivityRecord.getStackLocked(token);
6684            if (stack != null) {
6685                ActivityRecord.activityResumedLocked(token);
6686            }
6687        }
6688        Binder.restoreCallingIdentity(origId);
6689    }
6690
6691    @Override
6692    public final void activityPaused(IBinder token) {
6693        final long origId = Binder.clearCallingIdentity();
6694        synchronized(this) {
6695            ActivityStack stack = ActivityRecord.getStackLocked(token);
6696            if (stack != null) {
6697                stack.activityPausedLocked(token, false);
6698            }
6699        }
6700        Binder.restoreCallingIdentity(origId);
6701    }
6702
6703    @Override
6704    public final void activityStopped(IBinder token, Bundle icicle,
6705            PersistableBundle persistentState, CharSequence description) {
6706        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6707
6708        // Refuse possible leaked file descriptors
6709        if (icicle != null && icicle.hasFileDescriptors()) {
6710            throw new IllegalArgumentException("File descriptors passed in Bundle");
6711        }
6712
6713        final long origId = Binder.clearCallingIdentity();
6714
6715        synchronized (this) {
6716            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6717            if (r != null) {
6718                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6719            }
6720        }
6721
6722        trimApplications();
6723
6724        Binder.restoreCallingIdentity(origId);
6725    }
6726
6727    @Override
6728    public final void activityDestroyed(IBinder token) {
6729        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6730        synchronized (this) {
6731            ActivityStack stack = ActivityRecord.getStackLocked(token);
6732            if (stack != null) {
6733                stack.activityDestroyedLocked(token, "activityDestroyed");
6734            }
6735        }
6736    }
6737
6738    @Override
6739    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6740            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6741        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6742                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6743        synchronized (this) {
6744            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6745            if (record == null) {
6746                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6747                        + "found for: " + token);
6748            }
6749            record.setSizeConfigurations(horizontalSizeConfiguration,
6750                    verticalSizeConfigurations, smallestSizeConfigurations);
6751        }
6752    }
6753
6754    @Override
6755    public final void backgroundResourcesReleased(IBinder token) {
6756        final long origId = Binder.clearCallingIdentity();
6757        try {
6758            synchronized (this) {
6759                ActivityStack stack = ActivityRecord.getStackLocked(token);
6760                if (stack != null) {
6761                    stack.backgroundResourcesReleased();
6762                }
6763            }
6764        } finally {
6765            Binder.restoreCallingIdentity(origId);
6766        }
6767    }
6768
6769    @Override
6770    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6771        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6772    }
6773
6774    @Override
6775    public final void notifyEnterAnimationComplete(IBinder token) {
6776        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6777    }
6778
6779    @Override
6780    public String getCallingPackage(IBinder token) {
6781        synchronized (this) {
6782            ActivityRecord r = getCallingRecordLocked(token);
6783            return r != null ? r.info.packageName : null;
6784        }
6785    }
6786
6787    @Override
6788    public ComponentName getCallingActivity(IBinder token) {
6789        synchronized (this) {
6790            ActivityRecord r = getCallingRecordLocked(token);
6791            return r != null ? r.intent.getComponent() : null;
6792        }
6793    }
6794
6795    private ActivityRecord getCallingRecordLocked(IBinder token) {
6796        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6797        if (r == null) {
6798            return null;
6799        }
6800        return r.resultTo;
6801    }
6802
6803    @Override
6804    public ComponentName getActivityClassForToken(IBinder token) {
6805        synchronized(this) {
6806            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6807            if (r == null) {
6808                return null;
6809            }
6810            return r.intent.getComponent();
6811        }
6812    }
6813
6814    @Override
6815    public String getPackageForToken(IBinder token) {
6816        synchronized(this) {
6817            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6818            if (r == null) {
6819                return null;
6820            }
6821            return r.packageName;
6822        }
6823    }
6824
6825    @Override
6826    public boolean isRootVoiceInteraction(IBinder token) {
6827        synchronized(this) {
6828            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6829            if (r == null) {
6830                return false;
6831            }
6832            return r.rootVoiceInteraction;
6833        }
6834    }
6835
6836    @Override
6837    public IIntentSender getIntentSender(int type,
6838            String packageName, IBinder token, String resultWho,
6839            int requestCode, Intent[] intents, String[] resolvedTypes,
6840            int flags, Bundle bOptions, int userId) {
6841        enforceNotIsolatedCaller("getIntentSender");
6842        // Refuse possible leaked file descriptors
6843        if (intents != null) {
6844            if (intents.length < 1) {
6845                throw new IllegalArgumentException("Intents array length must be >= 1");
6846            }
6847            for (int i=0; i<intents.length; i++) {
6848                Intent intent = intents[i];
6849                if (intent != null) {
6850                    if (intent.hasFileDescriptors()) {
6851                        throw new IllegalArgumentException("File descriptors passed in Intent");
6852                    }
6853                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6854                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6855                        throw new IllegalArgumentException(
6856                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6857                    }
6858                    intents[i] = new Intent(intent);
6859                }
6860            }
6861            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6862                throw new IllegalArgumentException(
6863                        "Intent array length does not match resolvedTypes length");
6864            }
6865        }
6866        if (bOptions != null) {
6867            if (bOptions.hasFileDescriptors()) {
6868                throw new IllegalArgumentException("File descriptors passed in options");
6869            }
6870        }
6871
6872        synchronized(this) {
6873            int callingUid = Binder.getCallingUid();
6874            int origUserId = userId;
6875            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6876                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6877                    ALLOW_NON_FULL, "getIntentSender", null);
6878            if (origUserId == UserHandle.USER_CURRENT) {
6879                // We don't want to evaluate this until the pending intent is
6880                // actually executed.  However, we do want to always do the
6881                // security checking for it above.
6882                userId = UserHandle.USER_CURRENT;
6883            }
6884            try {
6885                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6886                    int uid = AppGlobals.getPackageManager()
6887                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6888                    if (!UserHandle.isSameApp(callingUid, uid)) {
6889                        String msg = "Permission Denial: getIntentSender() from pid="
6890                            + Binder.getCallingPid()
6891                            + ", uid=" + Binder.getCallingUid()
6892                            + ", (need uid=" + uid + ")"
6893                            + " is not allowed to send as package " + packageName;
6894                        Slog.w(TAG, msg);
6895                        throw new SecurityException(msg);
6896                    }
6897                }
6898
6899                return getIntentSenderLocked(type, packageName, callingUid, userId,
6900                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6901
6902            } catch (RemoteException e) {
6903                throw new SecurityException(e);
6904            }
6905        }
6906    }
6907
6908    IIntentSender getIntentSenderLocked(int type, String packageName,
6909            int callingUid, int userId, IBinder token, String resultWho,
6910            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6911            Bundle bOptions) {
6912        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6913        ActivityRecord activity = null;
6914        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6915            activity = ActivityRecord.isInStackLocked(token);
6916            if (activity == null) {
6917                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6918                return null;
6919            }
6920            if (activity.finishing) {
6921                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6922                return null;
6923            }
6924        }
6925
6926        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6927        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6928        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6929        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6930                |PendingIntent.FLAG_UPDATE_CURRENT);
6931
6932        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6933                type, packageName, activity, resultWho,
6934                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6935        WeakReference<PendingIntentRecord> ref;
6936        ref = mIntentSenderRecords.get(key);
6937        PendingIntentRecord rec = ref != null ? ref.get() : null;
6938        if (rec != null) {
6939            if (!cancelCurrent) {
6940                if (updateCurrent) {
6941                    if (rec.key.requestIntent != null) {
6942                        rec.key.requestIntent.replaceExtras(intents != null ?
6943                                intents[intents.length - 1] : null);
6944                    }
6945                    if (intents != null) {
6946                        intents[intents.length-1] = rec.key.requestIntent;
6947                        rec.key.allIntents = intents;
6948                        rec.key.allResolvedTypes = resolvedTypes;
6949                    } else {
6950                        rec.key.allIntents = null;
6951                        rec.key.allResolvedTypes = null;
6952                    }
6953                }
6954                return rec;
6955            }
6956            rec.canceled = true;
6957            mIntentSenderRecords.remove(key);
6958        }
6959        if (noCreate) {
6960            return rec;
6961        }
6962        rec = new PendingIntentRecord(this, key, callingUid);
6963        mIntentSenderRecords.put(key, rec.ref);
6964        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6965            if (activity.pendingResults == null) {
6966                activity.pendingResults
6967                        = new HashSet<WeakReference<PendingIntentRecord>>();
6968            }
6969            activity.pendingResults.add(rec.ref);
6970        }
6971        return rec;
6972    }
6973
6974    @Override
6975    public void cancelIntentSender(IIntentSender sender) {
6976        if (!(sender instanceof PendingIntentRecord)) {
6977            return;
6978        }
6979        synchronized(this) {
6980            PendingIntentRecord rec = (PendingIntentRecord)sender;
6981            try {
6982                int uid = AppGlobals.getPackageManager()
6983                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6984                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6985                    String msg = "Permission Denial: cancelIntentSender() from pid="
6986                        + Binder.getCallingPid()
6987                        + ", uid=" + Binder.getCallingUid()
6988                        + " is not allowed to cancel packges "
6989                        + rec.key.packageName;
6990                    Slog.w(TAG, msg);
6991                    throw new SecurityException(msg);
6992                }
6993            } catch (RemoteException e) {
6994                throw new SecurityException(e);
6995            }
6996            cancelIntentSenderLocked(rec, true);
6997        }
6998    }
6999
7000    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7001        rec.canceled = true;
7002        mIntentSenderRecords.remove(rec.key);
7003        if (cleanActivity && rec.key.activity != null) {
7004            rec.key.activity.pendingResults.remove(rec.ref);
7005        }
7006    }
7007
7008    @Override
7009    public String getPackageForIntentSender(IIntentSender pendingResult) {
7010        if (!(pendingResult instanceof PendingIntentRecord)) {
7011            return null;
7012        }
7013        try {
7014            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7015            return res.key.packageName;
7016        } catch (ClassCastException e) {
7017        }
7018        return null;
7019    }
7020
7021    @Override
7022    public int getUidForIntentSender(IIntentSender sender) {
7023        if (sender instanceof PendingIntentRecord) {
7024            try {
7025                PendingIntentRecord res = (PendingIntentRecord)sender;
7026                return res.uid;
7027            } catch (ClassCastException e) {
7028            }
7029        }
7030        return -1;
7031    }
7032
7033    @Override
7034    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7035        if (!(pendingResult instanceof PendingIntentRecord)) {
7036            return false;
7037        }
7038        try {
7039            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7040            if (res.key.allIntents == null) {
7041                return false;
7042            }
7043            for (int i=0; i<res.key.allIntents.length; i++) {
7044                Intent intent = res.key.allIntents[i];
7045                if (intent.getPackage() != null && intent.getComponent() != null) {
7046                    return false;
7047                }
7048            }
7049            return true;
7050        } catch (ClassCastException e) {
7051        }
7052        return false;
7053    }
7054
7055    @Override
7056    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7057        if (!(pendingResult instanceof PendingIntentRecord)) {
7058            return false;
7059        }
7060        try {
7061            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7062            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7063                return true;
7064            }
7065            return false;
7066        } catch (ClassCastException e) {
7067        }
7068        return false;
7069    }
7070
7071    @Override
7072    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7073        if (!(pendingResult instanceof PendingIntentRecord)) {
7074            return null;
7075        }
7076        try {
7077            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7078            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7079        } catch (ClassCastException e) {
7080        }
7081        return null;
7082    }
7083
7084    @Override
7085    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7086        if (!(pendingResult instanceof PendingIntentRecord)) {
7087            return null;
7088        }
7089        try {
7090            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7091            synchronized (this) {
7092                return getTagForIntentSenderLocked(res, prefix);
7093            }
7094        } catch (ClassCastException e) {
7095        }
7096        return null;
7097    }
7098
7099    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7100        final Intent intent = res.key.requestIntent;
7101        if (intent != null) {
7102            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7103                    || res.lastTagPrefix.equals(prefix))) {
7104                return res.lastTag;
7105            }
7106            res.lastTagPrefix = prefix;
7107            final StringBuilder sb = new StringBuilder(128);
7108            if (prefix != null) {
7109                sb.append(prefix);
7110            }
7111            if (intent.getAction() != null) {
7112                sb.append(intent.getAction());
7113            } else if (intent.getComponent() != null) {
7114                intent.getComponent().appendShortString(sb);
7115            } else {
7116                sb.append("?");
7117            }
7118            return res.lastTag = sb.toString();
7119        }
7120        return null;
7121    }
7122
7123    @Override
7124    public void setProcessLimit(int max) {
7125        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7126                "setProcessLimit()");
7127        synchronized (this) {
7128            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7129            mProcessLimitOverride = max;
7130        }
7131        trimApplications();
7132    }
7133
7134    @Override
7135    public int getProcessLimit() {
7136        synchronized (this) {
7137            return mProcessLimitOverride;
7138        }
7139    }
7140
7141    void foregroundTokenDied(ForegroundToken token) {
7142        synchronized (ActivityManagerService.this) {
7143            synchronized (mPidsSelfLocked) {
7144                ForegroundToken cur
7145                    = mForegroundProcesses.get(token.pid);
7146                if (cur != token) {
7147                    return;
7148                }
7149                mForegroundProcesses.remove(token.pid);
7150                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7151                if (pr == null) {
7152                    return;
7153                }
7154                pr.forcingToForeground = null;
7155                updateProcessForegroundLocked(pr, false, false);
7156            }
7157            updateOomAdjLocked();
7158        }
7159    }
7160
7161    @Override
7162    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7163        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7164                "setProcessForeground()");
7165        synchronized(this) {
7166            boolean changed = false;
7167
7168            synchronized (mPidsSelfLocked) {
7169                ProcessRecord pr = mPidsSelfLocked.get(pid);
7170                if (pr == null && isForeground) {
7171                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7172                    return;
7173                }
7174                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7175                if (oldToken != null) {
7176                    oldToken.token.unlinkToDeath(oldToken, 0);
7177                    mForegroundProcesses.remove(pid);
7178                    if (pr != null) {
7179                        pr.forcingToForeground = null;
7180                    }
7181                    changed = true;
7182                }
7183                if (isForeground && token != null) {
7184                    ForegroundToken newToken = new ForegroundToken() {
7185                        @Override
7186                        public void binderDied() {
7187                            foregroundTokenDied(this);
7188                        }
7189                    };
7190                    newToken.pid = pid;
7191                    newToken.token = token;
7192                    try {
7193                        token.linkToDeath(newToken, 0);
7194                        mForegroundProcesses.put(pid, newToken);
7195                        pr.forcingToForeground = token;
7196                        changed = true;
7197                    } catch (RemoteException e) {
7198                        // If the process died while doing this, we will later
7199                        // do the cleanup with the process death link.
7200                    }
7201                }
7202            }
7203
7204            if (changed) {
7205                updateOomAdjLocked();
7206            }
7207        }
7208    }
7209
7210    @Override
7211    public boolean inMultiWindowMode(IBinder token) {
7212        final long origId = Binder.clearCallingIdentity();
7213        try {
7214            synchronized(this) {
7215                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7216                if (r == null) {
7217                    return false;
7218                }
7219                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7220                return !r.task.mFullscreen;
7221            }
7222        } finally {
7223            Binder.restoreCallingIdentity(origId);
7224        }
7225    }
7226
7227    @Override
7228    public boolean inPictureInPictureMode(IBinder token) {
7229        final long origId = Binder.clearCallingIdentity();
7230        try {
7231            synchronized(this) {
7232                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7233                if (stack == null) {
7234                    return false;
7235                }
7236                return stack.mStackId == PINNED_STACK_ID;
7237            }
7238        } finally {
7239            Binder.restoreCallingIdentity(origId);
7240        }
7241    }
7242
7243    @Override
7244    public void enterPictureInPictureMode(IBinder token) {
7245        final long origId = Binder.clearCallingIdentity();
7246        try {
7247            synchronized(this) {
7248                if (!mSupportsPictureInPicture) {
7249                    throw new IllegalStateException("enterPictureInPictureMode: "
7250                            + "Device doesn't support picture-in-picture mode.");
7251                }
7252
7253                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7254
7255                if (r == null) {
7256                    throw new IllegalStateException("enterPictureInPictureMode: "
7257                            + "Can't find activity for token=" + token);
7258                }
7259
7260                if (!r.info.supportsPip) {
7261                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7262                            + "Picture-In-Picture not supported for r=" + r);
7263                }
7264
7265                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7266                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7267                        ? mDefaultPinnedStackBounds : null;
7268
7269                mStackSupervisor.moveActivityToStackLocked(
7270                        r, PINNED_STACK_ID, "enterPictureInPictureMode", bounds);
7271            }
7272        } finally {
7273            Binder.restoreCallingIdentity(origId);
7274        }
7275    }
7276
7277    // =========================================================
7278    // PROCESS INFO
7279    // =========================================================
7280
7281    static class ProcessInfoService extends IProcessInfoService.Stub {
7282        final ActivityManagerService mActivityManagerService;
7283        ProcessInfoService(ActivityManagerService activityManagerService) {
7284            mActivityManagerService = activityManagerService;
7285        }
7286
7287        @Override
7288        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7289            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7290                    /*in*/ pids, /*out*/ states, null);
7291        }
7292
7293        @Override
7294        public void getProcessStatesAndOomScoresFromPids(
7295                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7296            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7297                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7298        }
7299    }
7300
7301    /**
7302     * For each PID in the given input array, write the current process state
7303     * for that process into the states array, or -1 to indicate that no
7304     * process with the given PID exists. If scores array is provided, write
7305     * the oom score for the process into the scores array, with INVALID_ADJ
7306     * indicating the PID doesn't exist.
7307     */
7308    public void getProcessStatesAndOomScoresForPIDs(
7309            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7310        if (scores != null) {
7311            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7312                    "getProcessStatesAndOomScoresForPIDs()");
7313        }
7314
7315        if (pids == null) {
7316            throw new NullPointerException("pids");
7317        } else if (states == null) {
7318            throw new NullPointerException("states");
7319        } else if (pids.length != states.length) {
7320            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7321        } else if (scores != null && pids.length != scores.length) {
7322            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7323        }
7324
7325        synchronized (mPidsSelfLocked) {
7326            for (int i = 0; i < pids.length; i++) {
7327                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7328                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7329                        pr.curProcState;
7330                if (scores != null) {
7331                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7332                }
7333            }
7334        }
7335    }
7336
7337    // =========================================================
7338    // PERMISSIONS
7339    // =========================================================
7340
7341    static class PermissionController extends IPermissionController.Stub {
7342        ActivityManagerService mActivityManagerService;
7343        PermissionController(ActivityManagerService activityManagerService) {
7344            mActivityManagerService = activityManagerService;
7345        }
7346
7347        @Override
7348        public boolean checkPermission(String permission, int pid, int uid) {
7349            return mActivityManagerService.checkPermission(permission, pid,
7350                    uid) == PackageManager.PERMISSION_GRANTED;
7351        }
7352
7353        @Override
7354        public String[] getPackagesForUid(int uid) {
7355            return mActivityManagerService.mContext.getPackageManager()
7356                    .getPackagesForUid(uid);
7357        }
7358
7359        @Override
7360        public boolean isRuntimePermission(String permission) {
7361            try {
7362                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7363                        .getPermissionInfo(permission, 0);
7364                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7365            } catch (NameNotFoundException nnfe) {
7366                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7367            }
7368            return false;
7369        }
7370    }
7371
7372    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7373        @Override
7374        public int checkComponentPermission(String permission, int pid, int uid,
7375                int owningUid, boolean exported) {
7376            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7377                    owningUid, exported);
7378        }
7379
7380        @Override
7381        public Object getAMSLock() {
7382            return ActivityManagerService.this;
7383        }
7384    }
7385
7386    /**
7387     * This can be called with or without the global lock held.
7388     */
7389    int checkComponentPermission(String permission, int pid, int uid,
7390            int owningUid, boolean exported) {
7391        if (pid == MY_PID) {
7392            return PackageManager.PERMISSION_GRANTED;
7393        }
7394        return ActivityManager.checkComponentPermission(permission, uid,
7395                owningUid, exported);
7396    }
7397
7398    /**
7399     * As the only public entry point for permissions checking, this method
7400     * can enforce the semantic that requesting a check on a null global
7401     * permission is automatically denied.  (Internally a null permission
7402     * string is used when calling {@link #checkComponentPermission} in cases
7403     * when only uid-based security is needed.)
7404     *
7405     * This can be called with or without the global lock held.
7406     */
7407    @Override
7408    public int checkPermission(String permission, int pid, int uid) {
7409        if (permission == null) {
7410            return PackageManager.PERMISSION_DENIED;
7411        }
7412        return checkComponentPermission(permission, pid, uid, -1, true);
7413    }
7414
7415    @Override
7416    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7417        if (permission == null) {
7418            return PackageManager.PERMISSION_DENIED;
7419        }
7420
7421        // We might be performing an operation on behalf of an indirect binder
7422        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7423        // client identity accordingly before proceeding.
7424        Identity tlsIdentity = sCallerIdentity.get();
7425        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7426            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7427                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7428            uid = tlsIdentity.uid;
7429            pid = tlsIdentity.pid;
7430        }
7431
7432        return checkComponentPermission(permission, pid, uid, -1, true);
7433    }
7434
7435    /**
7436     * Binder IPC calls go through the public entry point.
7437     * This can be called with or without the global lock held.
7438     */
7439    int checkCallingPermission(String permission) {
7440        return checkPermission(permission,
7441                Binder.getCallingPid(),
7442                UserHandle.getAppId(Binder.getCallingUid()));
7443    }
7444
7445    /**
7446     * This can be called with or without the global lock held.
7447     */
7448    void enforceCallingPermission(String permission, String func) {
7449        if (checkCallingPermission(permission)
7450                == PackageManager.PERMISSION_GRANTED) {
7451            return;
7452        }
7453
7454        String msg = "Permission Denial: " + func + " from pid="
7455                + Binder.getCallingPid()
7456                + ", uid=" + Binder.getCallingUid()
7457                + " requires " + permission;
7458        Slog.w(TAG, msg);
7459        throw new SecurityException(msg);
7460    }
7461
7462    /**
7463     * Determine if UID is holding permissions required to access {@link Uri} in
7464     * the given {@link ProviderInfo}. Final permission checking is always done
7465     * in {@link ContentProvider}.
7466     */
7467    private final boolean checkHoldingPermissionsLocked(
7468            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7469        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7470                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7471        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7472            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7473                    != PERMISSION_GRANTED) {
7474                return false;
7475            }
7476        }
7477        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7478    }
7479
7480    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7481            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7482        if (pi.applicationInfo.uid == uid) {
7483            return true;
7484        } else if (!pi.exported) {
7485            return false;
7486        }
7487
7488        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7489        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7490        try {
7491            // check if target holds top-level <provider> permissions
7492            if (!readMet && pi.readPermission != null && considerUidPermissions
7493                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7494                readMet = true;
7495            }
7496            if (!writeMet && pi.writePermission != null && considerUidPermissions
7497                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7498                writeMet = true;
7499            }
7500
7501            // track if unprotected read/write is allowed; any denied
7502            // <path-permission> below removes this ability
7503            boolean allowDefaultRead = pi.readPermission == null;
7504            boolean allowDefaultWrite = pi.writePermission == null;
7505
7506            // check if target holds any <path-permission> that match uri
7507            final PathPermission[] pps = pi.pathPermissions;
7508            if (pps != null) {
7509                final String path = grantUri.uri.getPath();
7510                int i = pps.length;
7511                while (i > 0 && (!readMet || !writeMet)) {
7512                    i--;
7513                    PathPermission pp = pps[i];
7514                    if (pp.match(path)) {
7515                        if (!readMet) {
7516                            final String pprperm = pp.getReadPermission();
7517                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7518                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7519                                    + ": match=" + pp.match(path)
7520                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7521                            if (pprperm != null) {
7522                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7523                                        == PERMISSION_GRANTED) {
7524                                    readMet = true;
7525                                } else {
7526                                    allowDefaultRead = false;
7527                                }
7528                            }
7529                        }
7530                        if (!writeMet) {
7531                            final String ppwperm = pp.getWritePermission();
7532                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7533                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7534                                    + ": match=" + pp.match(path)
7535                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7536                            if (ppwperm != null) {
7537                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7538                                        == PERMISSION_GRANTED) {
7539                                    writeMet = true;
7540                                } else {
7541                                    allowDefaultWrite = false;
7542                                }
7543                            }
7544                        }
7545                    }
7546                }
7547            }
7548
7549            // grant unprotected <provider> read/write, if not blocked by
7550            // <path-permission> above
7551            if (allowDefaultRead) readMet = true;
7552            if (allowDefaultWrite) writeMet = true;
7553
7554        } catch (RemoteException e) {
7555            return false;
7556        }
7557
7558        return readMet && writeMet;
7559    }
7560
7561    public int getAppStartMode(int uid, String packageName) {
7562        synchronized (this) {
7563            return checkAllowBackgroundLocked(uid, packageName, -1);
7564        }
7565    }
7566
7567    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7568        UidRecord uidRec = mActiveUids.get(uid);
7569        if (uidRec == null || uidRec.idle) {
7570            if (callingPid >= 0) {
7571                ProcessRecord proc;
7572                synchronized (mPidsSelfLocked) {
7573                    proc = mPidsSelfLocked.get(callingPid);
7574                }
7575                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7576                    // Whoever is instigating this is in the foreground, so we will allow it
7577                    // to go through.
7578                    return ActivityManager.APP_START_MODE_NORMAL;
7579                }
7580            }
7581            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7582                    != AppOpsManager.MODE_ALLOWED) {
7583                return ActivityManager.APP_START_MODE_DELAYED;
7584            }
7585        }
7586        return ActivityManager.APP_START_MODE_NORMAL;
7587    }
7588
7589    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7590        ProviderInfo pi = null;
7591        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7592        if (cpr != null) {
7593            pi = cpr.info;
7594        } else {
7595            try {
7596                pi = AppGlobals.getPackageManager().resolveContentProvider(
7597                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7598            } catch (RemoteException ex) {
7599            }
7600        }
7601        return pi;
7602    }
7603
7604    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7605        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7606        if (targetUris != null) {
7607            return targetUris.get(grantUri);
7608        }
7609        return null;
7610    }
7611
7612    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7613            String targetPkg, int targetUid, GrantUri grantUri) {
7614        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7615        if (targetUris == null) {
7616            targetUris = Maps.newArrayMap();
7617            mGrantedUriPermissions.put(targetUid, targetUris);
7618        }
7619
7620        UriPermission perm = targetUris.get(grantUri);
7621        if (perm == null) {
7622            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7623            targetUris.put(grantUri, perm);
7624        }
7625
7626        return perm;
7627    }
7628
7629    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7630            final int modeFlags) {
7631        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7632        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7633                : UriPermission.STRENGTH_OWNED;
7634
7635        // Root gets to do everything.
7636        if (uid == 0) {
7637            return true;
7638        }
7639
7640        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7641        if (perms == null) return false;
7642
7643        // First look for exact match
7644        final UriPermission exactPerm = perms.get(grantUri);
7645        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7646            return true;
7647        }
7648
7649        // No exact match, look for prefixes
7650        final int N = perms.size();
7651        for (int i = 0; i < N; i++) {
7652            final UriPermission perm = perms.valueAt(i);
7653            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7654                    && perm.getStrength(modeFlags) >= minStrength) {
7655                return true;
7656            }
7657        }
7658
7659        return false;
7660    }
7661
7662    /**
7663     * @param uri This uri must NOT contain an embedded userId.
7664     * @param userId The userId in which the uri is to be resolved.
7665     */
7666    @Override
7667    public int checkUriPermission(Uri uri, int pid, int uid,
7668            final int modeFlags, int userId, IBinder callerToken) {
7669        enforceNotIsolatedCaller("checkUriPermission");
7670
7671        // Another redirected-binder-call permissions check as in
7672        // {@link checkPermissionWithToken}.
7673        Identity tlsIdentity = sCallerIdentity.get();
7674        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7675            uid = tlsIdentity.uid;
7676            pid = tlsIdentity.pid;
7677        }
7678
7679        // Our own process gets to do everything.
7680        if (pid == MY_PID) {
7681            return PackageManager.PERMISSION_GRANTED;
7682        }
7683        synchronized (this) {
7684            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7685                    ? PackageManager.PERMISSION_GRANTED
7686                    : PackageManager.PERMISSION_DENIED;
7687        }
7688    }
7689
7690    /**
7691     * Check if the targetPkg can be granted permission to access uri by
7692     * the callingUid using the given modeFlags.  Throws a security exception
7693     * if callingUid is not allowed to do this.  Returns the uid of the target
7694     * if the URI permission grant should be performed; returns -1 if it is not
7695     * needed (for example targetPkg already has permission to access the URI).
7696     * If you already know the uid of the target, you can supply it in
7697     * lastTargetUid else set that to -1.
7698     */
7699    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7700            final int modeFlags, int lastTargetUid) {
7701        if (!Intent.isAccessUriMode(modeFlags)) {
7702            return -1;
7703        }
7704
7705        if (targetPkg != null) {
7706            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7707                    "Checking grant " + targetPkg + " permission to " + grantUri);
7708        }
7709
7710        final IPackageManager pm = AppGlobals.getPackageManager();
7711
7712        // If this is not a content: uri, we can't do anything with it.
7713        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7714            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7715                    "Can't grant URI permission for non-content URI: " + grantUri);
7716            return -1;
7717        }
7718
7719        final String authority = grantUri.uri.getAuthority();
7720        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7721        if (pi == null) {
7722            Slog.w(TAG, "No content provider found for permission check: " +
7723                    grantUri.uri.toSafeString());
7724            return -1;
7725        }
7726
7727        int targetUid = lastTargetUid;
7728        if (targetUid < 0 && targetPkg != null) {
7729            try {
7730                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7731                if (targetUid < 0) {
7732                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7733                            "Can't grant URI permission no uid for: " + targetPkg);
7734                    return -1;
7735                }
7736            } catch (RemoteException ex) {
7737                return -1;
7738            }
7739        }
7740
7741        if (targetUid >= 0) {
7742            // First...  does the target actually need this permission?
7743            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7744                // No need to grant the target this permission.
7745                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7746                        "Target " + targetPkg + " already has full permission to " + grantUri);
7747                return -1;
7748            }
7749        } else {
7750            // First...  there is no target package, so can anyone access it?
7751            boolean allowed = pi.exported;
7752            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7753                if (pi.readPermission != null) {
7754                    allowed = false;
7755                }
7756            }
7757            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7758                if (pi.writePermission != null) {
7759                    allowed = false;
7760                }
7761            }
7762            if (allowed) {
7763                return -1;
7764            }
7765        }
7766
7767        /* There is a special cross user grant if:
7768         * - The target is on another user.
7769         * - Apps on the current user can access the uri without any uid permissions.
7770         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7771         * grant uri permissions.
7772         */
7773        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7774                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7775                modeFlags, false /*without considering the uid permissions*/);
7776
7777        // Second...  is the provider allowing granting of URI permissions?
7778        if (!specialCrossUserGrant) {
7779            if (!pi.grantUriPermissions) {
7780                throw new SecurityException("Provider " + pi.packageName
7781                        + "/" + pi.name
7782                        + " does not allow granting of Uri permissions (uri "
7783                        + grantUri + ")");
7784            }
7785            if (pi.uriPermissionPatterns != null) {
7786                final int N = pi.uriPermissionPatterns.length;
7787                boolean allowed = false;
7788                for (int i=0; i<N; i++) {
7789                    if (pi.uriPermissionPatterns[i] != null
7790                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7791                        allowed = true;
7792                        break;
7793                    }
7794                }
7795                if (!allowed) {
7796                    throw new SecurityException("Provider " + pi.packageName
7797                            + "/" + pi.name
7798                            + " does not allow granting of permission to path of Uri "
7799                            + grantUri);
7800                }
7801            }
7802        }
7803
7804        // Third...  does the caller itself have permission to access
7805        // this uri?
7806        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7807            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7808                // Require they hold a strong enough Uri permission
7809                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7810                    throw new SecurityException("Uid " + callingUid
7811                            + " does not have permission to uri " + grantUri);
7812                }
7813            }
7814        }
7815        return targetUid;
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param userId The userId in which the uri is to be resolved.
7821     */
7822    @Override
7823    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7824            final int modeFlags, int userId) {
7825        enforceNotIsolatedCaller("checkGrantUriPermission");
7826        synchronized(this) {
7827            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7828                    new GrantUri(userId, uri, false), modeFlags, -1);
7829        }
7830    }
7831
7832    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7833            final int modeFlags, UriPermissionOwner owner) {
7834        if (!Intent.isAccessUriMode(modeFlags)) {
7835            return;
7836        }
7837
7838        // So here we are: the caller has the assumed permission
7839        // to the uri, and the target doesn't.  Let's now give this to
7840        // the target.
7841
7842        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7843                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7844
7845        final String authority = grantUri.uri.getAuthority();
7846        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7847        if (pi == null) {
7848            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7849            return;
7850        }
7851
7852        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7853            grantUri.prefix = true;
7854        }
7855        final UriPermission perm = findOrCreateUriPermissionLocked(
7856                pi.packageName, targetPkg, targetUid, grantUri);
7857        perm.grantModes(modeFlags, owner);
7858    }
7859
7860    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7861            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7862        if (targetPkg == null) {
7863            throw new NullPointerException("targetPkg");
7864        }
7865        int targetUid;
7866        final IPackageManager pm = AppGlobals.getPackageManager();
7867        try {
7868            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7869        } catch (RemoteException ex) {
7870            return;
7871        }
7872
7873        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7874                targetUid);
7875        if (targetUid < 0) {
7876            return;
7877        }
7878
7879        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7880                owner);
7881    }
7882
7883    static class NeededUriGrants extends ArrayList<GrantUri> {
7884        final String targetPkg;
7885        final int targetUid;
7886        final int flags;
7887
7888        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7889            this.targetPkg = targetPkg;
7890            this.targetUid = targetUid;
7891            this.flags = flags;
7892        }
7893    }
7894
7895    /**
7896     * Like checkGrantUriPermissionLocked, but takes an Intent.
7897     */
7898    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7899            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7900        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7901                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7902                + " clip=" + (intent != null ? intent.getClipData() : null)
7903                + " from " + intent + "; flags=0x"
7904                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7905
7906        if (targetPkg == null) {
7907            throw new NullPointerException("targetPkg");
7908        }
7909
7910        if (intent == null) {
7911            return null;
7912        }
7913        Uri data = intent.getData();
7914        ClipData clip = intent.getClipData();
7915        if (data == null && clip == null) {
7916            return null;
7917        }
7918        // Default userId for uris in the intent (if they don't specify it themselves)
7919        int contentUserHint = intent.getContentUserHint();
7920        if (contentUserHint == UserHandle.USER_CURRENT) {
7921            contentUserHint = UserHandle.getUserId(callingUid);
7922        }
7923        final IPackageManager pm = AppGlobals.getPackageManager();
7924        int targetUid;
7925        if (needed != null) {
7926            targetUid = needed.targetUid;
7927        } else {
7928            try {
7929                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7930            } catch (RemoteException ex) {
7931                return null;
7932            }
7933            if (targetUid < 0) {
7934                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7935                        "Can't grant URI permission no uid for: " + targetPkg
7936                        + " on user " + targetUserId);
7937                return null;
7938            }
7939        }
7940        if (data != null) {
7941            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7942            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7943                    targetUid);
7944            if (targetUid > 0) {
7945                if (needed == null) {
7946                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7947                }
7948                needed.add(grantUri);
7949            }
7950        }
7951        if (clip != null) {
7952            for (int i=0; i<clip.getItemCount(); i++) {
7953                Uri uri = clip.getItemAt(i).getUri();
7954                if (uri != null) {
7955                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7956                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7957                            targetUid);
7958                    if (targetUid > 0) {
7959                        if (needed == null) {
7960                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7961                        }
7962                        needed.add(grantUri);
7963                    }
7964                } else {
7965                    Intent clipIntent = clip.getItemAt(i).getIntent();
7966                    if (clipIntent != null) {
7967                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7968                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7969                        if (newNeeded != null) {
7970                            needed = newNeeded;
7971                        }
7972                    }
7973                }
7974            }
7975        }
7976
7977        return needed;
7978    }
7979
7980    /**
7981     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7982     */
7983    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7984            UriPermissionOwner owner) {
7985        if (needed != null) {
7986            for (int i=0; i<needed.size(); i++) {
7987                GrantUri grantUri = needed.get(i);
7988                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7989                        grantUri, needed.flags, owner);
7990            }
7991        }
7992    }
7993
7994    void grantUriPermissionFromIntentLocked(int callingUid,
7995            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7996        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7997                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7998        if (needed == null) {
7999            return;
8000        }
8001
8002        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8003    }
8004
8005    /**
8006     * @param uri This uri must NOT contain an embedded userId.
8007     * @param userId The userId in which the uri is to be resolved.
8008     */
8009    @Override
8010    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8011            final int modeFlags, int userId) {
8012        enforceNotIsolatedCaller("grantUriPermission");
8013        GrantUri grantUri = new GrantUri(userId, uri, false);
8014        synchronized(this) {
8015            final ProcessRecord r = getRecordForAppLocked(caller);
8016            if (r == null) {
8017                throw new SecurityException("Unable to find app for caller "
8018                        + caller
8019                        + " when granting permission to uri " + grantUri);
8020            }
8021            if (targetPkg == null) {
8022                throw new IllegalArgumentException("null target");
8023            }
8024            if (grantUri == null) {
8025                throw new IllegalArgumentException("null uri");
8026            }
8027
8028            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8029                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8030                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8031                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8032
8033            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8034                    UserHandle.getUserId(r.uid));
8035        }
8036    }
8037
8038    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8039        if (perm.modeFlags == 0) {
8040            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8041                    perm.targetUid);
8042            if (perms != null) {
8043                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8044                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8045
8046                perms.remove(perm.uri);
8047                if (perms.isEmpty()) {
8048                    mGrantedUriPermissions.remove(perm.targetUid);
8049                }
8050            }
8051        }
8052    }
8053
8054    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8055        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8056                "Revoking all granted permissions to " + grantUri);
8057
8058        final IPackageManager pm = AppGlobals.getPackageManager();
8059        final String authority = grantUri.uri.getAuthority();
8060        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8061        if (pi == null) {
8062            Slog.w(TAG, "No content provider found for permission revoke: "
8063                    + grantUri.toSafeString());
8064            return;
8065        }
8066
8067        // Does the caller have this permission on the URI?
8068        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8069            // If they don't have direct access to the URI, then revoke any
8070            // ownerless URI permissions that have been granted to them.
8071            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8072            if (perms != null) {
8073                boolean persistChanged = false;
8074                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8075                    final UriPermission perm = it.next();
8076                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8077                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8078                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                                "Revoking non-owned " + perm.targetUid
8080                                + " permission to " + perm.uri);
8081                        persistChanged |= perm.revokeModes(
8082                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8083                        if (perm.modeFlags == 0) {
8084                            it.remove();
8085                        }
8086                    }
8087                }
8088                if (perms.isEmpty()) {
8089                    mGrantedUriPermissions.remove(callingUid);
8090                }
8091                if (persistChanged) {
8092                    schedulePersistUriGrants();
8093                }
8094            }
8095            return;
8096        }
8097
8098        boolean persistChanged = false;
8099
8100        // Go through all of the permissions and remove any that match.
8101        int N = mGrantedUriPermissions.size();
8102        for (int i = 0; i < N; i++) {
8103            final int targetUid = mGrantedUriPermissions.keyAt(i);
8104            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8105
8106            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8107                final UriPermission perm = it.next();
8108                if (perm.uri.sourceUserId == grantUri.sourceUserId
8109                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8110                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8111                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8112                    persistChanged |= perm.revokeModes(
8113                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8114                    if (perm.modeFlags == 0) {
8115                        it.remove();
8116                    }
8117                }
8118            }
8119
8120            if (perms.isEmpty()) {
8121                mGrantedUriPermissions.remove(targetUid);
8122                N--;
8123                i--;
8124            }
8125        }
8126
8127        if (persistChanged) {
8128            schedulePersistUriGrants();
8129        }
8130    }
8131
8132    /**
8133     * @param uri This uri must NOT contain an embedded userId.
8134     * @param userId The userId in which the uri is to be resolved.
8135     */
8136    @Override
8137    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8138            int userId) {
8139        enforceNotIsolatedCaller("revokeUriPermission");
8140        synchronized(this) {
8141            final ProcessRecord r = getRecordForAppLocked(caller);
8142            if (r == null) {
8143                throw new SecurityException("Unable to find app for caller "
8144                        + caller
8145                        + " when revoking permission to uri " + uri);
8146            }
8147            if (uri == null) {
8148                Slog.w(TAG, "revokeUriPermission: null uri");
8149                return;
8150            }
8151
8152            if (!Intent.isAccessUriMode(modeFlags)) {
8153                return;
8154            }
8155
8156            final String authority = uri.getAuthority();
8157            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8158            if (pi == null) {
8159                Slog.w(TAG, "No content provider found for permission revoke: "
8160                        + uri.toSafeString());
8161                return;
8162            }
8163
8164            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8165        }
8166    }
8167
8168    /**
8169     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8170     * given package.
8171     *
8172     * @param packageName Package name to match, or {@code null} to apply to all
8173     *            packages.
8174     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8175     *            to all users.
8176     * @param persistable If persistable grants should be removed.
8177     */
8178    private void removeUriPermissionsForPackageLocked(
8179            String packageName, int userHandle, boolean persistable) {
8180        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8181            throw new IllegalArgumentException("Must narrow by either package or user");
8182        }
8183
8184        boolean persistChanged = false;
8185
8186        int N = mGrantedUriPermissions.size();
8187        for (int i = 0; i < N; i++) {
8188            final int targetUid = mGrantedUriPermissions.keyAt(i);
8189            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8190
8191            // Only inspect grants matching user
8192            if (userHandle == UserHandle.USER_ALL
8193                    || userHandle == UserHandle.getUserId(targetUid)) {
8194                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8195                    final UriPermission perm = it.next();
8196
8197                    // Only inspect grants matching package
8198                    if (packageName == null || perm.sourcePkg.equals(packageName)
8199                            || perm.targetPkg.equals(packageName)) {
8200                        persistChanged |= perm.revokeModes(persistable
8201                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8202
8203                        // Only remove when no modes remain; any persisted grants
8204                        // will keep this alive.
8205                        if (perm.modeFlags == 0) {
8206                            it.remove();
8207                        }
8208                    }
8209                }
8210
8211                if (perms.isEmpty()) {
8212                    mGrantedUriPermissions.remove(targetUid);
8213                    N--;
8214                    i--;
8215                }
8216            }
8217        }
8218
8219        if (persistChanged) {
8220            schedulePersistUriGrants();
8221        }
8222    }
8223
8224    @Override
8225    public IBinder newUriPermissionOwner(String name) {
8226        enforceNotIsolatedCaller("newUriPermissionOwner");
8227        synchronized(this) {
8228            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8229            return owner.getExternalTokenLocked();
8230        }
8231    }
8232
8233    /**
8234     * @param uri This uri must NOT contain an embedded userId.
8235     * @param sourceUserId The userId in which the uri is to be resolved.
8236     * @param targetUserId The userId of the app that receives the grant.
8237     */
8238    @Override
8239    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8240            final int modeFlags, int sourceUserId, int targetUserId) {
8241        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8242                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8243                "grantUriPermissionFromOwner", null);
8244        synchronized(this) {
8245            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8246            if (owner == null) {
8247                throw new IllegalArgumentException("Unknown owner: " + token);
8248            }
8249            if (fromUid != Binder.getCallingUid()) {
8250                if (Binder.getCallingUid() != Process.myUid()) {
8251                    // Only system code can grant URI permissions on behalf
8252                    // of other users.
8253                    throw new SecurityException("nice try");
8254                }
8255            }
8256            if (targetPkg == null) {
8257                throw new IllegalArgumentException("null target");
8258            }
8259            if (uri == null) {
8260                throw new IllegalArgumentException("null uri");
8261            }
8262
8263            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8264                    modeFlags, owner, targetUserId);
8265        }
8266    }
8267
8268    /**
8269     * @param uri This uri must NOT contain an embedded userId.
8270     * @param userId The userId in which the uri is to be resolved.
8271     */
8272    @Override
8273    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8274        synchronized(this) {
8275            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8276            if (owner == null) {
8277                throw new IllegalArgumentException("Unknown owner: " + token);
8278            }
8279
8280            if (uri == null) {
8281                owner.removeUriPermissionsLocked(mode);
8282            } else {
8283                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8284            }
8285        }
8286    }
8287
8288    private void schedulePersistUriGrants() {
8289        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8290            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8291                    10 * DateUtils.SECOND_IN_MILLIS);
8292        }
8293    }
8294
8295    private void writeGrantedUriPermissions() {
8296        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8297
8298        // Snapshot permissions so we can persist without lock
8299        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8300        synchronized (this) {
8301            final int size = mGrantedUriPermissions.size();
8302            for (int i = 0; i < size; i++) {
8303                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8304                for (UriPermission perm : perms.values()) {
8305                    if (perm.persistedModeFlags != 0) {
8306                        persist.add(perm.snapshot());
8307                    }
8308                }
8309            }
8310        }
8311
8312        FileOutputStream fos = null;
8313        try {
8314            fos = mGrantFile.startWrite();
8315
8316            XmlSerializer out = new FastXmlSerializer();
8317            out.setOutput(fos, StandardCharsets.UTF_8.name());
8318            out.startDocument(null, true);
8319            out.startTag(null, TAG_URI_GRANTS);
8320            for (UriPermission.Snapshot perm : persist) {
8321                out.startTag(null, TAG_URI_GRANT);
8322                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8323                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8324                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8325                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8326                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8327                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8328                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8329                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8330                out.endTag(null, TAG_URI_GRANT);
8331            }
8332            out.endTag(null, TAG_URI_GRANTS);
8333            out.endDocument();
8334
8335            mGrantFile.finishWrite(fos);
8336        } catch (IOException e) {
8337            if (fos != null) {
8338                mGrantFile.failWrite(fos);
8339            }
8340        }
8341    }
8342
8343    private void readGrantedUriPermissionsLocked() {
8344        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8345
8346        final long now = System.currentTimeMillis();
8347
8348        FileInputStream fis = null;
8349        try {
8350            fis = mGrantFile.openRead();
8351            final XmlPullParser in = Xml.newPullParser();
8352            in.setInput(fis, StandardCharsets.UTF_8.name());
8353
8354            int type;
8355            while ((type = in.next()) != END_DOCUMENT) {
8356                final String tag = in.getName();
8357                if (type == START_TAG) {
8358                    if (TAG_URI_GRANT.equals(tag)) {
8359                        final int sourceUserId;
8360                        final int targetUserId;
8361                        final int userHandle = readIntAttribute(in,
8362                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8363                        if (userHandle != UserHandle.USER_NULL) {
8364                            // For backwards compatibility.
8365                            sourceUserId = userHandle;
8366                            targetUserId = userHandle;
8367                        } else {
8368                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8369                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8370                        }
8371                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8372                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8373                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8374                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8375                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8376                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8377
8378                        // Sanity check that provider still belongs to source package
8379                        final ProviderInfo pi = getProviderInfoLocked(
8380                                uri.getAuthority(), sourceUserId);
8381                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8382                            int targetUid = -1;
8383                            try {
8384                                targetUid = AppGlobals.getPackageManager()
8385                                        .getPackageUid(targetPkg, targetUserId);
8386                            } catch (RemoteException e) {
8387                            }
8388                            if (targetUid != -1) {
8389                                final UriPermission perm = findOrCreateUriPermissionLocked(
8390                                        sourcePkg, targetPkg, targetUid,
8391                                        new GrantUri(sourceUserId, uri, prefix));
8392                                perm.initPersistedModes(modeFlags, createdTime);
8393                            }
8394                        } else {
8395                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8396                                    + " but instead found " + pi);
8397                        }
8398                    }
8399                }
8400            }
8401        } catch (FileNotFoundException e) {
8402            // Missing grants is okay
8403        } catch (IOException e) {
8404            Slog.wtf(TAG, "Failed reading Uri grants", e);
8405        } catch (XmlPullParserException e) {
8406            Slog.wtf(TAG, "Failed reading Uri grants", e);
8407        } finally {
8408            IoUtils.closeQuietly(fis);
8409        }
8410    }
8411
8412    /**
8413     * @param uri This uri must NOT contain an embedded userId.
8414     * @param userId The userId in which the uri is to be resolved.
8415     */
8416    @Override
8417    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8418        enforceNotIsolatedCaller("takePersistableUriPermission");
8419
8420        Preconditions.checkFlagsArgument(modeFlags,
8421                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8422
8423        synchronized (this) {
8424            final int callingUid = Binder.getCallingUid();
8425            boolean persistChanged = false;
8426            GrantUri grantUri = new GrantUri(userId, uri, false);
8427
8428            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8429                    new GrantUri(userId, uri, false));
8430            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8431                    new GrantUri(userId, uri, true));
8432
8433            final boolean exactValid = (exactPerm != null)
8434                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8435            final boolean prefixValid = (prefixPerm != null)
8436                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8437
8438            if (!(exactValid || prefixValid)) {
8439                throw new SecurityException("No persistable permission grants found for UID "
8440                        + callingUid + " and Uri " + grantUri.toSafeString());
8441            }
8442
8443            if (exactValid) {
8444                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8445            }
8446            if (prefixValid) {
8447                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8448            }
8449
8450            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8451
8452            if (persistChanged) {
8453                schedulePersistUriGrants();
8454            }
8455        }
8456    }
8457
8458    /**
8459     * @param uri This uri must NOT contain an embedded userId.
8460     * @param userId The userId in which the uri is to be resolved.
8461     */
8462    @Override
8463    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8464        enforceNotIsolatedCaller("releasePersistableUriPermission");
8465
8466        Preconditions.checkFlagsArgument(modeFlags,
8467                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8468
8469        synchronized (this) {
8470            final int callingUid = Binder.getCallingUid();
8471            boolean persistChanged = false;
8472
8473            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8474                    new GrantUri(userId, uri, false));
8475            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8476                    new GrantUri(userId, uri, true));
8477            if (exactPerm == null && prefixPerm == null) {
8478                throw new SecurityException("No permission grants found for UID " + callingUid
8479                        + " and Uri " + uri.toSafeString());
8480            }
8481
8482            if (exactPerm != null) {
8483                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8484                removeUriPermissionIfNeededLocked(exactPerm);
8485            }
8486            if (prefixPerm != null) {
8487                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8488                removeUriPermissionIfNeededLocked(prefixPerm);
8489            }
8490
8491            if (persistChanged) {
8492                schedulePersistUriGrants();
8493            }
8494        }
8495    }
8496
8497    /**
8498     * Prune any older {@link UriPermission} for the given UID until outstanding
8499     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8500     *
8501     * @return if any mutations occured that require persisting.
8502     */
8503    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8504        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8505        if (perms == null) return false;
8506        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8507
8508        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8509        for (UriPermission perm : perms.values()) {
8510            if (perm.persistedModeFlags != 0) {
8511                persisted.add(perm);
8512            }
8513        }
8514
8515        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8516        if (trimCount <= 0) return false;
8517
8518        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8519        for (int i = 0; i < trimCount; i++) {
8520            final UriPermission perm = persisted.get(i);
8521
8522            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8523                    "Trimming grant created at " + perm.persistedCreateTime);
8524
8525            perm.releasePersistableModes(~0);
8526            removeUriPermissionIfNeededLocked(perm);
8527        }
8528
8529        return true;
8530    }
8531
8532    @Override
8533    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8534            String packageName, boolean incoming) {
8535        enforceNotIsolatedCaller("getPersistedUriPermissions");
8536        Preconditions.checkNotNull(packageName, "packageName");
8537
8538        final int callingUid = Binder.getCallingUid();
8539        final IPackageManager pm = AppGlobals.getPackageManager();
8540        try {
8541            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8542            if (packageUid != callingUid) {
8543                throw new SecurityException(
8544                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8545            }
8546        } catch (RemoteException e) {
8547            throw new SecurityException("Failed to verify package name ownership");
8548        }
8549
8550        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8551        synchronized (this) {
8552            if (incoming) {
8553                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8554                        callingUid);
8555                if (perms == null) {
8556                    Slog.w(TAG, "No permission grants found for " + packageName);
8557                } else {
8558                    for (UriPermission perm : perms.values()) {
8559                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8560                            result.add(perm.buildPersistedPublicApiObject());
8561                        }
8562                    }
8563                }
8564            } else {
8565                final int size = mGrantedUriPermissions.size();
8566                for (int i = 0; i < size; i++) {
8567                    final ArrayMap<GrantUri, UriPermission> perms =
8568                            mGrantedUriPermissions.valueAt(i);
8569                    for (UriPermission perm : perms.values()) {
8570                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8571                            result.add(perm.buildPersistedPublicApiObject());
8572                        }
8573                    }
8574                }
8575            }
8576        }
8577        return new ParceledListSlice<android.content.UriPermission>(result);
8578    }
8579
8580    @Override
8581    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8582        synchronized (this) {
8583            ProcessRecord app =
8584                who != null ? getRecordForAppLocked(who) : null;
8585            if (app == null) return;
8586
8587            Message msg = Message.obtain();
8588            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8589            msg.obj = app;
8590            msg.arg1 = waiting ? 1 : 0;
8591            mUiHandler.sendMessage(msg);
8592        }
8593    }
8594
8595    @Override
8596    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8597        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8598        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8599        outInfo.availMem = Process.getFreeMemory();
8600        outInfo.totalMem = Process.getTotalMemory();
8601        outInfo.threshold = homeAppMem;
8602        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8603        outInfo.hiddenAppThreshold = cachedAppMem;
8604        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8605                ProcessList.SERVICE_ADJ);
8606        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8607                ProcessList.VISIBLE_APP_ADJ);
8608        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8609                ProcessList.FOREGROUND_APP_ADJ);
8610    }
8611
8612    // =========================================================
8613    // TASK MANAGEMENT
8614    // =========================================================
8615
8616    @Override
8617    public List<IAppTask> getAppTasks(String callingPackage) {
8618        int callingUid = Binder.getCallingUid();
8619        long ident = Binder.clearCallingIdentity();
8620
8621        synchronized(this) {
8622            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8623            try {
8624                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8625
8626                final int N = mRecentTasks.size();
8627                for (int i = 0; i < N; i++) {
8628                    TaskRecord tr = mRecentTasks.get(i);
8629                    // Skip tasks that do not match the caller.  We don't need to verify
8630                    // callingPackage, because we are also limiting to callingUid and know
8631                    // that will limit to the correct security sandbox.
8632                    if (tr.effectiveUid != callingUid) {
8633                        continue;
8634                    }
8635                    Intent intent = tr.getBaseIntent();
8636                    if (intent == null ||
8637                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8638                        continue;
8639                    }
8640                    ActivityManager.RecentTaskInfo taskInfo =
8641                            createRecentTaskInfoFromTaskRecord(tr);
8642                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8643                    list.add(taskImpl);
8644                }
8645            } finally {
8646                Binder.restoreCallingIdentity(ident);
8647            }
8648            return list;
8649        }
8650    }
8651
8652    @Override
8653    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8654        final int callingUid = Binder.getCallingUid();
8655        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8656
8657        synchronized(this) {
8658            if (DEBUG_ALL) Slog.v(
8659                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8660
8661            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8662                    callingUid);
8663
8664            // TODO: Improve with MRU list from all ActivityStacks.
8665            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8666        }
8667
8668        return list;
8669    }
8670
8671    /**
8672     * Creates a new RecentTaskInfo from a TaskRecord.
8673     */
8674    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8675        // Update the task description to reflect any changes in the task stack
8676        tr.updateTaskDescription();
8677
8678        // Compose the recent task info
8679        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8680        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8681        rti.persistentId = tr.taskId;
8682        rti.baseIntent = new Intent(tr.getBaseIntent());
8683        rti.origActivity = tr.origActivity;
8684        rti.realActivity = tr.realActivity;
8685        rti.description = tr.lastDescription;
8686        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8687        rti.userId = tr.userId;
8688        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8689        rti.firstActiveTime = tr.firstActiveTime;
8690        rti.lastActiveTime = tr.lastActiveTime;
8691        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8692        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8693        rti.numActivities = 0;
8694        if (tr.mBounds != null) {
8695            rti.bounds = new Rect(tr.mBounds);
8696        }
8697
8698        ActivityRecord base = null;
8699        ActivityRecord top = null;
8700        ActivityRecord tmp;
8701
8702        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8703            tmp = tr.mActivities.get(i);
8704            if (tmp.finishing) {
8705                continue;
8706            }
8707            base = tmp;
8708            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8709                top = base;
8710            }
8711            rti.numActivities++;
8712        }
8713
8714        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8715        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8716
8717        return rti;
8718    }
8719
8720    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8721        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8722                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8723        if (!allowed) {
8724            if (checkPermission(android.Manifest.permission.GET_TASKS,
8725                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8726                // Temporary compatibility: some existing apps on the system image may
8727                // still be requesting the old permission and not switched to the new
8728                // one; if so, we'll still allow them full access.  This means we need
8729                // to see if they are holding the old permission and are a system app.
8730                try {
8731                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8732                        allowed = true;
8733                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8734                                + " is using old GET_TASKS but privileged; allowing");
8735                    }
8736                } catch (RemoteException e) {
8737                }
8738            }
8739        }
8740        if (!allowed) {
8741            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8742                    + " does not hold REAL_GET_TASKS; limiting output");
8743        }
8744        return allowed;
8745    }
8746
8747    @Override
8748    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8749        final int callingUid = Binder.getCallingUid();
8750        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8751                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8752
8753        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8754        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8755        synchronized (this) {
8756            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8757                    callingUid);
8758            final boolean detailed = checkCallingPermission(
8759                    android.Manifest.permission.GET_DETAILED_TASKS)
8760                    == PackageManager.PERMISSION_GRANTED;
8761
8762            final int recentsCount = mRecentTasks.size();
8763            ArrayList<ActivityManager.RecentTaskInfo> res =
8764                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8765
8766            final Set<Integer> includedUsers;
8767            if (includeProfiles) {
8768                includedUsers = mUserController.getProfileIds(userId);
8769            } else {
8770                includedUsers = new HashSet<>();
8771            }
8772            includedUsers.add(Integer.valueOf(userId));
8773
8774            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8775                TaskRecord tr = mRecentTasks.get(i);
8776                // Only add calling user or related users recent tasks
8777                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8778                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8779                    continue;
8780                }
8781
8782                // Return the entry if desired by the caller.  We always return
8783                // the first entry, because callers always expect this to be the
8784                // foreground app.  We may filter others if the caller has
8785                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8786                // we should exclude the entry.
8787
8788                if (i == 0
8789                        || withExcluded
8790                        || (tr.intent == null)
8791                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8792                                == 0)) {
8793                    if (!allowed) {
8794                        // If the caller doesn't have the GET_TASKS permission, then only
8795                        // allow them to see a small subset of tasks -- their own and home.
8796                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8797                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8798                            continue;
8799                        }
8800                    }
8801                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8802                        if (tr.stack != null && tr.stack.isHomeStack()) {
8803                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8804                                    "Skipping, home stack task: " + tr);
8805                            continue;
8806                        }
8807                    }
8808                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8809                        if (tr.stack != null && tr.stack.isDockedStack()) {
8810                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8811                                    "Skipping, docked stack task: " + tr);
8812                            continue;
8813                        }
8814                    }
8815                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8816                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8817                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8818                                    "Skipping, pinned stack task: " + tr);
8819                            continue;
8820                        }
8821                    }
8822                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8823                        // Don't include auto remove tasks that are finished or finishing.
8824                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8825                                "Skipping, auto-remove without activity: " + tr);
8826                        continue;
8827                    }
8828                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8829                            && !tr.isAvailable) {
8830                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8831                                "Skipping, unavail real act: " + tr);
8832                        continue;
8833                    }
8834
8835                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8836                    if (!detailed) {
8837                        rti.baseIntent.replaceExtras((Bundle)null);
8838                    }
8839
8840                    res.add(rti);
8841                    maxNum--;
8842                }
8843            }
8844            return res;
8845        }
8846    }
8847
8848    @Override
8849    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8850        synchronized (this) {
8851            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8852                    "getTaskThumbnail()");
8853            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8854                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8855            if (tr != null) {
8856                return tr.getTaskThumbnailLocked();
8857            }
8858        }
8859        return null;
8860    }
8861
8862    @Override
8863    public int addAppTask(IBinder activityToken, Intent intent,
8864            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8865        final int callingUid = Binder.getCallingUid();
8866        final long callingIdent = Binder.clearCallingIdentity();
8867
8868        try {
8869            synchronized (this) {
8870                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8871                if (r == null) {
8872                    throw new IllegalArgumentException("Activity does not exist; token="
8873                            + activityToken);
8874                }
8875                ComponentName comp = intent.getComponent();
8876                if (comp == null) {
8877                    throw new IllegalArgumentException("Intent " + intent
8878                            + " must specify explicit component");
8879                }
8880                if (thumbnail.getWidth() != mThumbnailWidth
8881                        || thumbnail.getHeight() != mThumbnailHeight) {
8882                    throw new IllegalArgumentException("Bad thumbnail size: got "
8883                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8884                            + mThumbnailWidth + "x" + mThumbnailHeight);
8885                }
8886                if (intent.getSelector() != null) {
8887                    intent.setSelector(null);
8888                }
8889                if (intent.getSourceBounds() != null) {
8890                    intent.setSourceBounds(null);
8891                }
8892                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8893                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8894                        // The caller has added this as an auto-remove task...  that makes no
8895                        // sense, so turn off auto-remove.
8896                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8897                    }
8898                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8899                    // Must be a new task.
8900                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8901                }
8902                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8903                    mLastAddedTaskActivity = null;
8904                }
8905                ActivityInfo ainfo = mLastAddedTaskActivity;
8906                if (ainfo == null) {
8907                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8908                            comp, 0, UserHandle.getUserId(callingUid));
8909                    if (ainfo.applicationInfo.uid != callingUid) {
8910                        throw new SecurityException(
8911                                "Can't add task for another application: target uid="
8912                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8913                    }
8914                }
8915
8916                // Use the full screen as the context for the task thumbnail
8917                final Point displaySize = new Point();
8918                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8919                r.task.stack.getDisplaySize(displaySize);
8920                thumbnailInfo.taskWidth = displaySize.x;
8921                thumbnailInfo.taskHeight = displaySize.y;
8922                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8923
8924                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8925                        intent, description, thumbnailInfo);
8926
8927                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8928                if (trimIdx >= 0) {
8929                    // If this would have caused a trim, then we'll abort because that
8930                    // means it would be added at the end of the list but then just removed.
8931                    return INVALID_TASK_ID;
8932                }
8933
8934                final int N = mRecentTasks.size();
8935                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8936                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8937                    tr.removedFromRecents();
8938                }
8939
8940                task.inRecents = true;
8941                mRecentTasks.add(task);
8942                r.task.stack.addTask(task, false, "addAppTask");
8943
8944                task.setLastThumbnailLocked(thumbnail);
8945                task.freeLastThumbnail();
8946
8947                return task.taskId;
8948            }
8949        } finally {
8950            Binder.restoreCallingIdentity(callingIdent);
8951        }
8952    }
8953
8954    @Override
8955    public Point getAppTaskThumbnailSize() {
8956        synchronized (this) {
8957            return new Point(mThumbnailWidth,  mThumbnailHeight);
8958        }
8959    }
8960
8961    @Override
8962    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8963        synchronized (this) {
8964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8965            if (r != null) {
8966                r.setTaskDescription(td);
8967                r.task.updateTaskDescription();
8968            }
8969        }
8970    }
8971
8972    @Override
8973    public void setTaskResizeable(int taskId, boolean resizeable) {
8974        synchronized (this) {
8975            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8976                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8977            if (task == null) {
8978                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8979                return;
8980            }
8981            if (task.mResizeable != resizeable) {
8982                task.mResizeable = resizeable;
8983                mWindowManager.setTaskResizeable(taskId, resizeable);
8984                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8985                mStackSupervisor.resumeTopActivitiesLocked();
8986            }
8987        }
8988    }
8989
8990    @Override
8991    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8992        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8993                "resizeTask()");
8994        long ident = Binder.clearCallingIdentity();
8995        try {
8996            synchronized (this) {
8997                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8998                if (task == null) {
8999                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9000                    return;
9001                }
9002                int stackId = task.stack.mStackId;
9003                // First, check if this is a non-resizeble task in docked stack or if the task size
9004                // is affected by the docked stack changing size. If so, instead of resizing, we
9005                // can only scroll the task. No need to update configuration.
9006                if (bounds != null && !task.mResizeable
9007                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9008                    mWindowManager.scrollTask(task.taskId, bounds);
9009                    return;
9010                }
9011
9012                // Place the task in the right stack if it isn't there already based on
9013                // the requested bounds.
9014                // The stack transition logic is:
9015                // - a null bounds on a freeform task moves that task to fullscreen
9016                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9017                //   that task to freeform
9018                // - otherwise the task is not moved
9019                if (!StackId.isTaskResizeAllowed(stackId)) {
9020                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9021                }
9022                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9023                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9024                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9025                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9026                }
9027                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9028                if (stackId != task.stack.mStackId) {
9029                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9030                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9031                    preserveWindow = false;
9032                }
9033
9034                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9035            }
9036        } finally {
9037            Binder.restoreCallingIdentity(ident);
9038        }
9039    }
9040
9041    @Override
9042    public Rect getTaskBounds(int taskId) {
9043        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9044                "getTaskBounds()");
9045        long ident = Binder.clearCallingIdentity();
9046        Rect rect = new Rect();
9047        try {
9048            synchronized (this) {
9049                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9050                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9051                if (task == null) {
9052                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9053                    return rect;
9054                }
9055                if (task.stack != null) {
9056                    // Return the bounds from window manager since it will be adjusted for various
9057                    // things like the presense of a docked stack for tasks that aren't resizeable.
9058                    mWindowManager.getTaskBounds(task.taskId, rect);
9059                } else {
9060                    // Task isn't in window manager yet since it isn't associated with a stack.
9061                    // Return the persist value from activity manager
9062                    if (task.mBounds != null) {
9063                        rect.set(task.mBounds);
9064                    } else if (task.mLastNonFullscreenBounds != null) {
9065                        rect.set(task.mLastNonFullscreenBounds);
9066                    }
9067                }
9068            }
9069        } finally {
9070            Binder.restoreCallingIdentity(ident);
9071        }
9072        return rect;
9073    }
9074
9075    @Override
9076    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9077        if (userId != UserHandle.getCallingUserId()) {
9078            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9079                    "getTaskDescriptionIcon");
9080        }
9081        final File passedIconFile = new File(filePath);
9082        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9083                passedIconFile.getName());
9084        if (!legitIconFile.getPath().equals(filePath)
9085                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9086            throw new IllegalArgumentException("Bad file path: " + filePath);
9087        }
9088        return mTaskPersister.getTaskDescriptionIcon(filePath);
9089    }
9090
9091    @Override
9092    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9093            throws RemoteException {
9094        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9095                opts.getCustomInPlaceResId() == 0) {
9096            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9097                    "with valid animation");
9098        }
9099        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9100        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9101                opts.getCustomInPlaceResId());
9102        mWindowManager.executeAppTransition();
9103    }
9104
9105    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9106            boolean removeFromRecents) {
9107        if (removeFromRecents) {
9108            mRecentTasks.remove(tr);
9109            tr.removedFromRecents();
9110        }
9111        ComponentName component = tr.getBaseIntent().getComponent();
9112        if (component == null) {
9113            Slog.w(TAG, "No component for base intent of task: " + tr);
9114            return;
9115        }
9116
9117        // Find any running services associated with this app and stop if needed.
9118        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9119
9120        if (!killProcess) {
9121            return;
9122        }
9123
9124        // Determine if the process(es) for this task should be killed.
9125        final String pkg = component.getPackageName();
9126        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9127        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9128        for (int i = 0; i < pmap.size(); i++) {
9129
9130            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9131            for (int j = 0; j < uids.size(); j++) {
9132                ProcessRecord proc = uids.valueAt(j);
9133                if (proc.userId != tr.userId) {
9134                    // Don't kill process for a different user.
9135                    continue;
9136                }
9137                if (proc == mHomeProcess) {
9138                    // Don't kill the home process along with tasks from the same package.
9139                    continue;
9140                }
9141                if (!proc.pkgList.containsKey(pkg)) {
9142                    // Don't kill process that is not associated with this task.
9143                    continue;
9144                }
9145
9146                for (int k = 0; k < proc.activities.size(); k++) {
9147                    TaskRecord otherTask = proc.activities.get(k).task;
9148                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9149                        // Don't kill process(es) that has an activity in a different task that is
9150                        // also in recents.
9151                        return;
9152                    }
9153                }
9154
9155                if (proc.foregroundServices) {
9156                    // Don't kill process(es) with foreground service.
9157                    return;
9158                }
9159
9160                // Add process to kill list.
9161                procsToKill.add(proc);
9162            }
9163        }
9164
9165        // Kill the running processes.
9166        for (int i = 0; i < procsToKill.size(); i++) {
9167            ProcessRecord pr = procsToKill.get(i);
9168            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9169                    && pr.curReceiver == null) {
9170                pr.kill("remove task", true);
9171            } else {
9172                // We delay killing processes that are not in the background or running a receiver.
9173                pr.waitingToKill = "remove task";
9174            }
9175        }
9176    }
9177
9178    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9179        // Remove all tasks with activities in the specified package from the list of recent tasks
9180        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9181            TaskRecord tr = mRecentTasks.get(i);
9182            if (tr.userId != userId) continue;
9183
9184            ComponentName cn = tr.intent.getComponent();
9185            if (cn != null && cn.getPackageName().equals(packageName)) {
9186                // If the package name matches, remove the task.
9187                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9188            }
9189        }
9190    }
9191
9192    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9193            int userId) {
9194
9195        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9196            TaskRecord tr = mRecentTasks.get(i);
9197            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9198                continue;
9199            }
9200
9201            ComponentName cn = tr.intent.getComponent();
9202            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9203                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9204            if (sameComponent) {
9205                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9206            }
9207        }
9208    }
9209
9210    /**
9211     * Removes the task with the specified task id.
9212     *
9213     * @param taskId Identifier of the task to be removed.
9214     * @param killProcess Kill any process associated with the task if possible.
9215     * @param removeFromRecents Whether to also remove the task from recents.
9216     * @return Returns true if the given task was found and removed.
9217     */
9218    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9219            boolean removeFromRecents) {
9220        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9221                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9222        if (tr != null) {
9223            tr.removeTaskActivitiesLocked();
9224            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9225            if (tr.isPersistable) {
9226                notifyTaskPersisterLocked(null, true);
9227            }
9228            return true;
9229        }
9230        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9231        return false;
9232    }
9233
9234    @Override
9235    public boolean removeTask(int taskId) {
9236        synchronized (this) {
9237            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9238                    "removeTask()");
9239            long ident = Binder.clearCallingIdentity();
9240            try {
9241                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9242            } finally {
9243                Binder.restoreCallingIdentity(ident);
9244            }
9245        }
9246    }
9247
9248    /**
9249     * TODO: Add mController hook
9250     */
9251    @Override
9252    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9253        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9254
9255        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9256        synchronized(this) {
9257            moveTaskToFrontLocked(taskId, flags, bOptions);
9258        }
9259    }
9260
9261    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9262        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9263
9264        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9265                Binder.getCallingUid(), -1, -1, "Task to front")) {
9266            ActivityOptions.abort(options);
9267            return;
9268        }
9269        final long origId = Binder.clearCallingIdentity();
9270        try {
9271            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9272            if (task == null) {
9273                Slog.d(TAG, "Could not find task for id: "+ taskId);
9274                return;
9275            }
9276            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9277                mStackSupervisor.showLockTaskToast();
9278                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9279                return;
9280            }
9281            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9282            if (prev != null && prev.isRecentsActivity()) {
9283                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9284            }
9285            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9286        } finally {
9287            Binder.restoreCallingIdentity(origId);
9288        }
9289        ActivityOptions.abort(options);
9290    }
9291
9292    /**
9293     * Moves an activity, and all of the other activities within the same task, to the bottom
9294     * of the history stack.  The activity's order within the task is unchanged.
9295     *
9296     * @param token A reference to the activity we wish to move
9297     * @param nonRoot If false then this only works if the activity is the root
9298     *                of a task; if true it will work for any activity in a task.
9299     * @return Returns true if the move completed, false if not.
9300     */
9301    @Override
9302    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9303        enforceNotIsolatedCaller("moveActivityTaskToBack");
9304        synchronized(this) {
9305            final long origId = Binder.clearCallingIdentity();
9306            try {
9307                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9308                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9309                if (task != null) {
9310                    if (mStackSupervisor.isLockedTask(task)) {
9311                        mStackSupervisor.showLockTaskToast();
9312                        return false;
9313                    }
9314                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9315                }
9316            } finally {
9317                Binder.restoreCallingIdentity(origId);
9318            }
9319        }
9320        return false;
9321    }
9322
9323    @Override
9324    public void moveTaskBackwards(int task) {
9325        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9326                "moveTaskBackwards()");
9327
9328        synchronized(this) {
9329            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9330                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9331                return;
9332            }
9333            final long origId = Binder.clearCallingIdentity();
9334            moveTaskBackwardsLocked(task);
9335            Binder.restoreCallingIdentity(origId);
9336        }
9337    }
9338
9339    private final void moveTaskBackwardsLocked(int task) {
9340        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9341    }
9342
9343    @Override
9344    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9345            IActivityContainerCallback callback) throws RemoteException {
9346        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9347                "createActivityContainer()");
9348        synchronized (this) {
9349            if (parentActivityToken == null) {
9350                throw new IllegalArgumentException("parent token must not be null");
9351            }
9352            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9353            if (r == null) {
9354                return null;
9355            }
9356            if (callback == null) {
9357                throw new IllegalArgumentException("callback must not be null");
9358            }
9359            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9360        }
9361    }
9362
9363    @Override
9364    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9365        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9366                "deleteActivityContainer()");
9367        synchronized (this) {
9368            mStackSupervisor.deleteActivityContainer(container);
9369        }
9370    }
9371
9372    @Override
9373    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9374        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9375                "createStackOnDisplay()");
9376        synchronized (this) {
9377            final int stackId = mStackSupervisor.getNextStackId();
9378            final ActivityStack stack =
9379                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9380            if (stack == null) {
9381                return null;
9382            }
9383            return stack.mActivityContainer;
9384        }
9385    }
9386
9387    @Override
9388    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9389        synchronized (this) {
9390            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9391            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9392                return stack.mActivityContainer.getDisplayId();
9393            }
9394            return Display.DEFAULT_DISPLAY;
9395        }
9396    }
9397
9398    @Override
9399    public int getActivityStackId(IBinder token) throws RemoteException {
9400        synchronized (this) {
9401            ActivityStack stack = ActivityRecord.getStackLocked(token);
9402            if (stack == null) {
9403                return INVALID_STACK_ID;
9404            }
9405            return stack.mStackId;
9406        }
9407    }
9408
9409    @Override
9410    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9411        if (stackId == HOME_STACK_ID) {
9412            throw new IllegalArgumentException(
9413                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9414        }
9415        synchronized (this) {
9416            long ident = Binder.clearCallingIdentity();
9417            try {
9418                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9419                if (r == null) {
9420                    throw new IllegalArgumentException(
9421                            "moveActivityToStack: No activity record matching token=" + token);
9422                }
9423                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9424                        + " to stackId=" + stackId);
9425                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9426                        "moveActivityToStack", ANIMATE);
9427            } finally {
9428                Binder.restoreCallingIdentity(ident);
9429            }
9430        }
9431    }
9432
9433    @Override
9434    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9435        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9436                "moveTaskToStack()");
9437        if (stackId == HOME_STACK_ID) {
9438            throw new IllegalArgumentException(
9439                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9440        }
9441        synchronized (this) {
9442            long ident = Binder.clearCallingIdentity();
9443            try {
9444                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9445                        + " to stackId=" + stackId + " toTop=" + toTop);
9446                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9447                        "moveTaskToStack", ANIMATE);
9448            } finally {
9449                Binder.restoreCallingIdentity(ident);
9450            }
9451        }
9452    }
9453
9454    /**
9455     * Moves the input task to the docked stack.
9456     *
9457     * @param taskId Id of task to move.
9458     * @param createMode The mode the docked stack should be created in if it doesn't exist
9459     *                   already. See
9460     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9461     *                   and
9462     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9463     * @param toTop If the task and stack should be moved to the top.
9464     * @param animate Whether we should play an animation for the moving the task
9465     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9466     *                      docked stack. Pass {@code null} to use default bounds.
9467     */
9468    @Override
9469    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9470            Rect initialBounds) {
9471        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9472                "moveTaskToDockedStack()");
9473        synchronized (this) {
9474            long ident = Binder.clearCallingIdentity();
9475            try {
9476                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9477                        + " to createMode=" + createMode + " toTop=" + toTop);
9478                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9479                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9480                        "moveTaskToDockedStack", animate);
9481            } finally {
9482                Binder.restoreCallingIdentity(ident);
9483            }
9484        }
9485    }
9486
9487    /**
9488     * Moves the top activity in the input stackId to the pinned stack.
9489     *
9490     * @param stackId Id of stack to move the top activity to pinned stack.
9491     * @param bounds Bounds to use for pinned stack.
9492     *
9493     * @return True if the top activity of the input stack was successfully moved to the pinned
9494     *          stack.
9495     */
9496    @Override
9497    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9498        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9499                "moveTopActivityToPinnedStack()");
9500        synchronized (this) {
9501            if (!mSupportsPictureInPicture) {
9502                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9503                        + "Device doesn't support picture-in-pciture mode");
9504            }
9505
9506            long ident = Binder.clearCallingIdentity();
9507            try {
9508                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9509            } finally {
9510                Binder.restoreCallingIdentity(ident);
9511            }
9512        }
9513    }
9514
9515    @Override
9516    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9517        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9518                "resizeStack()");
9519        long ident = Binder.clearCallingIdentity();
9520        try {
9521            synchronized (this) {
9522                mStackSupervisor.resizeStackLocked(
9523                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9524            }
9525        } finally {
9526            Binder.restoreCallingIdentity(ident);
9527        }
9528    }
9529
9530    @Override
9531    public void positionTaskInStack(int taskId, int stackId, int position) {
9532        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9533                "positionTaskInStack()");
9534        if (stackId == HOME_STACK_ID) {
9535            throw new IllegalArgumentException(
9536                    "positionTaskInStack: Attempt to change the position of task "
9537                    + taskId + " in/to home stack");
9538        }
9539        synchronized (this) {
9540            long ident = Binder.clearCallingIdentity();
9541            try {
9542                if (DEBUG_STACK) Slog.d(TAG_STACK,
9543                        "positionTaskInStack: positioning task=" + taskId
9544                        + " in stackId=" + stackId + " at position=" + position);
9545                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9546            } finally {
9547                Binder.restoreCallingIdentity(ident);
9548            }
9549        }
9550    }
9551
9552    @Override
9553    public List<StackInfo> getAllStackInfos() {
9554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9555                "getAllStackInfos()");
9556        long ident = Binder.clearCallingIdentity();
9557        try {
9558            synchronized (this) {
9559                return mStackSupervisor.getAllStackInfosLocked();
9560            }
9561        } finally {
9562            Binder.restoreCallingIdentity(ident);
9563        }
9564    }
9565
9566    @Override
9567    public StackInfo getStackInfo(int stackId) {
9568        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9569                "getStackInfo()");
9570        long ident = Binder.clearCallingIdentity();
9571        try {
9572            synchronized (this) {
9573                return mStackSupervisor.getStackInfoLocked(stackId);
9574            }
9575        } finally {
9576            Binder.restoreCallingIdentity(ident);
9577        }
9578    }
9579
9580    @Override
9581    public boolean isInHomeStack(int taskId) {
9582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9583                "getStackInfo()");
9584        long ident = Binder.clearCallingIdentity();
9585        try {
9586            synchronized (this) {
9587                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9588                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9589                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9590            }
9591        } finally {
9592            Binder.restoreCallingIdentity(ident);
9593        }
9594    }
9595
9596    @Override
9597    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9598        synchronized(this) {
9599            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9600        }
9601    }
9602
9603    @Override
9604    public void updateDeviceOwner(String packageName) {
9605        final int callingUid = Binder.getCallingUid();
9606        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9607            throw new SecurityException("updateDeviceOwner called from non-system process");
9608        }
9609        synchronized (this) {
9610            mDeviceOwnerName = packageName;
9611        }
9612    }
9613
9614    @Override
9615    public void updateLockTaskPackages(int userId, String[] packages) {
9616        final int callingUid = Binder.getCallingUid();
9617        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9618            throw new SecurityException("updateLockTaskPackage called from non-system process");
9619        }
9620        synchronized (this) {
9621            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9622                    Arrays.toString(packages));
9623            mLockTaskPackages.put(userId, packages);
9624            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9625        }
9626    }
9627
9628
9629    void startLockTaskModeLocked(TaskRecord task) {
9630        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9631        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9632            return;
9633        }
9634
9635        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9636        // is initiated by system after the pinning request was shown and locked mode is initiated
9637        // by an authorized app directly
9638        final int callingUid = Binder.getCallingUid();
9639        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9640        long ident = Binder.clearCallingIdentity();
9641        try {
9642            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9643            if (!isSystemInitiated) {
9644                task.mLockTaskUid = callingUid;
9645                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9646                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9647                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9648                    StatusBarManagerInternal statusBarManager =
9649                            LocalServices.getService(StatusBarManagerInternal.class);
9650                    if (statusBarManager != null) {
9651                        statusBarManager.showScreenPinningRequest();
9652                    }
9653                    return;
9654                }
9655
9656                if (stack == null || task != stack.topTask()) {
9657                    throw new IllegalArgumentException("Invalid task, not in foreground");
9658                }
9659            }
9660            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9661                    "Locking fully");
9662            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9663                    ActivityManager.LOCK_TASK_MODE_PINNED :
9664                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9665                    "startLockTask", true);
9666        } finally {
9667            Binder.restoreCallingIdentity(ident);
9668        }
9669    }
9670
9671    @Override
9672    public void startLockTaskMode(int taskId) {
9673        synchronized (this) {
9674            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9675            if (task != null) {
9676                startLockTaskModeLocked(task);
9677            }
9678        }
9679    }
9680
9681    @Override
9682    public void startLockTaskMode(IBinder token) {
9683        synchronized (this) {
9684            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9685            if (r == null) {
9686                return;
9687            }
9688            final TaskRecord task = r.task;
9689            if (task != null) {
9690                startLockTaskModeLocked(task);
9691            }
9692        }
9693    }
9694
9695    @Override
9696    public void startLockTaskModeOnCurrent() throws RemoteException {
9697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9698                "startLockTaskModeOnCurrent");
9699        long ident = Binder.clearCallingIdentity();
9700        try {
9701            synchronized (this) {
9702                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9703                if (r != null) {
9704                    startLockTaskModeLocked(r.task);
9705                }
9706            }
9707        } finally {
9708            Binder.restoreCallingIdentity(ident);
9709        }
9710    }
9711
9712    @Override
9713    public void stopLockTaskMode() {
9714        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9715        if (lockTask == null) {
9716            // Our work here is done.
9717            return;
9718        }
9719
9720        final int callingUid = Binder.getCallingUid();
9721        final int lockTaskUid = lockTask.mLockTaskUid;
9722        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9723        // It is possible lockTaskMode was started by the system process because
9724        // android:lockTaskMode is set to a locking value in the application manifest instead of
9725        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9726        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9727        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9728                callingUid != lockTaskUid
9729                && (lockTaskUid != 0
9730                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9731            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9732                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9733        }
9734
9735        long ident = Binder.clearCallingIdentity();
9736        try {
9737            Log.d(TAG, "stopLockTaskMode");
9738            // Stop lock task
9739            synchronized (this) {
9740                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9741                        "stopLockTask", true);
9742            }
9743        } finally {
9744            Binder.restoreCallingIdentity(ident);
9745        }
9746    }
9747
9748    @Override
9749    public void stopLockTaskModeOnCurrent() throws RemoteException {
9750        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9751                "stopLockTaskModeOnCurrent");
9752        long ident = Binder.clearCallingIdentity();
9753        try {
9754            stopLockTaskMode();
9755        } finally {
9756            Binder.restoreCallingIdentity(ident);
9757        }
9758    }
9759
9760    @Override
9761    public boolean isInLockTaskMode() {
9762        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9763    }
9764
9765    @Override
9766    public int getLockTaskModeState() {
9767        synchronized (this) {
9768            return mStackSupervisor.getLockTaskModeState();
9769        }
9770    }
9771
9772    @Override
9773    public void showLockTaskEscapeMessage(IBinder token) {
9774        synchronized (this) {
9775            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9776            if (r == null) {
9777                return;
9778            }
9779            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9780        }
9781    }
9782
9783    // =========================================================
9784    // CONTENT PROVIDERS
9785    // =========================================================
9786
9787    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9788        List<ProviderInfo> providers = null;
9789        try {
9790            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9791                    .queryContentProviders(app.processName, app.uid,
9792                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9793                                    | PackageManager.MATCH_ENCRYPTION_DEFAULT);
9794            providers = slice != null ? slice.getList() : null;
9795        } catch (RemoteException ex) {
9796        }
9797        if (DEBUG_MU) Slog.v(TAG_MU,
9798                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9799        int userId = app.userId;
9800        if (providers != null) {
9801            int N = providers.size();
9802            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9803            for (int i=0; i<N; i++) {
9804                ProviderInfo cpi =
9805                    (ProviderInfo)providers.get(i);
9806                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9807                        cpi.name, cpi.flags);
9808                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9809                    // This is a singleton provider, but a user besides the
9810                    // default user is asking to initialize a process it runs
9811                    // in...  well, no, it doesn't actually run in this process,
9812                    // it runs in the process of the default user.  Get rid of it.
9813                    providers.remove(i);
9814                    N--;
9815                    i--;
9816                    continue;
9817                }
9818
9819                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9820                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9821                if (cpr == null) {
9822                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9823                    mProviderMap.putProviderByClass(comp, cpr);
9824                }
9825                if (DEBUG_MU) Slog.v(TAG_MU,
9826                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9827                app.pubProviders.put(cpi.name, cpr);
9828                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9829                    // Don't add this if it is a platform component that is marked
9830                    // to run in multiple processes, because this is actually
9831                    // part of the framework so doesn't make sense to track as a
9832                    // separate apk in the process.
9833                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9834                            mProcessStats);
9835                }
9836                notifyPackageUse(cpi.applicationInfo.packageName);
9837            }
9838        }
9839        return providers;
9840    }
9841
9842    /**
9843     * Check if {@link ProcessRecord} has a possible chance at accessing the
9844     * given {@link ProviderInfo}. Final permission checking is always done
9845     * in {@link ContentProvider}.
9846     */
9847    private final String checkContentProviderPermissionLocked(
9848            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9849        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9850        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9851        boolean checkedGrants = false;
9852        if (checkUser) {
9853            // Looking for cross-user grants before enforcing the typical cross-users permissions
9854            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9855            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9856                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9857                    return null;
9858                }
9859                checkedGrants = true;
9860            }
9861            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9862                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9863            if (userId != tmpTargetUserId) {
9864                // When we actually went to determine the final targer user ID, this ended
9865                // up different than our initial check for the authority.  This is because
9866                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9867                // SELF.  So we need to re-check the grants again.
9868                checkedGrants = false;
9869            }
9870        }
9871        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9872                cpi.applicationInfo.uid, cpi.exported)
9873                == PackageManager.PERMISSION_GRANTED) {
9874            return null;
9875        }
9876        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9877                cpi.applicationInfo.uid, cpi.exported)
9878                == PackageManager.PERMISSION_GRANTED) {
9879            return null;
9880        }
9881
9882        PathPermission[] pps = cpi.pathPermissions;
9883        if (pps != null) {
9884            int i = pps.length;
9885            while (i > 0) {
9886                i--;
9887                PathPermission pp = pps[i];
9888                String pprperm = pp.getReadPermission();
9889                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9890                        cpi.applicationInfo.uid, cpi.exported)
9891                        == PackageManager.PERMISSION_GRANTED) {
9892                    return null;
9893                }
9894                String ppwperm = pp.getWritePermission();
9895                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9896                        cpi.applicationInfo.uid, cpi.exported)
9897                        == PackageManager.PERMISSION_GRANTED) {
9898                    return null;
9899                }
9900            }
9901        }
9902        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9903            return null;
9904        }
9905
9906        String msg;
9907        if (!cpi.exported) {
9908            msg = "Permission Denial: opening provider " + cpi.name
9909                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9910                    + ", uid=" + callingUid + ") that is not exported from uid "
9911                    + cpi.applicationInfo.uid;
9912        } else {
9913            msg = "Permission Denial: opening provider " + cpi.name
9914                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9915                    + ", uid=" + callingUid + ") requires "
9916                    + cpi.readPermission + " or " + cpi.writePermission;
9917        }
9918        Slog.w(TAG, msg);
9919        return msg;
9920    }
9921
9922    /**
9923     * Returns if the ContentProvider has granted a uri to callingUid
9924     */
9925    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9926        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9927        if (perms != null) {
9928            for (int i=perms.size()-1; i>=0; i--) {
9929                GrantUri grantUri = perms.keyAt(i);
9930                if (grantUri.sourceUserId == userId || !checkUser) {
9931                    if (matchesProvider(grantUri.uri, cpi)) {
9932                        return true;
9933                    }
9934                }
9935            }
9936        }
9937        return false;
9938    }
9939
9940    /**
9941     * Returns true if the uri authority is one of the authorities specified in the provider.
9942     */
9943    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9944        String uriAuth = uri.getAuthority();
9945        String cpiAuth = cpi.authority;
9946        if (cpiAuth.indexOf(';') == -1) {
9947            return cpiAuth.equals(uriAuth);
9948        }
9949        String[] cpiAuths = cpiAuth.split(";");
9950        int length = cpiAuths.length;
9951        for (int i = 0; i < length; i++) {
9952            if (cpiAuths[i].equals(uriAuth)) return true;
9953        }
9954        return false;
9955    }
9956
9957    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9958            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9959        if (r != null) {
9960            for (int i=0; i<r.conProviders.size(); i++) {
9961                ContentProviderConnection conn = r.conProviders.get(i);
9962                if (conn.provider == cpr) {
9963                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9964                            "Adding provider requested by "
9965                            + r.processName + " from process "
9966                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9967                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9968                    if (stable) {
9969                        conn.stableCount++;
9970                        conn.numStableIncs++;
9971                    } else {
9972                        conn.unstableCount++;
9973                        conn.numUnstableIncs++;
9974                    }
9975                    return conn;
9976                }
9977            }
9978            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9979            if (stable) {
9980                conn.stableCount = 1;
9981                conn.numStableIncs = 1;
9982            } else {
9983                conn.unstableCount = 1;
9984                conn.numUnstableIncs = 1;
9985            }
9986            cpr.connections.add(conn);
9987            r.conProviders.add(conn);
9988            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9989            return conn;
9990        }
9991        cpr.addExternalProcessHandleLocked(externalProcessToken);
9992        return null;
9993    }
9994
9995    boolean decProviderCountLocked(ContentProviderConnection conn,
9996            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9997        if (conn != null) {
9998            cpr = conn.provider;
9999            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10000                    "Removing provider requested by "
10001                    + conn.client.processName + " from process "
10002                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10003                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10004            if (stable) {
10005                conn.stableCount--;
10006            } else {
10007                conn.unstableCount--;
10008            }
10009            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10010                cpr.connections.remove(conn);
10011                conn.client.conProviders.remove(conn);
10012                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10013                    // The client is more important than last activity -- note the time this
10014                    // is happening, so we keep the old provider process around a bit as last
10015                    // activity to avoid thrashing it.
10016                    if (cpr.proc != null) {
10017                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10018                    }
10019                }
10020                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10021                return true;
10022            }
10023            return false;
10024        }
10025        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10026        return false;
10027    }
10028
10029    private void checkTime(long startTime, String where) {
10030        long now = SystemClock.elapsedRealtime();
10031        if ((now-startTime) > 1000) {
10032            // If we are taking more than a second, log about it.
10033            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10034        }
10035    }
10036
10037    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10038            String name, IBinder token, boolean stable, int userId) {
10039        ContentProviderRecord cpr;
10040        ContentProviderConnection conn = null;
10041        ProviderInfo cpi = null;
10042
10043        synchronized(this) {
10044            long startTime = SystemClock.elapsedRealtime();
10045
10046            ProcessRecord r = null;
10047            if (caller != null) {
10048                r = getRecordForAppLocked(caller);
10049                if (r == null) {
10050                    throw new SecurityException(
10051                            "Unable to find app for caller " + caller
10052                          + " (pid=" + Binder.getCallingPid()
10053                          + ") when getting content provider " + name);
10054                }
10055            }
10056
10057            boolean checkCrossUser = true;
10058
10059            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10060
10061            // First check if this content provider has been published...
10062            cpr = mProviderMap.getProviderByName(name, userId);
10063            // If that didn't work, check if it exists for user 0 and then
10064            // verify that it's a singleton provider before using it.
10065            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10066                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10067                if (cpr != null) {
10068                    cpi = cpr.info;
10069                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10070                            cpi.name, cpi.flags)
10071                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10072                        userId = UserHandle.USER_SYSTEM;
10073                        checkCrossUser = false;
10074                    } else {
10075                        cpr = null;
10076                        cpi = null;
10077                    }
10078                }
10079            }
10080
10081            boolean providerRunning = cpr != null;
10082            if (providerRunning) {
10083                cpi = cpr.info;
10084                String msg;
10085                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10086                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10087                        != null) {
10088                    throw new SecurityException(msg);
10089                }
10090                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10091
10092                if (r != null && cpr.canRunHere(r)) {
10093                    // This provider has been published or is in the process
10094                    // of being published...  but it is also allowed to run
10095                    // in the caller's process, so don't make a connection
10096                    // and just let the caller instantiate its own instance.
10097                    ContentProviderHolder holder = cpr.newHolder(null);
10098                    // don't give caller the provider object, it needs
10099                    // to make its own.
10100                    holder.provider = null;
10101                    return holder;
10102                }
10103
10104                final long origId = Binder.clearCallingIdentity();
10105
10106                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10107
10108                // In this case the provider instance already exists, so we can
10109                // return it right away.
10110                conn = incProviderCountLocked(r, cpr, token, stable);
10111                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10112                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10113                        // If this is a perceptible app accessing the provider,
10114                        // make sure to count it as being accessed and thus
10115                        // back up on the LRU list.  This is good because
10116                        // content providers are often expensive to start.
10117                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10118                        updateLruProcessLocked(cpr.proc, false, null);
10119                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10120                    }
10121                }
10122
10123                if (cpr.proc != null) {
10124                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10125                    boolean success = updateOomAdjLocked(cpr.proc);
10126                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10127                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10128                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10129                    // NOTE: there is still a race here where a signal could be
10130                    // pending on the process even though we managed to update its
10131                    // adj level.  Not sure what to do about this, but at least
10132                    // the race is now smaller.
10133                    if (!success) {
10134                        // Uh oh...  it looks like the provider's process
10135                        // has been killed on us.  We need to wait for a new
10136                        // process to be started, and make sure its death
10137                        // doesn't kill our process.
10138                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10139                                + " is crashing; detaching " + r);
10140                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10141                        checkTime(startTime, "getContentProviderImpl: before appDied");
10142                        appDiedLocked(cpr.proc);
10143                        checkTime(startTime, "getContentProviderImpl: after appDied");
10144                        if (!lastRef) {
10145                            // This wasn't the last ref our process had on
10146                            // the provider...  we have now been killed, bail.
10147                            return null;
10148                        }
10149                        providerRunning = false;
10150                        conn = null;
10151                    }
10152                }
10153
10154                Binder.restoreCallingIdentity(origId);
10155            }
10156
10157            if (!providerRunning) {
10158                try {
10159                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10160                    cpi = AppGlobals.getPackageManager().
10161                        resolveContentProvider(name,
10162                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10163                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10164                } catch (RemoteException ex) {
10165                }
10166                if (cpi == null) {
10167                    return null;
10168                }
10169                // If the provider is a singleton AND
10170                // (it's a call within the same user || the provider is a
10171                // privileged app)
10172                // Then allow connecting to the singleton provider
10173                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10174                        cpi.name, cpi.flags)
10175                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10176                if (singleton) {
10177                    userId = UserHandle.USER_SYSTEM;
10178                }
10179                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10180                checkTime(startTime, "getContentProviderImpl: got app info for user");
10181
10182                String msg;
10183                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10184                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10185                        != null) {
10186                    throw new SecurityException(msg);
10187                }
10188                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10189
10190                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10191                        && !cpi.processName.equals("system")) {
10192                    // If this content provider does not run in the system
10193                    // process, and the system is not yet ready to run other
10194                    // processes, then fail fast instead of hanging.
10195                    throw new IllegalArgumentException(
10196                            "Attempt to launch content provider before system ready");
10197                }
10198
10199                // Make sure that the user who owns this provider is running.  If not,
10200                // we don't want to allow it to run.
10201                if (!mUserController.isUserRunningLocked(userId, 0)) {
10202                    Slog.w(TAG, "Unable to launch app "
10203                            + cpi.applicationInfo.packageName + "/"
10204                            + cpi.applicationInfo.uid + " for provider "
10205                            + name + ": user " + userId + " is stopped");
10206                    return null;
10207                }
10208
10209                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10210                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10211                cpr = mProviderMap.getProviderByClass(comp, userId);
10212                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10213                final boolean firstClass = cpr == null;
10214                if (firstClass) {
10215                    final long ident = Binder.clearCallingIdentity();
10216
10217                    // If permissions need a review before any of the app components can run,
10218                    // we return no provider and launch a review activity if the calling app
10219                    // is in the foreground.
10220                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10221                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10222                            return null;
10223                        }
10224                    }
10225
10226                    try {
10227                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10228                        ApplicationInfo ai =
10229                            AppGlobals.getPackageManager().
10230                                getApplicationInfo(
10231                                        cpi.applicationInfo.packageName,
10232                                        STOCK_PM_FLAGS, userId);
10233                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10234                        if (ai == null) {
10235                            Slog.w(TAG, "No package info for content provider "
10236                                    + cpi.name);
10237                            return null;
10238                        }
10239                        ai = getAppInfoForUser(ai, userId);
10240                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10241                    } catch (RemoteException ex) {
10242                        // pm is in same process, this will never happen.
10243                    } finally {
10244                        Binder.restoreCallingIdentity(ident);
10245                    }
10246                }
10247
10248                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10249
10250                if (r != null && cpr.canRunHere(r)) {
10251                    // If this is a multiprocess provider, then just return its
10252                    // info and allow the caller to instantiate it.  Only do
10253                    // this if the provider is the same user as the caller's
10254                    // process, or can run as root (so can be in any process).
10255                    return cpr.newHolder(null);
10256                }
10257
10258                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10259                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10260                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10261
10262                // This is single process, and our app is now connecting to it.
10263                // See if we are already in the process of launching this
10264                // provider.
10265                final int N = mLaunchingProviders.size();
10266                int i;
10267                for (i = 0; i < N; i++) {
10268                    if (mLaunchingProviders.get(i) == cpr) {
10269                        break;
10270                    }
10271                }
10272
10273                // If the provider is not already being launched, then get it
10274                // started.
10275                if (i >= N) {
10276                    final long origId = Binder.clearCallingIdentity();
10277
10278                    try {
10279                        // Content provider is now in use, its package can't be stopped.
10280                        try {
10281                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10282                            AppGlobals.getPackageManager().setPackageStoppedState(
10283                                    cpr.appInfo.packageName, false, userId);
10284                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10285                        } catch (RemoteException e) {
10286                        } catch (IllegalArgumentException e) {
10287                            Slog.w(TAG, "Failed trying to unstop package "
10288                                    + cpr.appInfo.packageName + ": " + e);
10289                        }
10290
10291                        // Use existing process if already started
10292                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10293                        ProcessRecord proc = getProcessRecordLocked(
10294                                cpi.processName, cpr.appInfo.uid, false);
10295                        if (proc != null && proc.thread != null) {
10296                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10297                                    "Installing in existing process " + proc);
10298                            if (!proc.pubProviders.containsKey(cpi.name)) {
10299                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10300                                proc.pubProviders.put(cpi.name, cpr);
10301                                try {
10302                                    proc.thread.scheduleInstallProvider(cpi);
10303                                } catch (RemoteException e) {
10304                                }
10305                            }
10306                        } else {
10307                            checkTime(startTime, "getContentProviderImpl: before start process");
10308                            proc = startProcessLocked(cpi.processName,
10309                                    cpr.appInfo, false, 0, "content provider",
10310                                    new ComponentName(cpi.applicationInfo.packageName,
10311                                            cpi.name), false, false, false);
10312                            checkTime(startTime, "getContentProviderImpl: after start process");
10313                            if (proc == null) {
10314                                Slog.w(TAG, "Unable to launch app "
10315                                        + cpi.applicationInfo.packageName + "/"
10316                                        + cpi.applicationInfo.uid + " for provider "
10317                                        + name + ": process is bad");
10318                                return null;
10319                            }
10320                        }
10321                        cpr.launchingApp = proc;
10322                        mLaunchingProviders.add(cpr);
10323                    } finally {
10324                        Binder.restoreCallingIdentity(origId);
10325                    }
10326                }
10327
10328                checkTime(startTime, "getContentProviderImpl: updating data structures");
10329
10330                // Make sure the provider is published (the same provider class
10331                // may be published under multiple names).
10332                if (firstClass) {
10333                    mProviderMap.putProviderByClass(comp, cpr);
10334                }
10335
10336                mProviderMap.putProviderByName(name, cpr);
10337                conn = incProviderCountLocked(r, cpr, token, stable);
10338                if (conn != null) {
10339                    conn.waiting = true;
10340                }
10341            }
10342            checkTime(startTime, "getContentProviderImpl: done!");
10343        }
10344
10345        // Wait for the provider to be published...
10346        synchronized (cpr) {
10347            while (cpr.provider == null) {
10348                if (cpr.launchingApp == null) {
10349                    Slog.w(TAG, "Unable to launch app "
10350                            + cpi.applicationInfo.packageName + "/"
10351                            + cpi.applicationInfo.uid + " for provider "
10352                            + name + ": launching app became null");
10353                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10354                            UserHandle.getUserId(cpi.applicationInfo.uid),
10355                            cpi.applicationInfo.packageName,
10356                            cpi.applicationInfo.uid, name);
10357                    return null;
10358                }
10359                try {
10360                    if (DEBUG_MU) Slog.v(TAG_MU,
10361                            "Waiting to start provider " + cpr
10362                            + " launchingApp=" + cpr.launchingApp);
10363                    if (conn != null) {
10364                        conn.waiting = true;
10365                    }
10366                    cpr.wait();
10367                } catch (InterruptedException ex) {
10368                } finally {
10369                    if (conn != null) {
10370                        conn.waiting = false;
10371                    }
10372                }
10373            }
10374        }
10375        return cpr != null ? cpr.newHolder(conn) : null;
10376    }
10377
10378    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10379            ProcessRecord r, final int userId) {
10380        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10381                cpi.packageName, r.userId)) {
10382
10383            final boolean callerForeground = r != null ? r.setSchedGroup
10384                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10385
10386            // Show a permission review UI only for starting from a foreground app
10387            if (!callerForeground) {
10388                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10389                        + cpi.packageName + " requires a permissions review");
10390                return false;
10391            }
10392
10393            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10394            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10395                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10396            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10397
10398            if (DEBUG_PERMISSIONS_REVIEW) {
10399                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10400                        + "for package " + cpi.packageName);
10401            }
10402
10403            final UserHandle userHandle = new UserHandle(userId);
10404            mHandler.post(new Runnable() {
10405                @Override
10406                public void run() {
10407                    mContext.startActivityAsUser(intent, userHandle);
10408                }
10409            });
10410
10411            return false;
10412        }
10413
10414        return true;
10415    }
10416
10417    PackageManagerInternal getPackageManagerInternalLocked() {
10418        if (mPackageManagerInt == null) {
10419            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10420        }
10421        return mPackageManagerInt;
10422    }
10423
10424    @Override
10425    public final ContentProviderHolder getContentProvider(
10426            IApplicationThread caller, String name, int userId, boolean stable) {
10427        enforceNotIsolatedCaller("getContentProvider");
10428        if (caller == null) {
10429            String msg = "null IApplicationThread when getting content provider "
10430                    + name;
10431            Slog.w(TAG, msg);
10432            throw new SecurityException(msg);
10433        }
10434        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10435        // with cross-user grant.
10436        return getContentProviderImpl(caller, name, null, stable, userId);
10437    }
10438
10439    public ContentProviderHolder getContentProviderExternal(
10440            String name, int userId, IBinder token) {
10441        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10442            "Do not have permission in call getContentProviderExternal()");
10443        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10444                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10445        return getContentProviderExternalUnchecked(name, token, userId);
10446    }
10447
10448    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10449            IBinder token, int userId) {
10450        return getContentProviderImpl(null, name, token, true, userId);
10451    }
10452
10453    /**
10454     * Drop a content provider from a ProcessRecord's bookkeeping
10455     */
10456    public void removeContentProvider(IBinder connection, boolean stable) {
10457        enforceNotIsolatedCaller("removeContentProvider");
10458        long ident = Binder.clearCallingIdentity();
10459        try {
10460            synchronized (this) {
10461                ContentProviderConnection conn;
10462                try {
10463                    conn = (ContentProviderConnection)connection;
10464                } catch (ClassCastException e) {
10465                    String msg ="removeContentProvider: " + connection
10466                            + " not a ContentProviderConnection";
10467                    Slog.w(TAG, msg);
10468                    throw new IllegalArgumentException(msg);
10469                }
10470                if (conn == null) {
10471                    throw new NullPointerException("connection is null");
10472                }
10473                if (decProviderCountLocked(conn, null, null, stable)) {
10474                    updateOomAdjLocked();
10475                }
10476            }
10477        } finally {
10478            Binder.restoreCallingIdentity(ident);
10479        }
10480    }
10481
10482    public void removeContentProviderExternal(String name, IBinder token) {
10483        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10484            "Do not have permission in call removeContentProviderExternal()");
10485        int userId = UserHandle.getCallingUserId();
10486        long ident = Binder.clearCallingIdentity();
10487        try {
10488            removeContentProviderExternalUnchecked(name, token, userId);
10489        } finally {
10490            Binder.restoreCallingIdentity(ident);
10491        }
10492    }
10493
10494    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10495        synchronized (this) {
10496            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10497            if(cpr == null) {
10498                //remove from mProvidersByClass
10499                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10500                return;
10501            }
10502
10503            //update content provider record entry info
10504            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10505            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10506            if (localCpr.hasExternalProcessHandles()) {
10507                if (localCpr.removeExternalProcessHandleLocked(token)) {
10508                    updateOomAdjLocked();
10509                } else {
10510                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10511                            + " with no external reference for token: "
10512                            + token + ".");
10513                }
10514            } else {
10515                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10516                        + " with no external references.");
10517            }
10518        }
10519    }
10520
10521    public final void publishContentProviders(IApplicationThread caller,
10522            List<ContentProviderHolder> providers) {
10523        if (providers == null) {
10524            return;
10525        }
10526
10527        enforceNotIsolatedCaller("publishContentProviders");
10528        synchronized (this) {
10529            final ProcessRecord r = getRecordForAppLocked(caller);
10530            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10531            if (r == null) {
10532                throw new SecurityException(
10533                        "Unable to find app for caller " + caller
10534                      + " (pid=" + Binder.getCallingPid()
10535                      + ") when publishing content providers");
10536            }
10537
10538            final long origId = Binder.clearCallingIdentity();
10539
10540            final int N = providers.size();
10541            for (int i = 0; i < N; i++) {
10542                ContentProviderHolder src = providers.get(i);
10543                if (src == null || src.info == null || src.provider == null) {
10544                    continue;
10545                }
10546                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10547                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10548                if (dst != null) {
10549                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10550                    mProviderMap.putProviderByClass(comp, dst);
10551                    String names[] = dst.info.authority.split(";");
10552                    for (int j = 0; j < names.length; j++) {
10553                        mProviderMap.putProviderByName(names[j], dst);
10554                    }
10555
10556                    int launchingCount = mLaunchingProviders.size();
10557                    int j;
10558                    boolean wasInLaunchingProviders = false;
10559                    for (j = 0; j < launchingCount; j++) {
10560                        if (mLaunchingProviders.get(j) == dst) {
10561                            mLaunchingProviders.remove(j);
10562                            wasInLaunchingProviders = true;
10563                            j--;
10564                            launchingCount--;
10565                        }
10566                    }
10567                    if (wasInLaunchingProviders) {
10568                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10569                    }
10570                    synchronized (dst) {
10571                        dst.provider = src.provider;
10572                        dst.proc = r;
10573                        dst.notifyAll();
10574                    }
10575                    updateOomAdjLocked(r);
10576                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10577                            src.info.authority);
10578                }
10579            }
10580
10581            Binder.restoreCallingIdentity(origId);
10582        }
10583    }
10584
10585    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10586        ContentProviderConnection conn;
10587        try {
10588            conn = (ContentProviderConnection)connection;
10589        } catch (ClassCastException e) {
10590            String msg ="refContentProvider: " + connection
10591                    + " not a ContentProviderConnection";
10592            Slog.w(TAG, msg);
10593            throw new IllegalArgumentException(msg);
10594        }
10595        if (conn == null) {
10596            throw new NullPointerException("connection is null");
10597        }
10598
10599        synchronized (this) {
10600            if (stable > 0) {
10601                conn.numStableIncs += stable;
10602            }
10603            stable = conn.stableCount + stable;
10604            if (stable < 0) {
10605                throw new IllegalStateException("stableCount < 0: " + stable);
10606            }
10607
10608            if (unstable > 0) {
10609                conn.numUnstableIncs += unstable;
10610            }
10611            unstable = conn.unstableCount + unstable;
10612            if (unstable < 0) {
10613                throw new IllegalStateException("unstableCount < 0: " + unstable);
10614            }
10615
10616            if ((stable+unstable) <= 0) {
10617                throw new IllegalStateException("ref counts can't go to zero here: stable="
10618                        + stable + " unstable=" + unstable);
10619            }
10620            conn.stableCount = stable;
10621            conn.unstableCount = unstable;
10622            return !conn.dead;
10623        }
10624    }
10625
10626    public void unstableProviderDied(IBinder connection) {
10627        ContentProviderConnection conn;
10628        try {
10629            conn = (ContentProviderConnection)connection;
10630        } catch (ClassCastException e) {
10631            String msg ="refContentProvider: " + connection
10632                    + " not a ContentProviderConnection";
10633            Slog.w(TAG, msg);
10634            throw new IllegalArgumentException(msg);
10635        }
10636        if (conn == null) {
10637            throw new NullPointerException("connection is null");
10638        }
10639
10640        // Safely retrieve the content provider associated with the connection.
10641        IContentProvider provider;
10642        synchronized (this) {
10643            provider = conn.provider.provider;
10644        }
10645
10646        if (provider == null) {
10647            // Um, yeah, we're way ahead of you.
10648            return;
10649        }
10650
10651        // Make sure the caller is being honest with us.
10652        if (provider.asBinder().pingBinder()) {
10653            // Er, no, still looks good to us.
10654            synchronized (this) {
10655                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10656                        + " says " + conn + " died, but we don't agree");
10657                return;
10658            }
10659        }
10660
10661        // Well look at that!  It's dead!
10662        synchronized (this) {
10663            if (conn.provider.provider != provider) {
10664                // But something changed...  good enough.
10665                return;
10666            }
10667
10668            ProcessRecord proc = conn.provider.proc;
10669            if (proc == null || proc.thread == null) {
10670                // Seems like the process is already cleaned up.
10671                return;
10672            }
10673
10674            // As far as we're concerned, this is just like receiving a
10675            // death notification...  just a bit prematurely.
10676            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10677                    + ") early provider death");
10678            final long ident = Binder.clearCallingIdentity();
10679            try {
10680                appDiedLocked(proc);
10681            } finally {
10682                Binder.restoreCallingIdentity(ident);
10683            }
10684        }
10685    }
10686
10687    @Override
10688    public void appNotRespondingViaProvider(IBinder connection) {
10689        enforceCallingPermission(
10690                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10691
10692        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10693        if (conn == null) {
10694            Slog.w(TAG, "ContentProviderConnection is null");
10695            return;
10696        }
10697
10698        final ProcessRecord host = conn.provider.proc;
10699        if (host == null) {
10700            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10701            return;
10702        }
10703
10704        final long token = Binder.clearCallingIdentity();
10705        try {
10706            appNotResponding(host, null, null, false, "ContentProvider not responding");
10707        } finally {
10708            Binder.restoreCallingIdentity(token);
10709        }
10710    }
10711
10712    public final void installSystemProviders() {
10713        List<ProviderInfo> providers;
10714        synchronized (this) {
10715            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10716            providers = generateApplicationProvidersLocked(app);
10717            if (providers != null) {
10718                for (int i=providers.size()-1; i>=0; i--) {
10719                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10720                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10721                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10722                                + ": not system .apk");
10723                        providers.remove(i);
10724                    }
10725                }
10726            }
10727        }
10728        if (providers != null) {
10729            mSystemThread.installSystemProviders(providers);
10730        }
10731
10732        mCoreSettingsObserver = new CoreSettingsObserver(this);
10733
10734        //mUsageStatsService.monitorPackages();
10735    }
10736
10737    /**
10738     * Allows apps to retrieve the MIME type of a URI.
10739     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10740     * users, then it does not need permission to access the ContentProvider.
10741     * Either, it needs cross-user uri grants.
10742     *
10743     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10744     *
10745     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10746     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10747     */
10748    public String getProviderMimeType(Uri uri, int userId) {
10749        enforceNotIsolatedCaller("getProviderMimeType");
10750        final String name = uri.getAuthority();
10751        int callingUid = Binder.getCallingUid();
10752        int callingPid = Binder.getCallingPid();
10753        long ident = 0;
10754        boolean clearedIdentity = false;
10755        synchronized (this) {
10756            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10757        }
10758        if (canClearIdentity(callingPid, callingUid, userId)) {
10759            clearedIdentity = true;
10760            ident = Binder.clearCallingIdentity();
10761        }
10762        ContentProviderHolder holder = null;
10763        try {
10764            holder = getContentProviderExternalUnchecked(name, null, userId);
10765            if (holder != null) {
10766                return holder.provider.getType(uri);
10767            }
10768        } catch (RemoteException e) {
10769            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10770            return null;
10771        } finally {
10772            // We need to clear the identity to call removeContentProviderExternalUnchecked
10773            if (!clearedIdentity) {
10774                ident = Binder.clearCallingIdentity();
10775            }
10776            try {
10777                if (holder != null) {
10778                    removeContentProviderExternalUnchecked(name, null, userId);
10779                }
10780            } finally {
10781                Binder.restoreCallingIdentity(ident);
10782            }
10783        }
10784
10785        return null;
10786    }
10787
10788    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10789        if (UserHandle.getUserId(callingUid) == userId) {
10790            return true;
10791        }
10792        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10793                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10794                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10795                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10796                return true;
10797        }
10798        return false;
10799    }
10800
10801    // =========================================================
10802    // GLOBAL MANAGEMENT
10803    // =========================================================
10804
10805    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10806            boolean isolated, int isolatedUid) {
10807        String proc = customProcess != null ? customProcess : info.processName;
10808        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10809        final int userId = UserHandle.getUserId(info.uid);
10810        int uid = info.uid;
10811        if (isolated) {
10812            if (isolatedUid == 0) {
10813                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10814                while (true) {
10815                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10816                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10817                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10818                    }
10819                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10820                    mNextIsolatedProcessUid++;
10821                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10822                        // No process for this uid, use it.
10823                        break;
10824                    }
10825                    stepsLeft--;
10826                    if (stepsLeft <= 0) {
10827                        return null;
10828                    }
10829                }
10830            } else {
10831                // Special case for startIsolatedProcess (internal only), where
10832                // the uid of the isolated process is specified by the caller.
10833                uid = isolatedUid;
10834            }
10835        }
10836        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10837        if (!mBooted && !mBooting
10838                && userId == UserHandle.USER_SYSTEM
10839                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10840            r.persistent = true;
10841        }
10842        addProcessNameLocked(r);
10843        return r;
10844    }
10845
10846    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10847            String abiOverride) {
10848        ProcessRecord app;
10849        if (!isolated) {
10850            app = getProcessRecordLocked(info.processName, info.uid, true);
10851        } else {
10852            app = null;
10853        }
10854
10855        if (app == null) {
10856            app = newProcessRecordLocked(info, null, isolated, 0);
10857            updateLruProcessLocked(app, false, null);
10858            updateOomAdjLocked();
10859        }
10860
10861        // This package really, really can not be stopped.
10862        try {
10863            AppGlobals.getPackageManager().setPackageStoppedState(
10864                    info.packageName, false, UserHandle.getUserId(app.uid));
10865        } catch (RemoteException e) {
10866        } catch (IllegalArgumentException e) {
10867            Slog.w(TAG, "Failed trying to unstop package "
10868                    + info.packageName + ": " + e);
10869        }
10870
10871        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10872            app.persistent = true;
10873            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10874        }
10875        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10876            mPersistentStartingProcesses.add(app);
10877            startProcessLocked(app, "added application", app.processName, abiOverride,
10878                    null /* entryPoint */, null /* entryPointArgs */);
10879        }
10880
10881        return app;
10882    }
10883
10884    public void unhandledBack() {
10885        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10886                "unhandledBack()");
10887
10888        synchronized(this) {
10889            final long origId = Binder.clearCallingIdentity();
10890            try {
10891                getFocusedStack().unhandledBackLocked();
10892            } finally {
10893                Binder.restoreCallingIdentity(origId);
10894            }
10895        }
10896    }
10897
10898    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10899        enforceNotIsolatedCaller("openContentUri");
10900        final int userId = UserHandle.getCallingUserId();
10901        String name = uri.getAuthority();
10902        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10903        ParcelFileDescriptor pfd = null;
10904        if (cph != null) {
10905            // We record the binder invoker's uid in thread-local storage before
10906            // going to the content provider to open the file.  Later, in the code
10907            // that handles all permissions checks, we look for this uid and use
10908            // that rather than the Activity Manager's own uid.  The effect is that
10909            // we do the check against the caller's permissions even though it looks
10910            // to the content provider like the Activity Manager itself is making
10911            // the request.
10912            Binder token = new Binder();
10913            sCallerIdentity.set(new Identity(
10914                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10915            try {
10916                pfd = cph.provider.openFile(null, uri, "r", null, token);
10917            } catch (FileNotFoundException e) {
10918                // do nothing; pfd will be returned null
10919            } finally {
10920                // Ensure that whatever happens, we clean up the identity state
10921                sCallerIdentity.remove();
10922                // Ensure we're done with the provider.
10923                removeContentProviderExternalUnchecked(name, null, userId);
10924            }
10925        } else {
10926            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10927        }
10928        return pfd;
10929    }
10930
10931    // Actually is sleeping or shutting down or whatever else in the future
10932    // is an inactive state.
10933    public boolean isSleepingOrShuttingDown() {
10934        return isSleeping() || mShuttingDown;
10935    }
10936
10937    public boolean isSleeping() {
10938        return mSleeping;
10939    }
10940
10941    void onWakefulnessChanged(int wakefulness) {
10942        synchronized(this) {
10943            mWakefulness = wakefulness;
10944            updateSleepIfNeededLocked();
10945        }
10946    }
10947
10948    void finishRunningVoiceLocked() {
10949        if (mRunningVoice != null) {
10950            mRunningVoice = null;
10951            mVoiceWakeLock.release();
10952            updateSleepIfNeededLocked();
10953        }
10954    }
10955
10956    void startTimeTrackingFocusedActivityLocked() {
10957        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10958            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10959        }
10960    }
10961
10962    void updateSleepIfNeededLocked() {
10963        if (mSleeping && !shouldSleepLocked()) {
10964            mSleeping = false;
10965            startTimeTrackingFocusedActivityLocked();
10966            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10967            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10968            updateOomAdjLocked();
10969        } else if (!mSleeping && shouldSleepLocked()) {
10970            mSleeping = true;
10971            if (mCurAppTimeTracker != null) {
10972                mCurAppTimeTracker.stop();
10973            }
10974            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10975            mStackSupervisor.goingToSleepLocked();
10976            updateOomAdjLocked();
10977
10978            // Initialize the wake times of all processes.
10979            checkExcessivePowerUsageLocked(false);
10980            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10981            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10982            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10983        }
10984    }
10985
10986    private boolean shouldSleepLocked() {
10987        // Resume applications while running a voice interactor.
10988        if (mRunningVoice != null) {
10989            return false;
10990        }
10991
10992        // TODO: Transform the lock screen state into a sleep token instead.
10993        switch (mWakefulness) {
10994            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10995            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10996            case PowerManagerInternal.WAKEFULNESS_DOZING:
10997                // Pause applications whenever the lock screen is shown or any sleep
10998                // tokens have been acquired.
10999                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11000            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11001            default:
11002                // If we're asleep then pause applications unconditionally.
11003                return true;
11004        }
11005    }
11006
11007    /** Pokes the task persister. */
11008    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11009        if (task != null && task.stack != null && task.stack.isHomeStack()) {
11010            // Never persist the home stack.
11011            return;
11012        }
11013        mTaskPersister.wakeup(task, flush);
11014    }
11015
11016    /** Notifies all listeners when the task stack has changed. */
11017    void notifyTaskStackChangedLocked() {
11018        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11019        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11020        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11021        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11022    }
11023
11024    @Override
11025    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11026        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11027    }
11028
11029    @Override
11030    public boolean shutdown(int timeout) {
11031        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11032                != PackageManager.PERMISSION_GRANTED) {
11033            throw new SecurityException("Requires permission "
11034                    + android.Manifest.permission.SHUTDOWN);
11035        }
11036
11037        boolean timedout = false;
11038
11039        synchronized(this) {
11040            mShuttingDown = true;
11041            updateEventDispatchingLocked();
11042            timedout = mStackSupervisor.shutdownLocked(timeout);
11043        }
11044
11045        mAppOpsService.shutdown();
11046        if (mUsageStatsService != null) {
11047            mUsageStatsService.prepareShutdown();
11048        }
11049        mBatteryStatsService.shutdown();
11050        synchronized (this) {
11051            mProcessStats.shutdownLocked();
11052            notifyTaskPersisterLocked(null, true);
11053        }
11054
11055        return timedout;
11056    }
11057
11058    public final void activitySlept(IBinder token) {
11059        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11060
11061        final long origId = Binder.clearCallingIdentity();
11062
11063        synchronized (this) {
11064            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11065            if (r != null) {
11066                mStackSupervisor.activitySleptLocked(r);
11067            }
11068        }
11069
11070        Binder.restoreCallingIdentity(origId);
11071    }
11072
11073    private String lockScreenShownToString() {
11074        switch (mLockScreenShown) {
11075            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11076            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11077            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11078            default: return "Unknown=" + mLockScreenShown;
11079        }
11080    }
11081
11082    void logLockScreen(String msg) {
11083        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11084                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11085                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11086                + " mSleeping=" + mSleeping);
11087    }
11088
11089    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11090        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11091        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11092            boolean wasRunningVoice = mRunningVoice != null;
11093            mRunningVoice = session;
11094            if (!wasRunningVoice) {
11095                mVoiceWakeLock.acquire();
11096                updateSleepIfNeededLocked();
11097            }
11098        }
11099    }
11100
11101    private void updateEventDispatchingLocked() {
11102        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11103    }
11104
11105    public void setLockScreenShown(boolean shown) {
11106        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11107                != PackageManager.PERMISSION_GRANTED) {
11108            throw new SecurityException("Requires permission "
11109                    + android.Manifest.permission.DEVICE_POWER);
11110        }
11111
11112        synchronized(this) {
11113            long ident = Binder.clearCallingIdentity();
11114            try {
11115                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11116                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11117                updateSleepIfNeededLocked();
11118            } finally {
11119                Binder.restoreCallingIdentity(ident);
11120            }
11121        }
11122    }
11123
11124    @Override
11125    public void stopAppSwitches() {
11126        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11127                != PackageManager.PERMISSION_GRANTED) {
11128            throw new SecurityException("viewquires permission "
11129                    + android.Manifest.permission.STOP_APP_SWITCHES);
11130        }
11131
11132        synchronized(this) {
11133            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11134                    + APP_SWITCH_DELAY_TIME;
11135            mDidAppSwitch = false;
11136            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11137            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11138            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11139        }
11140    }
11141
11142    public void resumeAppSwitches() {
11143        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11144                != PackageManager.PERMISSION_GRANTED) {
11145            throw new SecurityException("Requires permission "
11146                    + android.Manifest.permission.STOP_APP_SWITCHES);
11147        }
11148
11149        synchronized(this) {
11150            // Note that we don't execute any pending app switches... we will
11151            // let those wait until either the timeout, or the next start
11152            // activity request.
11153            mAppSwitchesAllowedTime = 0;
11154        }
11155    }
11156
11157    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11158            int callingPid, int callingUid, String name) {
11159        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11160            return true;
11161        }
11162
11163        int perm = checkComponentPermission(
11164                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11165                sourceUid, -1, true);
11166        if (perm == PackageManager.PERMISSION_GRANTED) {
11167            return true;
11168        }
11169
11170        // If the actual IPC caller is different from the logical source, then
11171        // also see if they are allowed to control app switches.
11172        if (callingUid != -1 && callingUid != sourceUid) {
11173            perm = checkComponentPermission(
11174                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11175                    callingUid, -1, true);
11176            if (perm == PackageManager.PERMISSION_GRANTED) {
11177                return true;
11178            }
11179        }
11180
11181        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11182        return false;
11183    }
11184
11185    public void setDebugApp(String packageName, boolean waitForDebugger,
11186            boolean persistent) {
11187        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11188                "setDebugApp()");
11189
11190        long ident = Binder.clearCallingIdentity();
11191        try {
11192            // Note that this is not really thread safe if there are multiple
11193            // callers into it at the same time, but that's not a situation we
11194            // care about.
11195            if (persistent) {
11196                final ContentResolver resolver = mContext.getContentResolver();
11197                Settings.Global.putString(
11198                    resolver, Settings.Global.DEBUG_APP,
11199                    packageName);
11200                Settings.Global.putInt(
11201                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11202                    waitForDebugger ? 1 : 0);
11203            }
11204
11205            synchronized (this) {
11206                if (!persistent) {
11207                    mOrigDebugApp = mDebugApp;
11208                    mOrigWaitForDebugger = mWaitForDebugger;
11209                }
11210                mDebugApp = packageName;
11211                mWaitForDebugger = waitForDebugger;
11212                mDebugTransient = !persistent;
11213                if (packageName != null) {
11214                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11215                            false, UserHandle.USER_ALL, "set debug app");
11216                }
11217            }
11218        } finally {
11219            Binder.restoreCallingIdentity(ident);
11220        }
11221    }
11222
11223    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11224        synchronized (this) {
11225            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11226            if (!isDebuggable) {
11227                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11228                    throw new SecurityException("Process not debuggable: " + app.packageName);
11229                }
11230            }
11231
11232            mTrackAllocationApp = processName;
11233        }
11234    }
11235
11236    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11237        synchronized (this) {
11238            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11239            if (!isDebuggable) {
11240                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11241                    throw new SecurityException("Process not debuggable: " + app.packageName);
11242                }
11243            }
11244            mProfileApp = processName;
11245            mProfileFile = profilerInfo.profileFile;
11246            if (mProfileFd != null) {
11247                try {
11248                    mProfileFd.close();
11249                } catch (IOException e) {
11250                }
11251                mProfileFd = null;
11252            }
11253            mProfileFd = profilerInfo.profileFd;
11254            mSamplingInterval = profilerInfo.samplingInterval;
11255            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11256            mProfileType = 0;
11257        }
11258    }
11259
11260    @Override
11261    public void setAlwaysFinish(boolean enabled) {
11262        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11263                "setAlwaysFinish()");
11264
11265        Settings.Global.putInt(
11266                mContext.getContentResolver(),
11267                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11268
11269        synchronized (this) {
11270            mAlwaysFinishActivities = enabled;
11271        }
11272    }
11273
11274    @Override
11275    public void setActivityController(IActivityController controller) {
11276        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11277                "setActivityController()");
11278        synchronized (this) {
11279            mController = controller;
11280            Watchdog.getInstance().setActivityController(controller);
11281        }
11282    }
11283
11284    @Override
11285    public void setUserIsMonkey(boolean userIsMonkey) {
11286        synchronized (this) {
11287            synchronized (mPidsSelfLocked) {
11288                final int callingPid = Binder.getCallingPid();
11289                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11290                if (precessRecord == null) {
11291                    throw new SecurityException("Unknown process: " + callingPid);
11292                }
11293                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11294                    throw new SecurityException("Only an instrumentation process "
11295                            + "with a UiAutomation can call setUserIsMonkey");
11296                }
11297            }
11298            mUserIsMonkey = userIsMonkey;
11299        }
11300    }
11301
11302    @Override
11303    public boolean isUserAMonkey() {
11304        synchronized (this) {
11305            // If there is a controller also implies the user is a monkey.
11306            return (mUserIsMonkey || mController != null);
11307        }
11308    }
11309
11310    public void requestBugReport(boolean progress) {
11311        final String service = progress ? "bugreportplus" : "bugreport";
11312        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11313        SystemProperties.set("ctl.start", service);
11314    }
11315
11316    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11317        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11318    }
11319
11320    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11321        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11322            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11323        }
11324        return KEY_DISPATCHING_TIMEOUT;
11325    }
11326
11327    @Override
11328    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11329        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11330                != PackageManager.PERMISSION_GRANTED) {
11331            throw new SecurityException("Requires permission "
11332                    + android.Manifest.permission.FILTER_EVENTS);
11333        }
11334        ProcessRecord proc;
11335        long timeout;
11336        synchronized (this) {
11337            synchronized (mPidsSelfLocked) {
11338                proc = mPidsSelfLocked.get(pid);
11339            }
11340            timeout = getInputDispatchingTimeoutLocked(proc);
11341        }
11342
11343        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11344            return -1;
11345        }
11346
11347        return timeout;
11348    }
11349
11350    /**
11351     * Handle input dispatching timeouts.
11352     * Returns whether input dispatching should be aborted or not.
11353     */
11354    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11355            final ActivityRecord activity, final ActivityRecord parent,
11356            final boolean aboveSystem, String reason) {
11357        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11358                != PackageManager.PERMISSION_GRANTED) {
11359            throw new SecurityException("Requires permission "
11360                    + android.Manifest.permission.FILTER_EVENTS);
11361        }
11362
11363        final String annotation;
11364        if (reason == null) {
11365            annotation = "Input dispatching timed out";
11366        } else {
11367            annotation = "Input dispatching timed out (" + reason + ")";
11368        }
11369
11370        if (proc != null) {
11371            synchronized (this) {
11372                if (proc.debugging) {
11373                    return false;
11374                }
11375
11376                if (mDidDexOpt) {
11377                    // Give more time since we were dexopting.
11378                    mDidDexOpt = false;
11379                    return false;
11380                }
11381
11382                if (proc.instrumentationClass != null) {
11383                    Bundle info = new Bundle();
11384                    info.putString("shortMsg", "keyDispatchingTimedOut");
11385                    info.putString("longMsg", annotation);
11386                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11387                    return true;
11388                }
11389            }
11390            mHandler.post(new Runnable() {
11391                @Override
11392                public void run() {
11393                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11394                }
11395            });
11396        }
11397
11398        return true;
11399    }
11400
11401    @Override
11402    public Bundle getAssistContextExtras(int requestType) {
11403        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11404                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11405        if (pae == null) {
11406            return null;
11407        }
11408        synchronized (pae) {
11409            while (!pae.haveResult) {
11410                try {
11411                    pae.wait();
11412                } catch (InterruptedException e) {
11413                }
11414            }
11415        }
11416        synchronized (this) {
11417            buildAssistBundleLocked(pae, pae.result);
11418            mPendingAssistExtras.remove(pae);
11419            mUiHandler.removeCallbacks(pae);
11420        }
11421        return pae.extras;
11422    }
11423
11424    @Override
11425    public boolean isAssistDataAllowedOnCurrentActivity() {
11426        int userId;
11427        synchronized (this) {
11428            userId = mUserController.getCurrentUserIdLocked();
11429            ActivityRecord activity = getFocusedStack().topActivity();
11430            if (activity == null) {
11431                return false;
11432            }
11433            userId = activity.userId;
11434        }
11435        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11436                Context.DEVICE_POLICY_SERVICE);
11437        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11438    }
11439
11440    @Override
11441    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11442        long ident = Binder.clearCallingIdentity();
11443        try {
11444            synchronized (this) {
11445                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11446                ActivityRecord top = getFocusedStack().topActivity();
11447                if (top != caller) {
11448                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11449                            + " is not current top " + top);
11450                    return false;
11451                }
11452                if (!top.nowVisible) {
11453                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11454                            + " is not visible");
11455                    return false;
11456                }
11457            }
11458            AssistUtils utils = new AssistUtils(mContext);
11459            return utils.showSessionForActiveService(args,
11460                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11461        } finally {
11462            Binder.restoreCallingIdentity(ident);
11463        }
11464    }
11465
11466    @Override
11467    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11468            IBinder activityToken) {
11469        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11470                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11471    }
11472
11473    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11474            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11475            long timeout) {
11476        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11477                "enqueueAssistContext()");
11478        synchronized (this) {
11479            ActivityRecord activity = getFocusedStack().topActivity();
11480            if (activity == null) {
11481                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11482                return null;
11483            }
11484            if (activity.app == null || activity.app.thread == null) {
11485                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11486                return null;
11487            }
11488            if (activityToken != null) {
11489                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11490                if (activity != caller) {
11491                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11492                            + " is not current top " + activity);
11493                    return null;
11494                }
11495            }
11496            PendingAssistExtras pae;
11497            Bundle extras = new Bundle();
11498            if (args != null) {
11499                extras.putAll(args);
11500            }
11501            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11502            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11503            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11504            try {
11505                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11506                        requestType);
11507                mPendingAssistExtras.add(pae);
11508                mUiHandler.postDelayed(pae, timeout);
11509            } catch (RemoteException e) {
11510                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11511                return null;
11512            }
11513            return pae;
11514        }
11515    }
11516
11517    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11518        IResultReceiver receiver;
11519        synchronized (this) {
11520            mPendingAssistExtras.remove(pae);
11521            receiver = pae.receiver;
11522        }
11523        if (receiver != null) {
11524            // Caller wants result sent back to them.
11525            try {
11526                pae.receiver.send(0, null);
11527            } catch (RemoteException e) {
11528            }
11529        }
11530    }
11531
11532    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11533        if (result != null) {
11534            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11535        }
11536        if (pae.hint != null) {
11537            pae.extras.putBoolean(pae.hint, true);
11538        }
11539    }
11540
11541    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11542            AssistContent content, Uri referrer) {
11543        PendingAssistExtras pae = (PendingAssistExtras)token;
11544        synchronized (pae) {
11545            pae.result = extras;
11546            pae.structure = structure;
11547            pae.content = content;
11548            if (referrer != null) {
11549                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11550            }
11551            pae.haveResult = true;
11552            pae.notifyAll();
11553            if (pae.intent == null && pae.receiver == null) {
11554                // Caller is just waiting for the result.
11555                return;
11556            }
11557        }
11558
11559        // We are now ready to launch the assist activity.
11560        IResultReceiver sendReceiver = null;
11561        Bundle sendBundle = null;
11562        synchronized (this) {
11563            buildAssistBundleLocked(pae, extras);
11564            boolean exists = mPendingAssistExtras.remove(pae);
11565            mUiHandler.removeCallbacks(pae);
11566            if (!exists) {
11567                // Timed out.
11568                return;
11569            }
11570            if ((sendReceiver=pae.receiver) != null) {
11571                // Caller wants result sent back to them.
11572                sendBundle = new Bundle();
11573                sendBundle.putBundle("data", pae.extras);
11574                sendBundle.putParcelable("structure", pae.structure);
11575                sendBundle.putParcelable("content", pae.content);
11576            }
11577        }
11578        if (sendReceiver != null) {
11579            try {
11580                sendReceiver.send(0, sendBundle);
11581            } catch (RemoteException e) {
11582            }
11583            return;
11584        }
11585
11586        long ident = Binder.clearCallingIdentity();
11587        try {
11588            pae.intent.replaceExtras(pae.extras);
11589            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11590                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11591                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11592            closeSystemDialogs("assist");
11593            try {
11594                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11595            } catch (ActivityNotFoundException e) {
11596                Slog.w(TAG, "No activity to handle assist action.", e);
11597            }
11598        } finally {
11599            Binder.restoreCallingIdentity(ident);
11600        }
11601    }
11602
11603    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11604            Bundle args) {
11605        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11606                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11607    }
11608
11609    public void registerProcessObserver(IProcessObserver observer) {
11610        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11611                "registerProcessObserver()");
11612        synchronized (this) {
11613            mProcessObservers.register(observer);
11614        }
11615    }
11616
11617    @Override
11618    public void unregisterProcessObserver(IProcessObserver observer) {
11619        synchronized (this) {
11620            mProcessObservers.unregister(observer);
11621        }
11622    }
11623
11624    @Override
11625    public void registerUidObserver(IUidObserver observer, int which) {
11626        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11627                "registerUidObserver()");
11628        synchronized (this) {
11629            mUidObservers.register(observer, which);
11630        }
11631    }
11632
11633    @Override
11634    public void unregisterUidObserver(IUidObserver observer) {
11635        synchronized (this) {
11636            mUidObservers.unregister(observer);
11637        }
11638    }
11639
11640    @Override
11641    public boolean convertFromTranslucent(IBinder token) {
11642        final long origId = Binder.clearCallingIdentity();
11643        try {
11644            synchronized (this) {
11645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11646                if (r == null) {
11647                    return false;
11648                }
11649                final boolean translucentChanged = r.changeWindowTranslucency(true);
11650                if (translucentChanged) {
11651                    r.task.stack.releaseBackgroundResources(r);
11652                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11653                }
11654                mWindowManager.setAppFullscreen(token, true);
11655                return translucentChanged;
11656            }
11657        } finally {
11658            Binder.restoreCallingIdentity(origId);
11659        }
11660    }
11661
11662    @Override
11663    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11664        final long origId = Binder.clearCallingIdentity();
11665        try {
11666            synchronized (this) {
11667                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11668                if (r == null) {
11669                    return false;
11670                }
11671                int index = r.task.mActivities.lastIndexOf(r);
11672                if (index > 0) {
11673                    ActivityRecord under = r.task.mActivities.get(index - 1);
11674                    under.returningOptions = options;
11675                }
11676                final boolean translucentChanged = r.changeWindowTranslucency(false);
11677                if (translucentChanged) {
11678                    r.task.stack.convertActivityToTranslucent(r);
11679                }
11680                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11681                mWindowManager.setAppFullscreen(token, false);
11682                return translucentChanged;
11683            }
11684        } finally {
11685            Binder.restoreCallingIdentity(origId);
11686        }
11687    }
11688
11689    @Override
11690    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11691        final long origId = Binder.clearCallingIdentity();
11692        try {
11693            synchronized (this) {
11694                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11695                if (r != null) {
11696                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11697                }
11698            }
11699            return false;
11700        } finally {
11701            Binder.restoreCallingIdentity(origId);
11702        }
11703    }
11704
11705    @Override
11706    public boolean isBackgroundVisibleBehind(IBinder token) {
11707        final long origId = Binder.clearCallingIdentity();
11708        try {
11709            synchronized (this) {
11710                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11711                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11712                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11713                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11714                return visible;
11715            }
11716        } finally {
11717            Binder.restoreCallingIdentity(origId);
11718        }
11719    }
11720
11721    @Override
11722    public ActivityOptions getActivityOptions(IBinder token) {
11723        final long origId = Binder.clearCallingIdentity();
11724        try {
11725            synchronized (this) {
11726                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11727                if (r != null) {
11728                    final ActivityOptions activityOptions = r.pendingOptions;
11729                    r.pendingOptions = null;
11730                    return activityOptions;
11731                }
11732                return null;
11733            }
11734        } finally {
11735            Binder.restoreCallingIdentity(origId);
11736        }
11737    }
11738
11739    @Override
11740    public void setImmersive(IBinder token, boolean immersive) {
11741        synchronized(this) {
11742            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11743            if (r == null) {
11744                throw new IllegalArgumentException();
11745            }
11746            r.immersive = immersive;
11747
11748            // update associated state if we're frontmost
11749            if (r == mFocusedActivity) {
11750                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11751                applyUpdateLockStateLocked(r);
11752            }
11753        }
11754    }
11755
11756    @Override
11757    public boolean isImmersive(IBinder token) {
11758        synchronized (this) {
11759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11760            if (r == null) {
11761                throw new IllegalArgumentException();
11762            }
11763            return r.immersive;
11764        }
11765    }
11766
11767    @Override
11768    public void setVrMode(IBinder token, boolean enabled) {
11769        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11770            throw new UnsupportedOperationException("VR mode not supported on this device!");
11771        }
11772
11773        synchronized(this) {
11774            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11775            if (r == null) {
11776                throw new IllegalArgumentException();
11777            }
11778            r.isVrActivity = enabled;
11779
11780            // Update associated state if this activity is currently focused
11781            if (r == mFocusedActivity) {
11782                applyUpdateVrModeLocked(r);
11783            }
11784        }
11785    }
11786
11787    public boolean isTopActivityImmersive() {
11788        enforceNotIsolatedCaller("startActivity");
11789        synchronized (this) {
11790            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11791            return (r != null) ? r.immersive : false;
11792        }
11793    }
11794
11795    @Override
11796    public boolean isTopOfTask(IBinder token) {
11797        synchronized (this) {
11798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11799            if (r == null) {
11800                throw new IllegalArgumentException();
11801            }
11802            return r.task.getTopActivity() == r;
11803        }
11804    }
11805
11806    public final void enterSafeMode() {
11807        synchronized(this) {
11808            // It only makes sense to do this before the system is ready
11809            // and started launching other packages.
11810            if (!mSystemReady) {
11811                try {
11812                    AppGlobals.getPackageManager().enterSafeMode();
11813                } catch (RemoteException e) {
11814                }
11815            }
11816
11817            mSafeMode = true;
11818        }
11819    }
11820
11821    public final void showSafeModeOverlay() {
11822        View v = LayoutInflater.from(mContext).inflate(
11823                com.android.internal.R.layout.safe_mode, null);
11824        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11825        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11826        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11827        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11828        lp.gravity = Gravity.BOTTOM | Gravity.START;
11829        lp.format = v.getBackground().getOpacity();
11830        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11831                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11832        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11833        ((WindowManager)mContext.getSystemService(
11834                Context.WINDOW_SERVICE)).addView(v, lp);
11835    }
11836
11837    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11838        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11839            return;
11840        }
11841        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11842        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11843        synchronized (stats) {
11844            if (mBatteryStatsService.isOnBattery()) {
11845                mBatteryStatsService.enforceCallingPermission();
11846                int MY_UID = Binder.getCallingUid();
11847                final int uid;
11848                if (sender == null) {
11849                    uid = sourceUid;
11850                } else {
11851                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11852                }
11853                BatteryStatsImpl.Uid.Pkg pkg =
11854                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11855                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11856                pkg.noteWakeupAlarmLocked(tag);
11857            }
11858        }
11859    }
11860
11861    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11862        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11863            return;
11864        }
11865        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11866        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11867        synchronized (stats) {
11868            mBatteryStatsService.enforceCallingPermission();
11869            int MY_UID = Binder.getCallingUid();
11870            final int uid;
11871            if (sender == null) {
11872                uid = sourceUid;
11873            } else {
11874                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11875            }
11876            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11877        }
11878    }
11879
11880    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11881        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11882            return;
11883        }
11884        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11885        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11886        synchronized (stats) {
11887            mBatteryStatsService.enforceCallingPermission();
11888            int MY_UID = Binder.getCallingUid();
11889            final int uid;
11890            if (sender == null) {
11891                uid = sourceUid;
11892            } else {
11893                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11894            }
11895            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11896        }
11897    }
11898
11899    public boolean killPids(int[] pids, String pReason, boolean secure) {
11900        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11901            throw new SecurityException("killPids only available to the system");
11902        }
11903        String reason = (pReason == null) ? "Unknown" : pReason;
11904        // XXX Note: don't acquire main activity lock here, because the window
11905        // manager calls in with its locks held.
11906
11907        boolean killed = false;
11908        synchronized (mPidsSelfLocked) {
11909            int worstType = 0;
11910            for (int i=0; i<pids.length; i++) {
11911                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11912                if (proc != null) {
11913                    int type = proc.setAdj;
11914                    if (type > worstType) {
11915                        worstType = type;
11916                    }
11917                }
11918            }
11919
11920            // If the worst oom_adj is somewhere in the cached proc LRU range,
11921            // then constrain it so we will kill all cached procs.
11922            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11923                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11924                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11925            }
11926
11927            // If this is not a secure call, don't let it kill processes that
11928            // are important.
11929            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11930                worstType = ProcessList.SERVICE_ADJ;
11931            }
11932
11933            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11934            for (int i=0; i<pids.length; i++) {
11935                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11936                if (proc == null) {
11937                    continue;
11938                }
11939                int adj = proc.setAdj;
11940                if (adj >= worstType && !proc.killedByAm) {
11941                    proc.kill(reason, true);
11942                    killed = true;
11943                }
11944            }
11945        }
11946        return killed;
11947    }
11948
11949    @Override
11950    public void killUid(int appId, int userId, String reason) {
11951        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11952        synchronized (this) {
11953            final long identity = Binder.clearCallingIdentity();
11954            try {
11955                killPackageProcessesLocked(null, appId, userId,
11956                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, true,
11957                        reason != null ? reason : "kill uid");
11958            } finally {
11959                Binder.restoreCallingIdentity(identity);
11960            }
11961        }
11962    }
11963
11964    @Override
11965    public boolean killProcessesBelowForeground(String reason) {
11966        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11967            throw new SecurityException("killProcessesBelowForeground() only available to system");
11968        }
11969
11970        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11971    }
11972
11973    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11974        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11975            throw new SecurityException("killProcessesBelowAdj() only available to system");
11976        }
11977
11978        boolean killed = false;
11979        synchronized (mPidsSelfLocked) {
11980            final int size = mPidsSelfLocked.size();
11981            for (int i = 0; i < size; i++) {
11982                final int pid = mPidsSelfLocked.keyAt(i);
11983                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11984                if (proc == null) continue;
11985
11986                final int adj = proc.setAdj;
11987                if (adj > belowAdj && !proc.killedByAm) {
11988                    proc.kill(reason, true);
11989                    killed = true;
11990                }
11991            }
11992        }
11993        return killed;
11994    }
11995
11996    @Override
11997    public void hang(final IBinder who, boolean allowRestart) {
11998        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11999                != PackageManager.PERMISSION_GRANTED) {
12000            throw new SecurityException("Requires permission "
12001                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12002        }
12003
12004        final IBinder.DeathRecipient death = new DeathRecipient() {
12005            @Override
12006            public void binderDied() {
12007                synchronized (this) {
12008                    notifyAll();
12009                }
12010            }
12011        };
12012
12013        try {
12014            who.linkToDeath(death, 0);
12015        } catch (RemoteException e) {
12016            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12017            return;
12018        }
12019
12020        synchronized (this) {
12021            Watchdog.getInstance().setAllowRestart(allowRestart);
12022            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12023            synchronized (death) {
12024                while (who.isBinderAlive()) {
12025                    try {
12026                        death.wait();
12027                    } catch (InterruptedException e) {
12028                    }
12029                }
12030            }
12031            Watchdog.getInstance().setAllowRestart(true);
12032        }
12033    }
12034
12035    @Override
12036    public void restart() {
12037        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12038                != PackageManager.PERMISSION_GRANTED) {
12039            throw new SecurityException("Requires permission "
12040                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12041        }
12042
12043        Log.i(TAG, "Sending shutdown broadcast...");
12044
12045        BroadcastReceiver br = new BroadcastReceiver() {
12046            @Override public void onReceive(Context context, Intent intent) {
12047                // Now the broadcast is done, finish up the low-level shutdown.
12048                Log.i(TAG, "Shutting down activity manager...");
12049                shutdown(10000);
12050                Log.i(TAG, "Shutdown complete, restarting!");
12051                Process.killProcess(Process.myPid());
12052                System.exit(10);
12053            }
12054        };
12055
12056        // First send the high-level shut down broadcast.
12057        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12058        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12059        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12060        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12061        mContext.sendOrderedBroadcastAsUser(intent,
12062                UserHandle.ALL, null, br, mHandler, 0, null, null);
12063        */
12064        br.onReceive(mContext, intent);
12065    }
12066
12067    private long getLowRamTimeSinceIdle(long now) {
12068        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12069    }
12070
12071    @Override
12072    public void performIdleMaintenance() {
12073        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12074                != PackageManager.PERMISSION_GRANTED) {
12075            throw new SecurityException("Requires permission "
12076                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12077        }
12078
12079        synchronized (this) {
12080            final long now = SystemClock.uptimeMillis();
12081            final long timeSinceLastIdle = now - mLastIdleTime;
12082            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12083            mLastIdleTime = now;
12084            mLowRamTimeSinceLastIdle = 0;
12085            if (mLowRamStartTime != 0) {
12086                mLowRamStartTime = now;
12087            }
12088
12089            StringBuilder sb = new StringBuilder(128);
12090            sb.append("Idle maintenance over ");
12091            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12092            sb.append(" low RAM for ");
12093            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12094            Slog.i(TAG, sb.toString());
12095
12096            // If at least 1/3 of our time since the last idle period has been spent
12097            // with RAM low, then we want to kill processes.
12098            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12099
12100            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12101                ProcessRecord proc = mLruProcesses.get(i);
12102                if (proc.notCachedSinceIdle) {
12103                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12104                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12105                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12106                        if (doKilling && proc.initialIdlePss != 0
12107                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12108                            sb = new StringBuilder(128);
12109                            sb.append("Kill");
12110                            sb.append(proc.processName);
12111                            sb.append(" in idle maint: pss=");
12112                            sb.append(proc.lastPss);
12113                            sb.append(", initialPss=");
12114                            sb.append(proc.initialIdlePss);
12115                            sb.append(", period=");
12116                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12117                            sb.append(", lowRamPeriod=");
12118                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12119                            Slog.wtfQuiet(TAG, sb.toString());
12120                            proc.kill("idle maint (pss " + proc.lastPss
12121                                    + " from " + proc.initialIdlePss + ")", true);
12122                        }
12123                    }
12124                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12125                    proc.notCachedSinceIdle = true;
12126                    proc.initialIdlePss = 0;
12127                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12128                            mTestPssMode, isSleeping(), now);
12129                }
12130            }
12131
12132            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12133            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12134        }
12135    }
12136
12137    private void retrieveSettings() {
12138        final ContentResolver resolver = mContext.getContentResolver();
12139        final boolean freeformWindowManagement =
12140                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
12141        final boolean supportsPictureInPicture =
12142                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12143
12144        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12145        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12146        final boolean alwaysFinishActivities =
12147                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12148        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12149        final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
12150        final boolean forceResizable = Settings.Global.getInt(
12151                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
12152        // Transfer any global setting for forcing RTL layout, into a System Property
12153        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12154
12155        final Configuration configuration = new Configuration();
12156        Settings.System.getConfiguration(resolver, configuration);
12157        if (forceRtl) {
12158            // This will take care of setting the correct layout direction flags
12159            configuration.setLayoutDirection(configuration.locale);
12160        }
12161
12162        synchronized (this) {
12163            mDebugApp = mOrigDebugApp = debugApp;
12164            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12165            mAlwaysFinishActivities = alwaysFinishActivities;
12166            mForceResizableActivities = forceResizable;
12167            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12168            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12169            // This happens before any activities are started, so we can
12170            // change mConfiguration in-place.
12171            updateConfigurationLocked(configuration, null, true);
12172            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12173                    "Initial config: " + mConfiguration);
12174
12175            // Load resources only after the current configuration has been set.
12176            final Resources res = mContext.getResources();
12177            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12178            mThumbnailWidth = res.getDimensionPixelSize(
12179                    com.android.internal.R.dimen.thumbnail_width);
12180            mThumbnailHeight = res.getDimensionPixelSize(
12181                    com.android.internal.R.dimen.thumbnail_height);
12182            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12183                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12184        }
12185    }
12186
12187    public boolean testIsSystemReady() {
12188        // no need to synchronize(this) just to read & return the value
12189        return mSystemReady;
12190    }
12191
12192    private static File getCalledPreBootReceiversFile() {
12193        File dataDir = Environment.getDataDirectory();
12194        File systemDir = new File(dataDir, "system");
12195        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12196        return fname;
12197    }
12198
12199    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12200        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12201        File file = getCalledPreBootReceiversFile();
12202        FileInputStream fis = null;
12203        try {
12204            fis = new FileInputStream(file);
12205            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12206            int fvers = dis.readInt();
12207            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12208                String vers = dis.readUTF();
12209                String codename = dis.readUTF();
12210                String build = dis.readUTF();
12211                if (android.os.Build.VERSION.RELEASE.equals(vers)
12212                        && android.os.Build.VERSION.CODENAME.equals(codename)
12213                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12214                    int num = dis.readInt();
12215                    while (num > 0) {
12216                        num--;
12217                        String pkg = dis.readUTF();
12218                        String cls = dis.readUTF();
12219                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12220                    }
12221                }
12222            }
12223        } catch (FileNotFoundException e) {
12224        } catch (IOException e) {
12225            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12226        } finally {
12227            if (fis != null) {
12228                try {
12229                    fis.close();
12230                } catch (IOException e) {
12231                }
12232            }
12233        }
12234        return lastDoneReceivers;
12235    }
12236
12237    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12238        File file = getCalledPreBootReceiversFile();
12239        FileOutputStream fos = null;
12240        DataOutputStream dos = null;
12241        try {
12242            fos = new FileOutputStream(file);
12243            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12244            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12245            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12246            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12247            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12248            dos.writeInt(list.size());
12249            for (int i=0; i<list.size(); i++) {
12250                dos.writeUTF(list.get(i).getPackageName());
12251                dos.writeUTF(list.get(i).getClassName());
12252            }
12253        } catch (IOException e) {
12254            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12255            file.delete();
12256        } finally {
12257            FileUtils.sync(fos);
12258            if (dos != null) {
12259                try {
12260                    dos.close();
12261                } catch (IOException e) {
12262                    // TODO Auto-generated catch block
12263                    e.printStackTrace();
12264                }
12265            }
12266        }
12267    }
12268
12269    final class PreBootContinuation extends IIntentReceiver.Stub {
12270        final Intent intent;
12271        final Runnable onFinishCallback;
12272        final ArrayList<ComponentName> doneReceivers;
12273        final List<ResolveInfo> ris;
12274        final int[] users;
12275        int lastRi = -1;
12276        int curRi = 0;
12277        int curUser = 0;
12278
12279        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12280                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12281            intent = _intent;
12282            onFinishCallback = _onFinishCallback;
12283            doneReceivers = _doneReceivers;
12284            ris = _ris;
12285            users = _users;
12286        }
12287
12288        void go() {
12289            if (lastRi != curRi) {
12290                ActivityInfo ai = ris.get(curRi).activityInfo;
12291                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12292                intent.setComponent(comp);
12293                doneReceivers.add(comp);
12294                lastRi = curRi;
12295                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12296                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12297            }
12298            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12299                    + " for user " + users[curUser]);
12300            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12301            broadcastIntentLocked(null, null, intent, null, this,
12302                    0, null, null, null, AppOpsManager.OP_NONE,
12303                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12304        }
12305
12306        public void performReceive(Intent intent, int resultCode,
12307                String data, Bundle extras, boolean ordered,
12308                boolean sticky, int sendingUser) {
12309            curUser++;
12310            if (curUser >= users.length) {
12311                curUser = 0;
12312                curRi++;
12313                if (curRi >= ris.size()) {
12314                    // All done sending broadcasts!
12315                    if (onFinishCallback != null) {
12316                        // The raw IIntentReceiver interface is called
12317                        // with the AM lock held, so redispatch to
12318                        // execute our code without the lock.
12319                        mHandler.post(onFinishCallback);
12320                    }
12321                    return;
12322                }
12323            }
12324            go();
12325        }
12326    }
12327
12328    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12329            ArrayList<ComponentName> doneReceivers) {
12330        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12331        List<ResolveInfo> ris = null;
12332        try {
12333            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12334                    intent, null, 0, UserHandle.USER_SYSTEM);
12335        } catch (RemoteException e) {
12336        }
12337        if (ris == null) {
12338            return false;
12339        }
12340        for (int i=ris.size()-1; i>=0; i--) {
12341            if ((ris.get(i).activityInfo.applicationInfo.flags
12342                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
12343                ris.remove(i);
12344            }
12345        }
12346        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12347
12348        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12349        for (int i=0; i<ris.size(); i++) {
12350            ActivityInfo ai = ris.get(i).activityInfo;
12351            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12352            if (lastDoneReceivers.contains(comp)) {
12353                // We already did the pre boot receiver for this app with the current
12354                // platform version, so don't do it again...
12355                ris.remove(i);
12356                i--;
12357                // ...however, do keep it as one that has been done, so we don't
12358                // forget about it when rewriting the file of last done receivers.
12359                doneReceivers.add(comp);
12360            }
12361        }
12362
12363        if (ris.size() <= 0) {
12364            return false;
12365        }
12366
12367        // TODO: can we still do this with per user encryption?
12368        final int[] users = mUserController.getUsers();
12369        if (users.length <= 0) {
12370            return false;
12371        }
12372
12373        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12374                ris, users);
12375        cont.go();
12376        return true;
12377    }
12378
12379    public void systemReady(final Runnable goingCallback) {
12380        synchronized(this) {
12381            if (mSystemReady) {
12382                // If we're done calling all the receivers, run the next "boot phase" passed in
12383                // by the SystemServer
12384                if (goingCallback != null) {
12385                    goingCallback.run();
12386                }
12387                return;
12388            }
12389
12390            mLocalDeviceIdleController
12391                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12392
12393            // Make sure we have the current profile info, since it is needed for
12394            // security checks.
12395            mUserController.updateCurrentProfileIdsLocked();
12396
12397            mRecentTasks.clear();
12398            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12399            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12400            mTaskPersister.startPersisting();
12401
12402            // Check to see if there are any update receivers to run.
12403            if (!mDidUpdate) {
12404                if (mWaitingUpdate) {
12405                    return;
12406                }
12407                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12408                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12409                    public void run() {
12410                        synchronized (ActivityManagerService.this) {
12411                            mDidUpdate = true;
12412                        }
12413                        showBootMessage(mContext.getText(
12414                                R.string.android_upgrading_complete),
12415                                false);
12416                        writeLastDonePreBootReceivers(doneReceivers);
12417                        systemReady(goingCallback);
12418                    }
12419                }, doneReceivers);
12420
12421                if (mWaitingUpdate) {
12422                    return;
12423                }
12424                mDidUpdate = true;
12425            }
12426
12427            mAppOpsService.systemReady();
12428            mSystemReady = true;
12429        }
12430
12431        ArrayList<ProcessRecord> procsToKill = null;
12432        synchronized(mPidsSelfLocked) {
12433            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12434                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12435                if (!isAllowedWhileBooting(proc.info)){
12436                    if (procsToKill == null) {
12437                        procsToKill = new ArrayList<ProcessRecord>();
12438                    }
12439                    procsToKill.add(proc);
12440                }
12441            }
12442        }
12443
12444        synchronized(this) {
12445            if (procsToKill != null) {
12446                for (int i=procsToKill.size()-1; i>=0; i--) {
12447                    ProcessRecord proc = procsToKill.get(i);
12448                    Slog.i(TAG, "Removing system update proc: " + proc);
12449                    removeProcessLocked(proc, true, false, "system update done");
12450                }
12451            }
12452
12453            // Now that we have cleaned up any update processes, we
12454            // are ready to start launching real processes and know that
12455            // we won't trample on them any more.
12456            mProcessesReady = true;
12457        }
12458
12459        Slog.i(TAG, "System now ready");
12460        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12461            SystemClock.uptimeMillis());
12462
12463        synchronized(this) {
12464            // Make sure we have no pre-ready processes sitting around.
12465
12466            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12467                ResolveInfo ri = mContext.getPackageManager()
12468                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12469                                STOCK_PM_FLAGS);
12470                CharSequence errorMsg = null;
12471                if (ri != null) {
12472                    ActivityInfo ai = ri.activityInfo;
12473                    ApplicationInfo app = ai.applicationInfo;
12474                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12475                        mTopAction = Intent.ACTION_FACTORY_TEST;
12476                        mTopData = null;
12477                        mTopComponent = new ComponentName(app.packageName,
12478                                ai.name);
12479                    } else {
12480                        errorMsg = mContext.getResources().getText(
12481                                com.android.internal.R.string.factorytest_not_system);
12482                    }
12483                } else {
12484                    errorMsg = mContext.getResources().getText(
12485                            com.android.internal.R.string.factorytest_no_action);
12486                }
12487                if (errorMsg != null) {
12488                    mTopAction = null;
12489                    mTopData = null;
12490                    mTopComponent = null;
12491                    Message msg = Message.obtain();
12492                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12493                    msg.getData().putCharSequence("msg", errorMsg);
12494                    mUiHandler.sendMessage(msg);
12495                }
12496            }
12497        }
12498
12499        retrieveSettings();
12500        final int currentUserId;
12501        synchronized (this) {
12502            currentUserId = mUserController.getCurrentUserIdLocked();
12503            readGrantedUriPermissionsLocked();
12504        }
12505
12506        if (goingCallback != null) goingCallback.run();
12507
12508
12509        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12510                Integer.toString(currentUserId), currentUserId);
12511        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12512                Integer.toString(currentUserId), currentUserId);
12513        mSystemServiceManager.startUser(currentUserId);
12514
12515        synchronized (this) {
12516            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12517                try {
12518                    List apps = AppGlobals.getPackageManager().
12519                        getPersistentApplications(STOCK_PM_FLAGS);
12520                    if (apps != null) {
12521                        int N = apps.size();
12522                        int i;
12523                        for (i=0; i<N; i++) {
12524                            ApplicationInfo info
12525                                = (ApplicationInfo)apps.get(i);
12526                            if (info != null &&
12527                                    !info.packageName.equals("android")) {
12528                                addAppLocked(info, false, null /* ABI override */);
12529                            }
12530                        }
12531                    }
12532                } catch (RemoteException ex) {
12533                    // pm is in same process, this will never happen.
12534                }
12535            }
12536
12537            // Start up initial activity.
12538            mBooting = true;
12539            // Enable home activity for system user, so that the system can always boot
12540            if (UserManager.isSplitSystemUser()) {
12541                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12542                try {
12543                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12544                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12545                            UserHandle.USER_SYSTEM);
12546                } catch (RemoteException e) {
12547                    e.rethrowAsRuntimeException();
12548                }
12549            }
12550            startHomeActivityLocked(currentUserId, "systemReady");
12551
12552            try {
12553                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12554                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12555                            + " data partition or your device will be unstable.");
12556                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12557                }
12558            } catch (RemoteException e) {
12559            }
12560
12561            if (!Build.isBuildConsistent()) {
12562                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12563                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12564            }
12565
12566            long ident = Binder.clearCallingIdentity();
12567            try {
12568                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12569                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12570                        | Intent.FLAG_RECEIVER_FOREGROUND);
12571                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12572                broadcastIntentLocked(null, null, intent,
12573                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12574                        null, false, false, MY_PID, Process.SYSTEM_UID,
12575                        currentUserId);
12576                intent = new Intent(Intent.ACTION_USER_STARTING);
12577                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12578                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12579                broadcastIntentLocked(null, null, intent,
12580                        null, new IIntentReceiver.Stub() {
12581                            @Override
12582                            public void performReceive(Intent intent, int resultCode, String data,
12583                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12584                                    throws RemoteException {
12585                            }
12586                        }, 0, null, null,
12587                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12588                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12589            } catch (Throwable t) {
12590                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12591            } finally {
12592                Binder.restoreCallingIdentity(ident);
12593            }
12594            mStackSupervisor.resumeTopActivitiesLocked();
12595            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12596        }
12597    }
12598
12599    private boolean makeAppCrashingLocked(ProcessRecord app,
12600            String shortMsg, String longMsg, String stackTrace) {
12601        app.crashing = true;
12602        app.crashingReport = generateProcessError(app,
12603                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12604        startAppProblemLocked(app);
12605        app.stopFreezingAllLocked();
12606        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12607    }
12608
12609    private void makeAppNotRespondingLocked(ProcessRecord app,
12610            String activity, String shortMsg, String longMsg) {
12611        app.notResponding = true;
12612        app.notRespondingReport = generateProcessError(app,
12613                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12614                activity, shortMsg, longMsg, null);
12615        startAppProblemLocked(app);
12616        app.stopFreezingAllLocked();
12617    }
12618
12619    /**
12620     * Generate a process error record, suitable for attachment to a ProcessRecord.
12621     *
12622     * @param app The ProcessRecord in which the error occurred.
12623     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12624     *                      ActivityManager.AppErrorStateInfo
12625     * @param activity The activity associated with the crash, if known.
12626     * @param shortMsg Short message describing the crash.
12627     * @param longMsg Long message describing the crash.
12628     * @param stackTrace Full crash stack trace, may be null.
12629     *
12630     * @return Returns a fully-formed AppErrorStateInfo record.
12631     */
12632    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12633            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12634        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12635
12636        report.condition = condition;
12637        report.processName = app.processName;
12638        report.pid = app.pid;
12639        report.uid = app.info.uid;
12640        report.tag = activity;
12641        report.shortMsg = shortMsg;
12642        report.longMsg = longMsg;
12643        report.stackTrace = stackTrace;
12644
12645        return report;
12646    }
12647
12648    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12649        synchronized (this) {
12650            app.crashing = false;
12651            app.crashingReport = null;
12652            app.notResponding = false;
12653            app.notRespondingReport = null;
12654            if (app.anrDialog == fromDialog) {
12655                app.anrDialog = null;
12656            }
12657            if (app.waitDialog == fromDialog) {
12658                app.waitDialog = null;
12659            }
12660            if (app.pid > 0 && app.pid != MY_PID) {
12661                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12662                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12663                app.kill("user request after error", true);
12664            }
12665        }
12666    }
12667
12668    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12669            String shortMsg, String longMsg, String stackTrace) {
12670        long now = SystemClock.uptimeMillis();
12671
12672        Long crashTime;
12673        if (!app.isolated) {
12674            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12675        } else {
12676            crashTime = null;
12677        }
12678        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12679            // This process loses!
12680            Slog.w(TAG, "Process " + app.info.processName
12681                    + " has crashed too many times: killing!");
12682            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12683                    app.userId, app.info.processName, app.uid);
12684            mStackSupervisor.handleAppCrashLocked(app);
12685            if (!app.persistent) {
12686                // We don't want to start this process again until the user
12687                // explicitly does so...  but for persistent process, we really
12688                // need to keep it running.  If a persistent process is actually
12689                // repeatedly crashing, then badness for everyone.
12690                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12691                        app.info.processName);
12692                if (!app.isolated) {
12693                    // XXX We don't have a way to mark isolated processes
12694                    // as bad, since they don't have a peristent identity.
12695                    mBadProcesses.put(app.info.processName, app.uid,
12696                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12697                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12698                }
12699                app.bad = true;
12700                app.removed = true;
12701                // Don't let services in this process be restarted and potentially
12702                // annoy the user repeatedly.  Unless it is persistent, since those
12703                // processes run critical code.
12704                removeProcessLocked(app, false, false, "crash");
12705                mStackSupervisor.resumeTopActivitiesLocked();
12706                return false;
12707            }
12708            mStackSupervisor.resumeTopActivitiesLocked();
12709        } else {
12710            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12711        }
12712
12713        // Bump up the crash count of any services currently running in the proc.
12714        for (int i=app.services.size()-1; i>=0; i--) {
12715            // Any services running in the application need to be placed
12716            // back in the pending list.
12717            ServiceRecord sr = app.services.valueAt(i);
12718            sr.crashCount++;
12719        }
12720
12721        // If the crashing process is what we consider to be the "home process" and it has been
12722        // replaced by a third-party app, clear the package preferred activities from packages
12723        // with a home activity running in the process to prevent a repeatedly crashing app
12724        // from blocking the user to manually clear the list.
12725        final ArrayList<ActivityRecord> activities = app.activities;
12726        if (app == mHomeProcess && activities.size() > 0
12727                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12728            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12729                final ActivityRecord r = activities.get(activityNdx);
12730                if (r.isHomeActivity()) {
12731                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12732                    try {
12733                        ActivityThread.getPackageManager()
12734                                .clearPackagePreferredActivities(r.packageName);
12735                    } catch (RemoteException c) {
12736                        // pm is in same process, this will never happen.
12737                    }
12738                }
12739            }
12740        }
12741
12742        if (!app.isolated) {
12743            // XXX Can't keep track of crash times for isolated processes,
12744            // because they don't have a perisistent identity.
12745            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12746        }
12747
12748        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12749        return true;
12750    }
12751
12752    void startAppProblemLocked(ProcessRecord app) {
12753        // If this app is not running under the current user, then we
12754        // can't give it a report button because that would require
12755        // launching the report UI under a different user.
12756        app.errorReportReceiver = null;
12757
12758        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12759            if (app.userId == userId) {
12760                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12761                        mContext, app.info.packageName, app.info.flags);
12762            }
12763        }
12764        skipCurrentReceiverLocked(app);
12765    }
12766
12767    void skipCurrentReceiverLocked(ProcessRecord app) {
12768        for (BroadcastQueue queue : mBroadcastQueues) {
12769            queue.skipCurrentReceiverLocked(app);
12770        }
12771    }
12772
12773    /**
12774     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12775     * The application process will exit immediately after this call returns.
12776     * @param app object of the crashing app, null for the system server
12777     * @param crashInfo describing the exception
12778     */
12779    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12780        ProcessRecord r = findAppProcess(app, "Crash");
12781        final String processName = app == null ? "system_server"
12782                : (r == null ? "unknown" : r.processName);
12783
12784        handleApplicationCrashInner("crash", r, processName, crashInfo);
12785    }
12786
12787    /* Native crash reporting uses this inner version because it needs to be somewhat
12788     * decoupled from the AM-managed cleanup lifecycle
12789     */
12790    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12791            ApplicationErrorReport.CrashInfo crashInfo) {
12792        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12793                UserHandle.getUserId(Binder.getCallingUid()), processName,
12794                r == null ? -1 : r.info.flags,
12795                crashInfo.exceptionClassName,
12796                crashInfo.exceptionMessage,
12797                crashInfo.throwFileName,
12798                crashInfo.throwLineNumber);
12799
12800        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12801
12802        crashApplication(r, crashInfo);
12803    }
12804
12805    public void handleApplicationStrictModeViolation(
12806            IBinder app,
12807            int violationMask,
12808            StrictMode.ViolationInfo info) {
12809        ProcessRecord r = findAppProcess(app, "StrictMode");
12810        if (r == null) {
12811            return;
12812        }
12813
12814        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12815            Integer stackFingerprint = info.hashCode();
12816            boolean logIt = true;
12817            synchronized (mAlreadyLoggedViolatedStacks) {
12818                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12819                    logIt = false;
12820                    // TODO: sub-sample into EventLog for these, with
12821                    // the info.durationMillis?  Then we'd get
12822                    // the relative pain numbers, without logging all
12823                    // the stack traces repeatedly.  We'd want to do
12824                    // likewise in the client code, which also does
12825                    // dup suppression, before the Binder call.
12826                } else {
12827                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12828                        mAlreadyLoggedViolatedStacks.clear();
12829                    }
12830                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12831                }
12832            }
12833            if (logIt) {
12834                logStrictModeViolationToDropBox(r, info);
12835            }
12836        }
12837
12838        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12839            AppErrorResult result = new AppErrorResult();
12840            synchronized (this) {
12841                final long origId = Binder.clearCallingIdentity();
12842
12843                Message msg = Message.obtain();
12844                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12845                HashMap<String, Object> data = new HashMap<String, Object>();
12846                data.put("result", result);
12847                data.put("app", r);
12848                data.put("violationMask", violationMask);
12849                data.put("info", info);
12850                msg.obj = data;
12851                mUiHandler.sendMessage(msg);
12852
12853                Binder.restoreCallingIdentity(origId);
12854            }
12855            int res = result.get();
12856            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12857        }
12858    }
12859
12860    // Depending on the policy in effect, there could be a bunch of
12861    // these in quick succession so we try to batch these together to
12862    // minimize disk writes, number of dropbox entries, and maximize
12863    // compression, by having more fewer, larger records.
12864    private void logStrictModeViolationToDropBox(
12865            ProcessRecord process,
12866            StrictMode.ViolationInfo info) {
12867        if (info == null) {
12868            return;
12869        }
12870        final boolean isSystemApp = process == null ||
12871                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12872                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12873        final String processName = process == null ? "unknown" : process.processName;
12874        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12875        final DropBoxManager dbox = (DropBoxManager)
12876                mContext.getSystemService(Context.DROPBOX_SERVICE);
12877
12878        // Exit early if the dropbox isn't configured to accept this report type.
12879        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12880
12881        boolean bufferWasEmpty;
12882        boolean needsFlush;
12883        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12884        synchronized (sb) {
12885            bufferWasEmpty = sb.length() == 0;
12886            appendDropBoxProcessHeaders(process, processName, sb);
12887            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12888            sb.append("System-App: ").append(isSystemApp).append("\n");
12889            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12890            if (info.violationNumThisLoop != 0) {
12891                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12892            }
12893            if (info.numAnimationsRunning != 0) {
12894                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12895            }
12896            if (info.broadcastIntentAction != null) {
12897                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12898            }
12899            if (info.durationMillis != -1) {
12900                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12901            }
12902            if (info.numInstances != -1) {
12903                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12904            }
12905            if (info.tags != null) {
12906                for (String tag : info.tags) {
12907                    sb.append("Span-Tag: ").append(tag).append("\n");
12908                }
12909            }
12910            sb.append("\n");
12911            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12912                sb.append(info.crashInfo.stackTrace);
12913                sb.append("\n");
12914            }
12915            if (info.message != null) {
12916                sb.append(info.message);
12917                sb.append("\n");
12918            }
12919
12920            // Only buffer up to ~64k.  Various logging bits truncate
12921            // things at 128k.
12922            needsFlush = (sb.length() > 64 * 1024);
12923        }
12924
12925        // Flush immediately if the buffer's grown too large, or this
12926        // is a non-system app.  Non-system apps are isolated with a
12927        // different tag & policy and not batched.
12928        //
12929        // Batching is useful during internal testing with
12930        // StrictMode settings turned up high.  Without batching,
12931        // thousands of separate files could be created on boot.
12932        if (!isSystemApp || needsFlush) {
12933            new Thread("Error dump: " + dropboxTag) {
12934                @Override
12935                public void run() {
12936                    String report;
12937                    synchronized (sb) {
12938                        report = sb.toString();
12939                        sb.delete(0, sb.length());
12940                        sb.trimToSize();
12941                    }
12942                    if (report.length() != 0) {
12943                        dbox.addText(dropboxTag, report);
12944                    }
12945                }
12946            }.start();
12947            return;
12948        }
12949
12950        // System app batching:
12951        if (!bufferWasEmpty) {
12952            // An existing dropbox-writing thread is outstanding, so
12953            // we don't need to start it up.  The existing thread will
12954            // catch the buffer appends we just did.
12955            return;
12956        }
12957
12958        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12959        // (After this point, we shouldn't access AMS internal data structures.)
12960        new Thread("Error dump: " + dropboxTag) {
12961            @Override
12962            public void run() {
12963                // 5 second sleep to let stacks arrive and be batched together
12964                try {
12965                    Thread.sleep(5000);  // 5 seconds
12966                } catch (InterruptedException e) {}
12967
12968                String errorReport;
12969                synchronized (mStrictModeBuffer) {
12970                    errorReport = mStrictModeBuffer.toString();
12971                    if (errorReport.length() == 0) {
12972                        return;
12973                    }
12974                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12975                    mStrictModeBuffer.trimToSize();
12976                }
12977                dbox.addText(dropboxTag, errorReport);
12978            }
12979        }.start();
12980    }
12981
12982    /**
12983     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12984     * @param app object of the crashing app, null for the system server
12985     * @param tag reported by the caller
12986     * @param system whether this wtf is coming from the system
12987     * @param crashInfo describing the context of the error
12988     * @return true if the process should exit immediately (WTF is fatal)
12989     */
12990    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12991            final ApplicationErrorReport.CrashInfo crashInfo) {
12992        final int callingUid = Binder.getCallingUid();
12993        final int callingPid = Binder.getCallingPid();
12994
12995        if (system) {
12996            // If this is coming from the system, we could very well have low-level
12997            // system locks held, so we want to do this all asynchronously.  And we
12998            // never want this to become fatal, so there is that too.
12999            mHandler.post(new Runnable() {
13000                @Override public void run() {
13001                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13002                }
13003            });
13004            return false;
13005        }
13006
13007        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13008                crashInfo);
13009
13010        if (r != null && r.pid != Process.myPid() &&
13011                Settings.Global.getInt(mContext.getContentResolver(),
13012                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13013            crashApplication(r, crashInfo);
13014            return true;
13015        } else {
13016            return false;
13017        }
13018    }
13019
13020    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13021            final ApplicationErrorReport.CrashInfo crashInfo) {
13022        final ProcessRecord r = findAppProcess(app, "WTF");
13023        final String processName = app == null ? "system_server"
13024                : (r == null ? "unknown" : r.processName);
13025
13026        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13027                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13028
13029        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13030
13031        return r;
13032    }
13033
13034    /**
13035     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13036     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13037     */
13038    private ProcessRecord findAppProcess(IBinder app, String reason) {
13039        if (app == null) {
13040            return null;
13041        }
13042
13043        synchronized (this) {
13044            final int NP = mProcessNames.getMap().size();
13045            for (int ip=0; ip<NP; ip++) {
13046                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13047                final int NA = apps.size();
13048                for (int ia=0; ia<NA; ia++) {
13049                    ProcessRecord p = apps.valueAt(ia);
13050                    if (p.thread != null && p.thread.asBinder() == app) {
13051                        return p;
13052                    }
13053                }
13054            }
13055
13056            Slog.w(TAG, "Can't find mystery application for " + reason
13057                    + " from pid=" + Binder.getCallingPid()
13058                    + " uid=" + Binder.getCallingUid() + ": " + app);
13059            return null;
13060        }
13061    }
13062
13063    /**
13064     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13065     * to append various headers to the dropbox log text.
13066     */
13067    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13068            StringBuilder sb) {
13069        // Watchdog thread ends up invoking this function (with
13070        // a null ProcessRecord) to add the stack file to dropbox.
13071        // Do not acquire a lock on this (am) in such cases, as it
13072        // could cause a potential deadlock, if and when watchdog
13073        // is invoked due to unavailability of lock on am and it
13074        // would prevent watchdog from killing system_server.
13075        if (process == null) {
13076            sb.append("Process: ").append(processName).append("\n");
13077            return;
13078        }
13079        // Note: ProcessRecord 'process' is guarded by the service
13080        // instance.  (notably process.pkgList, which could otherwise change
13081        // concurrently during execution of this method)
13082        synchronized (this) {
13083            sb.append("Process: ").append(processName).append("\n");
13084            int flags = process.info.flags;
13085            IPackageManager pm = AppGlobals.getPackageManager();
13086            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13087            for (int ip=0; ip<process.pkgList.size(); ip++) {
13088                String pkg = process.pkgList.keyAt(ip);
13089                sb.append("Package: ").append(pkg);
13090                try {
13091                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13092                    if (pi != null) {
13093                        sb.append(" v").append(pi.versionCode);
13094                        if (pi.versionName != null) {
13095                            sb.append(" (").append(pi.versionName).append(")");
13096                        }
13097                    }
13098                } catch (RemoteException e) {
13099                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13100                }
13101                sb.append("\n");
13102            }
13103        }
13104    }
13105
13106    private static String processClass(ProcessRecord process) {
13107        if (process == null || process.pid == MY_PID) {
13108            return "system_server";
13109        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13110            return "system_app";
13111        } else {
13112            return "data_app";
13113        }
13114    }
13115
13116    /**
13117     * Write a description of an error (crash, WTF, ANR) to the drop box.
13118     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13119     * @param process which caused the error, null means the system server
13120     * @param activity which triggered the error, null if unknown
13121     * @param parent activity related to the error, null if unknown
13122     * @param subject line related to the error, null if absent
13123     * @param report in long form describing the error, null if absent
13124     * @param logFile to include in the report, null if none
13125     * @param crashInfo giving an application stack trace, null if absent
13126     */
13127    public void addErrorToDropBox(String eventType,
13128            ProcessRecord process, String processName, ActivityRecord activity,
13129            ActivityRecord parent, String subject,
13130            final String report, final File logFile,
13131            final ApplicationErrorReport.CrashInfo crashInfo) {
13132        // NOTE -- this must never acquire the ActivityManagerService lock,
13133        // otherwise the watchdog may be prevented from resetting the system.
13134
13135        final String dropboxTag = processClass(process) + "_" + eventType;
13136        final DropBoxManager dbox = (DropBoxManager)
13137                mContext.getSystemService(Context.DROPBOX_SERVICE);
13138
13139        // Exit early if the dropbox isn't configured to accept this report type.
13140        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13141
13142        final StringBuilder sb = new StringBuilder(1024);
13143        appendDropBoxProcessHeaders(process, processName, sb);
13144        if (activity != null) {
13145            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13146        }
13147        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13148            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13149        }
13150        if (parent != null && parent != activity) {
13151            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13152        }
13153        if (subject != null) {
13154            sb.append("Subject: ").append(subject).append("\n");
13155        }
13156        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13157        if (Debug.isDebuggerConnected()) {
13158            sb.append("Debugger: Connected\n");
13159        }
13160        sb.append("\n");
13161
13162        // Do the rest in a worker thread to avoid blocking the caller on I/O
13163        // (After this point, we shouldn't access AMS internal data structures.)
13164        Thread worker = new Thread("Error dump: " + dropboxTag) {
13165            @Override
13166            public void run() {
13167                if (report != null) {
13168                    sb.append(report);
13169                }
13170                if (logFile != null) {
13171                    try {
13172                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13173                                    "\n\n[[TRUNCATED]]"));
13174                    } catch (IOException e) {
13175                        Slog.e(TAG, "Error reading " + logFile, e);
13176                    }
13177                }
13178                if (crashInfo != null && crashInfo.stackTrace != null) {
13179                    sb.append(crashInfo.stackTrace);
13180                }
13181
13182                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13183                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13184                if (lines > 0) {
13185                    sb.append("\n");
13186
13187                    // Merge several logcat streams, and take the last N lines
13188                    InputStreamReader input = null;
13189                    try {
13190                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13191                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13192                                "-b", "crash",
13193                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13194
13195                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13196                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13197                        input = new InputStreamReader(logcat.getInputStream());
13198
13199                        int num;
13200                        char[] buf = new char[8192];
13201                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13202                    } catch (IOException e) {
13203                        Slog.e(TAG, "Error running logcat", e);
13204                    } finally {
13205                        if (input != null) try { input.close(); } catch (IOException e) {}
13206                    }
13207                }
13208
13209                dbox.addText(dropboxTag, sb.toString());
13210            }
13211        };
13212
13213        if (process == null) {
13214            // If process is null, we are being called from some internal code
13215            // and may be about to die -- run this synchronously.
13216            worker.run();
13217        } else {
13218            worker.start();
13219        }
13220    }
13221
13222    /**
13223     * Bring up the "unexpected error" dialog box for a crashing app.
13224     * Deal with edge cases (intercepts from instrumented applications,
13225     * ActivityController, error intent receivers, that sort of thing).
13226     * @param r the application crashing
13227     * @param crashInfo describing the failure
13228     */
13229    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13230        long timeMillis = System.currentTimeMillis();
13231        String shortMsg = crashInfo.exceptionClassName;
13232        String longMsg = crashInfo.exceptionMessage;
13233        String stackTrace = crashInfo.stackTrace;
13234        if (shortMsg != null && longMsg != null) {
13235            longMsg = shortMsg + ": " + longMsg;
13236        } else if (shortMsg != null) {
13237            longMsg = shortMsg;
13238        }
13239
13240        AppErrorResult result = new AppErrorResult();
13241        synchronized (this) {
13242            if (mController != null) {
13243                try {
13244                    String name = r != null ? r.processName : null;
13245                    int pid = r != null ? r.pid : Binder.getCallingPid();
13246                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13247                    if (!mController.appCrashed(name, pid,
13248                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13249                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13250                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13251                            Slog.w(TAG, "Skip killing native crashed app " + name
13252                                    + "(" + pid + ") during testing");
13253                        } else {
13254                            Slog.w(TAG, "Force-killing crashed app " + name
13255                                    + " at watcher's request");
13256                            if (r != null) {
13257                                r.kill("crash", true);
13258                            } else {
13259                                // Huh.
13260                                Process.killProcess(pid);
13261                                killProcessGroup(uid, pid);
13262                            }
13263                        }
13264                        return;
13265                    }
13266                } catch (RemoteException e) {
13267                    mController = null;
13268                    Watchdog.getInstance().setActivityController(null);
13269                }
13270            }
13271
13272            final long origId = Binder.clearCallingIdentity();
13273
13274            // If this process is running instrumentation, finish it.
13275            if (r != null && r.instrumentationClass != null) {
13276                Slog.w(TAG, "Error in app " + r.processName
13277                      + " running instrumentation " + r.instrumentationClass + ":");
13278                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13279                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13280                Bundle info = new Bundle();
13281                info.putString("shortMsg", shortMsg);
13282                info.putString("longMsg", longMsg);
13283                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13284                Binder.restoreCallingIdentity(origId);
13285                return;
13286            }
13287
13288            // Log crash in battery stats.
13289            if (r != null) {
13290                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13291            }
13292
13293            // If we can't identify the process or it's already exceeded its crash quota,
13294            // quit right away without showing a crash dialog.
13295            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13296                Binder.restoreCallingIdentity(origId);
13297                return;
13298            }
13299
13300            Message msg = Message.obtain();
13301            msg.what = SHOW_ERROR_UI_MSG;
13302            HashMap data = new HashMap();
13303            data.put("result", result);
13304            data.put("app", r);
13305            msg.obj = data;
13306            mUiHandler.sendMessage(msg);
13307
13308            Binder.restoreCallingIdentity(origId);
13309        }
13310
13311        int res = result.get();
13312
13313        Intent appErrorIntent = null;
13314        synchronized (this) {
13315            if (r != null && !r.isolated) {
13316                // XXX Can't keep track of crash time for isolated processes,
13317                // since they don't have a persistent identity.
13318                mProcessCrashTimes.put(r.info.processName, r.uid,
13319                        SystemClock.uptimeMillis());
13320            }
13321            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13322                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13323            }
13324        }
13325
13326        if (appErrorIntent != null) {
13327            try {
13328                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13329            } catch (ActivityNotFoundException e) {
13330                Slog.w(TAG, "bug report receiver dissappeared", e);
13331            }
13332        }
13333    }
13334
13335    Intent createAppErrorIntentLocked(ProcessRecord r,
13336            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13337        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13338        if (report == null) {
13339            return null;
13340        }
13341        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13342        result.setComponent(r.errorReportReceiver);
13343        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13344        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13345        return result;
13346    }
13347
13348    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13349            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13350        if (r.errorReportReceiver == null) {
13351            return null;
13352        }
13353
13354        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13355            return null;
13356        }
13357
13358        ApplicationErrorReport report = new ApplicationErrorReport();
13359        report.packageName = r.info.packageName;
13360        report.installerPackageName = r.errorReportReceiver.getPackageName();
13361        report.processName = r.processName;
13362        report.time = timeMillis;
13363        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13364
13365        if (r.crashing || r.forceCrashReport) {
13366            report.type = ApplicationErrorReport.TYPE_CRASH;
13367            report.crashInfo = crashInfo;
13368        } else if (r.notResponding) {
13369            report.type = ApplicationErrorReport.TYPE_ANR;
13370            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13371
13372            report.anrInfo.activity = r.notRespondingReport.tag;
13373            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13374            report.anrInfo.info = r.notRespondingReport.longMsg;
13375        }
13376
13377        return report;
13378    }
13379
13380    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13381        enforceNotIsolatedCaller("getProcessesInErrorState");
13382        // assume our apps are happy - lazy create the list
13383        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13384
13385        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13386                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13387        int userId = UserHandle.getUserId(Binder.getCallingUid());
13388
13389        synchronized (this) {
13390
13391            // iterate across all processes
13392            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13393                ProcessRecord app = mLruProcesses.get(i);
13394                if (!allUsers && app.userId != userId) {
13395                    continue;
13396                }
13397                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13398                    // This one's in trouble, so we'll generate a report for it
13399                    // crashes are higher priority (in case there's a crash *and* an anr)
13400                    ActivityManager.ProcessErrorStateInfo report = null;
13401                    if (app.crashing) {
13402                        report = app.crashingReport;
13403                    } else if (app.notResponding) {
13404                        report = app.notRespondingReport;
13405                    }
13406
13407                    if (report != null) {
13408                        if (errList == null) {
13409                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13410                        }
13411                        errList.add(report);
13412                    } else {
13413                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13414                                " crashing = " + app.crashing +
13415                                " notResponding = " + app.notResponding);
13416                    }
13417                }
13418            }
13419        }
13420
13421        return errList;
13422    }
13423
13424    static int procStateToImportance(int procState, int memAdj,
13425            ActivityManager.RunningAppProcessInfo currApp) {
13426        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13427        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13428            currApp.lru = memAdj;
13429        } else {
13430            currApp.lru = 0;
13431        }
13432        return imp;
13433    }
13434
13435    private void fillInProcMemInfo(ProcessRecord app,
13436            ActivityManager.RunningAppProcessInfo outInfo) {
13437        outInfo.pid = app.pid;
13438        outInfo.uid = app.info.uid;
13439        if (mHeavyWeightProcess == app) {
13440            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13441        }
13442        if (app.persistent) {
13443            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13444        }
13445        if (app.activities.size() > 0) {
13446            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13447        }
13448        outInfo.lastTrimLevel = app.trimMemoryLevel;
13449        int adj = app.curAdj;
13450        int procState = app.curProcState;
13451        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13452        outInfo.importanceReasonCode = app.adjTypeCode;
13453        outInfo.processState = app.curProcState;
13454    }
13455
13456    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13457        enforceNotIsolatedCaller("getRunningAppProcesses");
13458
13459        final int callingUid = Binder.getCallingUid();
13460
13461        // Lazy instantiation of list
13462        List<ActivityManager.RunningAppProcessInfo> runList = null;
13463        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13464                callingUid) == PackageManager.PERMISSION_GRANTED;
13465        final int userId = UserHandle.getUserId(callingUid);
13466        final boolean allUids = isGetTasksAllowed(
13467                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13468
13469        synchronized (this) {
13470            // Iterate across all processes
13471            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13472                ProcessRecord app = mLruProcesses.get(i);
13473                if ((!allUsers && app.userId != userId)
13474                        || (!allUids && app.uid != callingUid)) {
13475                    continue;
13476                }
13477                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13478                    // Generate process state info for running application
13479                    ActivityManager.RunningAppProcessInfo currApp =
13480                        new ActivityManager.RunningAppProcessInfo(app.processName,
13481                                app.pid, app.getPackageList());
13482                    fillInProcMemInfo(app, currApp);
13483                    if (app.adjSource instanceof ProcessRecord) {
13484                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13485                        currApp.importanceReasonImportance =
13486                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13487                                        app.adjSourceProcState);
13488                    } else if (app.adjSource instanceof ActivityRecord) {
13489                        ActivityRecord r = (ActivityRecord)app.adjSource;
13490                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13491                    }
13492                    if (app.adjTarget instanceof ComponentName) {
13493                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13494                    }
13495                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13496                    //        + " lru=" + currApp.lru);
13497                    if (runList == null) {
13498                        runList = new ArrayList<>();
13499                    }
13500                    runList.add(currApp);
13501                }
13502            }
13503        }
13504        return runList;
13505    }
13506
13507    public List<ApplicationInfo> getRunningExternalApplications() {
13508        enforceNotIsolatedCaller("getRunningExternalApplications");
13509        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13510        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13511        if (runningApps != null && runningApps.size() > 0) {
13512            Set<String> extList = new HashSet<String>();
13513            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13514                if (app.pkgList != null) {
13515                    for (String pkg : app.pkgList) {
13516                        extList.add(pkg);
13517                    }
13518                }
13519            }
13520            IPackageManager pm = AppGlobals.getPackageManager();
13521            for (String pkg : extList) {
13522                try {
13523                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13524                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13525                        retList.add(info);
13526                    }
13527                } catch (RemoteException e) {
13528                }
13529            }
13530        }
13531        return retList;
13532    }
13533
13534    @Override
13535    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13536        enforceNotIsolatedCaller("getMyMemoryState");
13537        synchronized (this) {
13538            ProcessRecord proc;
13539            synchronized (mPidsSelfLocked) {
13540                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13541            }
13542            fillInProcMemInfo(proc, outInfo);
13543        }
13544    }
13545
13546    @Override
13547    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13548            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13549        (new ActivityManagerShellCommand(this, false)).exec(
13550                this, in, out, err, args, resultReceiver);
13551    }
13552
13553    @Override
13554    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13555        if (checkCallingPermission(android.Manifest.permission.DUMP)
13556                != PackageManager.PERMISSION_GRANTED) {
13557            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13558                    + Binder.getCallingPid()
13559                    + ", uid=" + Binder.getCallingUid()
13560                    + " without permission "
13561                    + android.Manifest.permission.DUMP);
13562            return;
13563        }
13564
13565        boolean dumpAll = false;
13566        boolean dumpClient = false;
13567        String dumpPackage = null;
13568
13569        int opti = 0;
13570        while (opti < args.length) {
13571            String opt = args[opti];
13572            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13573                break;
13574            }
13575            opti++;
13576            if ("-a".equals(opt)) {
13577                dumpAll = true;
13578            } else if ("-c".equals(opt)) {
13579                dumpClient = true;
13580            } else if ("-p".equals(opt)) {
13581                if (opti < args.length) {
13582                    dumpPackage = args[opti];
13583                    opti++;
13584                } else {
13585                    pw.println("Error: -p option requires package argument");
13586                    return;
13587                }
13588                dumpClient = true;
13589            } else if ("-h".equals(opt)) {
13590                ActivityManagerShellCommand.dumpHelp(pw, true);
13591                return;
13592            } else {
13593                pw.println("Unknown argument: " + opt + "; use -h for help");
13594            }
13595        }
13596
13597        long origId = Binder.clearCallingIdentity();
13598        boolean more = false;
13599        // Is the caller requesting to dump a particular piece of data?
13600        if (opti < args.length) {
13601            String cmd = args[opti];
13602            opti++;
13603            if ("activities".equals(cmd) || "a".equals(cmd)) {
13604                synchronized (this) {
13605                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13606                }
13607            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13608                synchronized (this) {
13609                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13610                }
13611            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13612                String[] newArgs;
13613                String name;
13614                if (opti >= args.length) {
13615                    name = null;
13616                    newArgs = EMPTY_STRING_ARRAY;
13617                } else {
13618                    dumpPackage = args[opti];
13619                    opti++;
13620                    newArgs = new String[args.length - opti];
13621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13622                            args.length - opti);
13623                }
13624                synchronized (this) {
13625                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13626                }
13627            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13628                String[] newArgs;
13629                String name;
13630                if (opti >= args.length) {
13631                    name = null;
13632                    newArgs = EMPTY_STRING_ARRAY;
13633                } else {
13634                    dumpPackage = args[opti];
13635                    opti++;
13636                    newArgs = new String[args.length - opti];
13637                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13638                            args.length - opti);
13639                }
13640                synchronized (this) {
13641                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13642                }
13643            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13644                String[] newArgs;
13645                String name;
13646                if (opti >= args.length) {
13647                    name = null;
13648                    newArgs = EMPTY_STRING_ARRAY;
13649                } else {
13650                    dumpPackage = args[opti];
13651                    opti++;
13652                    newArgs = new String[args.length - opti];
13653                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13654                            args.length - opti);
13655                }
13656                synchronized (this) {
13657                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13658                }
13659            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13660                synchronized (this) {
13661                    dumpOomLocked(fd, pw, args, opti, true);
13662                }
13663            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13664                synchronized (this) {
13665                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13666                }
13667            } else if ("provider".equals(cmd)) {
13668                String[] newArgs;
13669                String name;
13670                if (opti >= args.length) {
13671                    name = null;
13672                    newArgs = EMPTY_STRING_ARRAY;
13673                } else {
13674                    name = args[opti];
13675                    opti++;
13676                    newArgs = new String[args.length - opti];
13677                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13678                }
13679                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13680                    pw.println("No providers match: " + name);
13681                    pw.println("Use -h for help.");
13682                }
13683            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13684                synchronized (this) {
13685                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13686                }
13687            } else if ("service".equals(cmd)) {
13688                String[] newArgs;
13689                String name;
13690                if (opti >= args.length) {
13691                    name = null;
13692                    newArgs = EMPTY_STRING_ARRAY;
13693                } else {
13694                    name = args[opti];
13695                    opti++;
13696                    newArgs = new String[args.length - opti];
13697                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13698                            args.length - opti);
13699                }
13700                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13701                    pw.println("No services match: " + name);
13702                    pw.println("Use -h for help.");
13703                }
13704            } else if ("package".equals(cmd)) {
13705                String[] newArgs;
13706                if (opti >= args.length) {
13707                    pw.println("package: no package name specified");
13708                    pw.println("Use -h for help.");
13709                } else {
13710                    dumpPackage = args[opti];
13711                    opti++;
13712                    newArgs = new String[args.length - opti];
13713                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13714                            args.length - opti);
13715                    args = newArgs;
13716                    opti = 0;
13717                    more = true;
13718                }
13719            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13720                synchronized (this) {
13721                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13722                }
13723            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13724                synchronized (this) {
13725                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13726                }
13727            } else {
13728                // Dumping a single activity?
13729                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13730                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13731                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13732                    if (res < 0) {
13733                        pw.println("Bad activity command, or no activities match: " + cmd);
13734                        pw.println("Use -h for help.");
13735                    }
13736                }
13737            }
13738            if (!more) {
13739                Binder.restoreCallingIdentity(origId);
13740                return;
13741            }
13742        }
13743
13744        // No piece of data specified, dump everything.
13745        synchronized (this) {
13746            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13747            pw.println();
13748            if (dumpAll) {
13749                pw.println("-------------------------------------------------------------------------------");
13750            }
13751            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13752            pw.println();
13753            if (dumpAll) {
13754                pw.println("-------------------------------------------------------------------------------");
13755            }
13756            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13757            pw.println();
13758            if (dumpAll) {
13759                pw.println("-------------------------------------------------------------------------------");
13760            }
13761            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13762            pw.println();
13763            if (dumpAll) {
13764                pw.println("-------------------------------------------------------------------------------");
13765            }
13766            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13767            pw.println();
13768            if (dumpAll) {
13769                pw.println("-------------------------------------------------------------------------------");
13770            }
13771            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13772            pw.println();
13773            if (dumpAll) {
13774                pw.println("-------------------------------------------------------------------------------");
13775            }
13776            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13777            if (mAssociations.size() > 0) {
13778                pw.println();
13779                if (dumpAll) {
13780                    pw.println("-------------------------------------------------------------------------------");
13781                }
13782                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13783            }
13784            pw.println();
13785            if (dumpAll) {
13786                pw.println("-------------------------------------------------------------------------------");
13787            }
13788            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13789        }
13790        Binder.restoreCallingIdentity(origId);
13791    }
13792
13793    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13794            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13795        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13796
13797        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13798                dumpPackage);
13799        boolean needSep = printedAnything;
13800
13801        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13802                dumpPackage, needSep, "  mFocusedActivity: ");
13803        if (printed) {
13804            printedAnything = true;
13805            needSep = false;
13806        }
13807
13808        if (dumpPackage == null) {
13809            if (needSep) {
13810                pw.println();
13811            }
13812            needSep = true;
13813            printedAnything = true;
13814            mStackSupervisor.dump(pw, "  ");
13815        }
13816
13817        if (!printedAnything) {
13818            pw.println("  (nothing)");
13819        }
13820    }
13821
13822    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13823            int opti, boolean dumpAll, String dumpPackage) {
13824        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13825
13826        boolean printedAnything = false;
13827
13828        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13829            boolean printedHeader = false;
13830
13831            final int N = mRecentTasks.size();
13832            for (int i=0; i<N; i++) {
13833                TaskRecord tr = mRecentTasks.get(i);
13834                if (dumpPackage != null) {
13835                    if (tr.realActivity == null ||
13836                            !dumpPackage.equals(tr.realActivity)) {
13837                        continue;
13838                    }
13839                }
13840                if (!printedHeader) {
13841                    pw.println("  Recent tasks:");
13842                    printedHeader = true;
13843                    printedAnything = true;
13844                }
13845                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13846                        pw.println(tr);
13847                if (dumpAll) {
13848                    mRecentTasks.get(i).dump(pw, "    ");
13849                }
13850            }
13851        }
13852
13853        if (!printedAnything) {
13854            pw.println("  (nothing)");
13855        }
13856    }
13857
13858    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13859            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13860        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13861
13862        int dumpUid = 0;
13863        if (dumpPackage != null) {
13864            IPackageManager pm = AppGlobals.getPackageManager();
13865            try {
13866                dumpUid = pm.getPackageUid(dumpPackage, 0);
13867            } catch (RemoteException e) {
13868            }
13869        }
13870
13871        boolean printedAnything = false;
13872
13873        final long now = SystemClock.uptimeMillis();
13874
13875        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13876            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13877                    = mAssociations.valueAt(i1);
13878            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13879                SparseArray<ArrayMap<String, Association>> sourceUids
13880                        = targetComponents.valueAt(i2);
13881                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13882                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13883                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13884                        Association ass = sourceProcesses.valueAt(i4);
13885                        if (dumpPackage != null) {
13886                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13887                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13888                                continue;
13889                            }
13890                        }
13891                        printedAnything = true;
13892                        pw.print("  ");
13893                        pw.print(ass.mTargetProcess);
13894                        pw.print("/");
13895                        UserHandle.formatUid(pw, ass.mTargetUid);
13896                        pw.print(" <- ");
13897                        pw.print(ass.mSourceProcess);
13898                        pw.print("/");
13899                        UserHandle.formatUid(pw, ass.mSourceUid);
13900                        pw.println();
13901                        pw.print("    via ");
13902                        pw.print(ass.mTargetComponent.flattenToShortString());
13903                        pw.println();
13904                        pw.print("    ");
13905                        long dur = ass.mTime;
13906                        if (ass.mNesting > 0) {
13907                            dur += now - ass.mStartTime;
13908                        }
13909                        TimeUtils.formatDuration(dur, pw);
13910                        pw.print(" (");
13911                        pw.print(ass.mCount);
13912                        pw.println(" times)");
13913                        if (ass.mNesting > 0) {
13914                            pw.print("    ");
13915                            pw.print(" Currently active: ");
13916                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13917                            pw.println();
13918                        }
13919                    }
13920                }
13921            }
13922
13923        }
13924
13925        if (!printedAnything) {
13926            pw.println("  (nothing)");
13927        }
13928    }
13929
13930    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13931            String header, boolean needSep) {
13932        boolean printed = false;
13933        int whichAppId = -1;
13934        if (dumpPackage != null) {
13935            try {
13936                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13937                        dumpPackage, 0);
13938                whichAppId = UserHandle.getAppId(info.uid);
13939            } catch (NameNotFoundException e) {
13940                e.printStackTrace();
13941            }
13942        }
13943        for (int i=0; i<uids.size(); i++) {
13944            UidRecord uidRec = uids.valueAt(i);
13945            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13946                continue;
13947            }
13948            if (!printed) {
13949                printed = true;
13950                if (needSep) {
13951                    pw.println();
13952                }
13953                pw.print("  ");
13954                pw.println(header);
13955                needSep = true;
13956            }
13957            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13958            pw.print(": "); pw.println(uidRec);
13959        }
13960        return printed;
13961    }
13962
13963    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13964            int opti, boolean dumpAll, String dumpPackage) {
13965        boolean needSep = false;
13966        boolean printedAnything = false;
13967        int numPers = 0;
13968
13969        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13970
13971        if (dumpAll) {
13972            final int NP = mProcessNames.getMap().size();
13973            for (int ip=0; ip<NP; ip++) {
13974                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13975                final int NA = procs.size();
13976                for (int ia=0; ia<NA; ia++) {
13977                    ProcessRecord r = procs.valueAt(ia);
13978                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13979                        continue;
13980                    }
13981                    if (!needSep) {
13982                        pw.println("  All known processes:");
13983                        needSep = true;
13984                        printedAnything = true;
13985                    }
13986                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13987                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13988                        pw.print(" "); pw.println(r);
13989                    r.dump(pw, "    ");
13990                    if (r.persistent) {
13991                        numPers++;
13992                    }
13993                }
13994            }
13995        }
13996
13997        if (mIsolatedProcesses.size() > 0) {
13998            boolean printed = false;
13999            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14000                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14001                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14002                    continue;
14003                }
14004                if (!printed) {
14005                    if (needSep) {
14006                        pw.println();
14007                    }
14008                    pw.println("  Isolated process list (sorted by uid):");
14009                    printedAnything = true;
14010                    printed = true;
14011                    needSep = true;
14012                }
14013                pw.println(String.format("%sIsolated #%2d: %s",
14014                        "    ", i, r.toString()));
14015            }
14016        }
14017
14018        if (mActiveUids.size() > 0) {
14019            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14020                printedAnything = needSep = true;
14021            }
14022        }
14023        if (mValidateUids.size() > 0) {
14024            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14025                printedAnything = needSep = true;
14026            }
14027        }
14028
14029        if (mLruProcesses.size() > 0) {
14030            if (needSep) {
14031                pw.println();
14032            }
14033            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14034                    pw.print(" total, non-act at ");
14035                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14036                    pw.print(", non-svc at ");
14037                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14038                    pw.println("):");
14039            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14040            needSep = true;
14041            printedAnything = true;
14042        }
14043
14044        if (dumpAll || dumpPackage != null) {
14045            synchronized (mPidsSelfLocked) {
14046                boolean printed = false;
14047                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14048                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14049                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14050                        continue;
14051                    }
14052                    if (!printed) {
14053                        if (needSep) pw.println();
14054                        needSep = true;
14055                        pw.println("  PID mappings:");
14056                        printed = true;
14057                        printedAnything = true;
14058                    }
14059                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14060                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14061                }
14062            }
14063        }
14064
14065        if (mForegroundProcesses.size() > 0) {
14066            synchronized (mPidsSelfLocked) {
14067                boolean printed = false;
14068                for (int i=0; i<mForegroundProcesses.size(); i++) {
14069                    ProcessRecord r = mPidsSelfLocked.get(
14070                            mForegroundProcesses.valueAt(i).pid);
14071                    if (dumpPackage != null && (r == null
14072                            || !r.pkgList.containsKey(dumpPackage))) {
14073                        continue;
14074                    }
14075                    if (!printed) {
14076                        if (needSep) pw.println();
14077                        needSep = true;
14078                        pw.println("  Foreground Processes:");
14079                        printed = true;
14080                        printedAnything = true;
14081                    }
14082                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14083                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14084                }
14085            }
14086        }
14087
14088        if (mPersistentStartingProcesses.size() > 0) {
14089            if (needSep) pw.println();
14090            needSep = true;
14091            printedAnything = true;
14092            pw.println("  Persisent processes that are starting:");
14093            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14094                    "Starting Norm", "Restarting PERS", dumpPackage);
14095        }
14096
14097        if (mRemovedProcesses.size() > 0) {
14098            if (needSep) pw.println();
14099            needSep = true;
14100            printedAnything = true;
14101            pw.println("  Processes that are being removed:");
14102            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14103                    "Removed Norm", "Removed PERS", dumpPackage);
14104        }
14105
14106        if (mProcessesOnHold.size() > 0) {
14107            if (needSep) pw.println();
14108            needSep = true;
14109            printedAnything = true;
14110            pw.println("  Processes that are on old until the system is ready:");
14111            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14112                    "OnHold Norm", "OnHold PERS", dumpPackage);
14113        }
14114
14115        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14116
14117        if (mProcessCrashTimes.getMap().size() > 0) {
14118            boolean printed = false;
14119            long now = SystemClock.uptimeMillis();
14120            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14121            final int NP = pmap.size();
14122            for (int ip=0; ip<NP; ip++) {
14123                String pname = pmap.keyAt(ip);
14124                SparseArray<Long> uids = pmap.valueAt(ip);
14125                final int N = uids.size();
14126                for (int i=0; i<N; i++) {
14127                    int puid = uids.keyAt(i);
14128                    ProcessRecord r = mProcessNames.get(pname, puid);
14129                    if (dumpPackage != null && (r == null
14130                            || !r.pkgList.containsKey(dumpPackage))) {
14131                        continue;
14132                    }
14133                    if (!printed) {
14134                        if (needSep) pw.println();
14135                        needSep = true;
14136                        pw.println("  Time since processes crashed:");
14137                        printed = true;
14138                        printedAnything = true;
14139                    }
14140                    pw.print("    Process "); pw.print(pname);
14141                            pw.print(" uid "); pw.print(puid);
14142                            pw.print(": last crashed ");
14143                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14144                            pw.println(" ago");
14145                }
14146            }
14147        }
14148
14149        if (mBadProcesses.getMap().size() > 0) {
14150            boolean printed = false;
14151            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14152            final int NP = pmap.size();
14153            for (int ip=0; ip<NP; ip++) {
14154                String pname = pmap.keyAt(ip);
14155                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14156                final int N = uids.size();
14157                for (int i=0; i<N; i++) {
14158                    int puid = uids.keyAt(i);
14159                    ProcessRecord r = mProcessNames.get(pname, puid);
14160                    if (dumpPackage != null && (r == null
14161                            || !r.pkgList.containsKey(dumpPackage))) {
14162                        continue;
14163                    }
14164                    if (!printed) {
14165                        if (needSep) pw.println();
14166                        needSep = true;
14167                        pw.println("  Bad processes:");
14168                        printedAnything = true;
14169                    }
14170                    BadProcessInfo info = uids.valueAt(i);
14171                    pw.print("    Bad process "); pw.print(pname);
14172                            pw.print(" uid "); pw.print(puid);
14173                            pw.print(": crashed at time "); pw.println(info.time);
14174                    if (info.shortMsg != null) {
14175                        pw.print("      Short msg: "); pw.println(info.shortMsg);
14176                    }
14177                    if (info.longMsg != null) {
14178                        pw.print("      Long msg: "); pw.println(info.longMsg);
14179                    }
14180                    if (info.stack != null) {
14181                        pw.println("      Stack:");
14182                        int lastPos = 0;
14183                        for (int pos=0; pos<info.stack.length(); pos++) {
14184                            if (info.stack.charAt(pos) == '\n') {
14185                                pw.print("        ");
14186                                pw.write(info.stack, lastPos, pos-lastPos);
14187                                pw.println();
14188                                lastPos = pos+1;
14189                            }
14190                        }
14191                        if (lastPos < info.stack.length()) {
14192                            pw.print("        ");
14193                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14194                            pw.println();
14195                        }
14196                    }
14197                }
14198            }
14199        }
14200
14201        if (dumpPackage == null) {
14202            pw.println();
14203            needSep = false;
14204            mUserController.dump(pw, dumpAll);
14205        }
14206        if (mHomeProcess != null && (dumpPackage == null
14207                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14208            if (needSep) {
14209                pw.println();
14210                needSep = false;
14211            }
14212            pw.println("  mHomeProcess: " + mHomeProcess);
14213        }
14214        if (mPreviousProcess != null && (dumpPackage == null
14215                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14216            if (needSep) {
14217                pw.println();
14218                needSep = false;
14219            }
14220            pw.println("  mPreviousProcess: " + mPreviousProcess);
14221        }
14222        if (dumpAll) {
14223            StringBuilder sb = new StringBuilder(128);
14224            sb.append("  mPreviousProcessVisibleTime: ");
14225            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14226            pw.println(sb);
14227        }
14228        if (mHeavyWeightProcess != null && (dumpPackage == null
14229                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14230            if (needSep) {
14231                pw.println();
14232                needSep = false;
14233            }
14234            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14235        }
14236        if (dumpPackage == null) {
14237            pw.println("  mConfiguration: " + mConfiguration);
14238        }
14239        if (dumpAll) {
14240            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14241            if (mCompatModePackages.getPackages().size() > 0) {
14242                boolean printed = false;
14243                for (Map.Entry<String, Integer> entry
14244                        : mCompatModePackages.getPackages().entrySet()) {
14245                    String pkg = entry.getKey();
14246                    int mode = entry.getValue();
14247                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14248                        continue;
14249                    }
14250                    if (!printed) {
14251                        pw.println("  mScreenCompatPackages:");
14252                        printed = true;
14253                    }
14254                    pw.print("    "); pw.print(pkg); pw.print(": ");
14255                            pw.print(mode); pw.println();
14256                }
14257            }
14258        }
14259        if (dumpPackage == null) {
14260            pw.println("  mWakefulness="
14261                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14262            pw.println("  mSleepTokens=" + mSleepTokens);
14263            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14264                    + lockScreenShownToString());
14265            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14266            if (mRunningVoice != null) {
14267                pw.println("  mRunningVoice=" + mRunningVoice);
14268                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14269            }
14270        }
14271        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14272                || mOrigWaitForDebugger) {
14273            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14274                    || dumpPackage.equals(mOrigDebugApp)) {
14275                if (needSep) {
14276                    pw.println();
14277                    needSep = false;
14278                }
14279                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14280                        + " mDebugTransient=" + mDebugTransient
14281                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14282            }
14283        }
14284        if (mCurAppTimeTracker != null) {
14285            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14286        }
14287        if (mMemWatchProcesses.getMap().size() > 0) {
14288            pw.println("  Mem watch processes:");
14289            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14290                    = mMemWatchProcesses.getMap();
14291            for (int i=0; i<procs.size(); i++) {
14292                final String proc = procs.keyAt(i);
14293                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14294                for (int j=0; j<uids.size(); j++) {
14295                    if (needSep) {
14296                        pw.println();
14297                        needSep = false;
14298                    }
14299                    StringBuilder sb = new StringBuilder();
14300                    sb.append("    ").append(proc).append('/');
14301                    UserHandle.formatUid(sb, uids.keyAt(j));
14302                    Pair<Long, String> val = uids.valueAt(j);
14303                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14304                    if (val.second != null) {
14305                        sb.append(", report to ").append(val.second);
14306                    }
14307                    pw.println(sb.toString());
14308                }
14309            }
14310            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14311            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14312            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14313                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14314        }
14315        if (mTrackAllocationApp != null) {
14316            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14317                if (needSep) {
14318                    pw.println();
14319                    needSep = false;
14320                }
14321                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14322            }
14323        }
14324        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14325                || mProfileFd != null) {
14326            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14327                if (needSep) {
14328                    pw.println();
14329                    needSep = false;
14330                }
14331                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14332                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14333                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14334                        + mAutoStopProfiler);
14335                pw.println("  mProfileType=" + mProfileType);
14336            }
14337        }
14338        if (dumpPackage == null) {
14339            if (mAlwaysFinishActivities || mController != null) {
14340                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14341                        + " mController=" + mController);
14342            }
14343            if (dumpAll) {
14344                pw.println("  Total persistent processes: " + numPers);
14345                pw.println("  mProcessesReady=" + mProcessesReady
14346                        + " mSystemReady=" + mSystemReady
14347                        + " mBooted=" + mBooted
14348                        + " mFactoryTest=" + mFactoryTest);
14349                pw.println("  mBooting=" + mBooting
14350                        + " mCallFinishBooting=" + mCallFinishBooting
14351                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14352                pw.print("  mLastPowerCheckRealtime=");
14353                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14354                        pw.println("");
14355                pw.print("  mLastPowerCheckUptime=");
14356                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14357                        pw.println("");
14358                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14359                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14360                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14361                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14362                        + " (" + mLruProcesses.size() + " total)"
14363                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14364                        + " mNumServiceProcs=" + mNumServiceProcs
14365                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14366                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14367                        + " mLastMemoryLevel" + mLastMemoryLevel
14368                        + " mLastNumProcesses" + mLastNumProcesses);
14369                long now = SystemClock.uptimeMillis();
14370                pw.print("  mLastIdleTime=");
14371                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14372                        pw.print(" mLowRamSinceLastIdle=");
14373                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14374                        pw.println();
14375            }
14376        }
14377
14378        if (!printedAnything) {
14379            pw.println("  (nothing)");
14380        }
14381    }
14382
14383    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14384            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14385        if (mProcessesToGc.size() > 0) {
14386            boolean printed = false;
14387            long now = SystemClock.uptimeMillis();
14388            for (int i=0; i<mProcessesToGc.size(); i++) {
14389                ProcessRecord proc = mProcessesToGc.get(i);
14390                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14391                    continue;
14392                }
14393                if (!printed) {
14394                    if (needSep) pw.println();
14395                    needSep = true;
14396                    pw.println("  Processes that are waiting to GC:");
14397                    printed = true;
14398                }
14399                pw.print("    Process "); pw.println(proc);
14400                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14401                        pw.print(", last gced=");
14402                        pw.print(now-proc.lastRequestedGc);
14403                        pw.print(" ms ago, last lowMem=");
14404                        pw.print(now-proc.lastLowMemory);
14405                        pw.println(" ms ago");
14406
14407            }
14408        }
14409        return needSep;
14410    }
14411
14412    void printOomLevel(PrintWriter pw, String name, int adj) {
14413        pw.print("    ");
14414        if (adj >= 0) {
14415            pw.print(' ');
14416            if (adj < 10) pw.print(' ');
14417        } else {
14418            if (adj > -10) pw.print(' ');
14419        }
14420        pw.print(adj);
14421        pw.print(": ");
14422        pw.print(name);
14423        pw.print(" (");
14424        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14425        pw.println(")");
14426    }
14427
14428    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14429            int opti, boolean dumpAll) {
14430        boolean needSep = false;
14431
14432        if (mLruProcesses.size() > 0) {
14433            if (needSep) pw.println();
14434            needSep = true;
14435            pw.println("  OOM levels:");
14436            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14437            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14438            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14439            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14440            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14441            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14442            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14443            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14444            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14445            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14446            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14447            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14448            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14449            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14450
14451            if (needSep) pw.println();
14452            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14453                    pw.print(" total, non-act at ");
14454                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14455                    pw.print(", non-svc at ");
14456                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14457                    pw.println("):");
14458            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14459            needSep = true;
14460        }
14461
14462        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14463
14464        pw.println();
14465        pw.println("  mHomeProcess: " + mHomeProcess);
14466        pw.println("  mPreviousProcess: " + mPreviousProcess);
14467        if (mHeavyWeightProcess != null) {
14468            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14469        }
14470
14471        return true;
14472    }
14473
14474    /**
14475     * There are three ways to call this:
14476     *  - no provider specified: dump all the providers
14477     *  - a flattened component name that matched an existing provider was specified as the
14478     *    first arg: dump that one provider
14479     *  - the first arg isn't the flattened component name of an existing provider:
14480     *    dump all providers whose component contains the first arg as a substring
14481     */
14482    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14483            int opti, boolean dumpAll) {
14484        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14485    }
14486
14487    static class ItemMatcher {
14488        ArrayList<ComponentName> components;
14489        ArrayList<String> strings;
14490        ArrayList<Integer> objects;
14491        boolean all;
14492
14493        ItemMatcher() {
14494            all = true;
14495        }
14496
14497        void build(String name) {
14498            ComponentName componentName = ComponentName.unflattenFromString(name);
14499            if (componentName != null) {
14500                if (components == null) {
14501                    components = new ArrayList<ComponentName>();
14502                }
14503                components.add(componentName);
14504                all = false;
14505            } else {
14506                int objectId = 0;
14507                // Not a '/' separated full component name; maybe an object ID?
14508                try {
14509                    objectId = Integer.parseInt(name, 16);
14510                    if (objects == null) {
14511                        objects = new ArrayList<Integer>();
14512                    }
14513                    objects.add(objectId);
14514                    all = false;
14515                } catch (RuntimeException e) {
14516                    // Not an integer; just do string match.
14517                    if (strings == null) {
14518                        strings = new ArrayList<String>();
14519                    }
14520                    strings.add(name);
14521                    all = false;
14522                }
14523            }
14524        }
14525
14526        int build(String[] args, int opti) {
14527            for (; opti<args.length; opti++) {
14528                String name = args[opti];
14529                if ("--".equals(name)) {
14530                    return opti+1;
14531                }
14532                build(name);
14533            }
14534            return opti;
14535        }
14536
14537        boolean match(Object object, ComponentName comp) {
14538            if (all) {
14539                return true;
14540            }
14541            if (components != null) {
14542                for (int i=0; i<components.size(); i++) {
14543                    if (components.get(i).equals(comp)) {
14544                        return true;
14545                    }
14546                }
14547            }
14548            if (objects != null) {
14549                for (int i=0; i<objects.size(); i++) {
14550                    if (System.identityHashCode(object) == objects.get(i)) {
14551                        return true;
14552                    }
14553                }
14554            }
14555            if (strings != null) {
14556                String flat = comp.flattenToString();
14557                for (int i=0; i<strings.size(); i++) {
14558                    if (flat.contains(strings.get(i))) {
14559                        return true;
14560                    }
14561                }
14562            }
14563            return false;
14564        }
14565    }
14566
14567    /**
14568     * There are three things that cmd can be:
14569     *  - a flattened component name that matches an existing activity
14570     *  - the cmd arg isn't the flattened component name of an existing activity:
14571     *    dump all activity whose component contains the cmd as a substring
14572     *  - A hex number of the ActivityRecord object instance.
14573     */
14574    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14575            int opti, boolean dumpAll) {
14576        ArrayList<ActivityRecord> activities;
14577
14578        synchronized (this) {
14579            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14580        }
14581
14582        if (activities.size() <= 0) {
14583            return false;
14584        }
14585
14586        String[] newArgs = new String[args.length - opti];
14587        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14588
14589        TaskRecord lastTask = null;
14590        boolean needSep = false;
14591        for (int i=activities.size()-1; i>=0; i--) {
14592            ActivityRecord r = activities.get(i);
14593            if (needSep) {
14594                pw.println();
14595            }
14596            needSep = true;
14597            synchronized (this) {
14598                if (lastTask != r.task) {
14599                    lastTask = r.task;
14600                    pw.print("TASK "); pw.print(lastTask.affinity);
14601                            pw.print(" id="); pw.println(lastTask.taskId);
14602                    if (dumpAll) {
14603                        lastTask.dump(pw, "  ");
14604                    }
14605                }
14606            }
14607            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14608        }
14609        return true;
14610    }
14611
14612    /**
14613     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14614     * there is a thread associated with the activity.
14615     */
14616    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14617            final ActivityRecord r, String[] args, boolean dumpAll) {
14618        String innerPrefix = prefix + "  ";
14619        synchronized (this) {
14620            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14621                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14622                    pw.print(" pid=");
14623                    if (r.app != null) pw.println(r.app.pid);
14624                    else pw.println("(not running)");
14625            if (dumpAll) {
14626                r.dump(pw, innerPrefix);
14627            }
14628        }
14629        if (r.app != null && r.app.thread != null) {
14630            // flush anything that is already in the PrintWriter since the thread is going
14631            // to write to the file descriptor directly
14632            pw.flush();
14633            try {
14634                TransferPipe tp = new TransferPipe();
14635                try {
14636                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14637                            r.appToken, innerPrefix, args);
14638                    tp.go(fd);
14639                } finally {
14640                    tp.kill();
14641                }
14642            } catch (IOException e) {
14643                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14644            } catch (RemoteException e) {
14645                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14646            }
14647        }
14648    }
14649
14650    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14651            int opti, boolean dumpAll, String dumpPackage) {
14652        boolean needSep = false;
14653        boolean onlyHistory = false;
14654        boolean printedAnything = false;
14655
14656        if ("history".equals(dumpPackage)) {
14657            if (opti < args.length && "-s".equals(args[opti])) {
14658                dumpAll = false;
14659            }
14660            onlyHistory = true;
14661            dumpPackage = null;
14662        }
14663
14664        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14665        if (!onlyHistory && dumpAll) {
14666            if (mRegisteredReceivers.size() > 0) {
14667                boolean printed = false;
14668                Iterator it = mRegisteredReceivers.values().iterator();
14669                while (it.hasNext()) {
14670                    ReceiverList r = (ReceiverList)it.next();
14671                    if (dumpPackage != null && (r.app == null ||
14672                            !dumpPackage.equals(r.app.info.packageName))) {
14673                        continue;
14674                    }
14675                    if (!printed) {
14676                        pw.println("  Registered Receivers:");
14677                        needSep = true;
14678                        printed = true;
14679                        printedAnything = true;
14680                    }
14681                    pw.print("  * "); pw.println(r);
14682                    r.dump(pw, "    ");
14683                }
14684            }
14685
14686            if (mReceiverResolver.dump(pw, needSep ?
14687                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14688                    "    ", dumpPackage, false, false)) {
14689                needSep = true;
14690                printedAnything = true;
14691            }
14692        }
14693
14694        for (BroadcastQueue q : mBroadcastQueues) {
14695            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14696            printedAnything |= needSep;
14697        }
14698
14699        needSep = true;
14700
14701        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14702            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14703                if (needSep) {
14704                    pw.println();
14705                }
14706                needSep = true;
14707                printedAnything = true;
14708                pw.print("  Sticky broadcasts for user ");
14709                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14710                StringBuilder sb = new StringBuilder(128);
14711                for (Map.Entry<String, ArrayList<Intent>> ent
14712                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14713                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14714                    if (dumpAll) {
14715                        pw.println(":");
14716                        ArrayList<Intent> intents = ent.getValue();
14717                        final int N = intents.size();
14718                        for (int i=0; i<N; i++) {
14719                            sb.setLength(0);
14720                            sb.append("    Intent: ");
14721                            intents.get(i).toShortString(sb, false, true, false, false);
14722                            pw.println(sb.toString());
14723                            Bundle bundle = intents.get(i).getExtras();
14724                            if (bundle != null) {
14725                                pw.print("      ");
14726                                pw.println(bundle.toString());
14727                            }
14728                        }
14729                    } else {
14730                        pw.println("");
14731                    }
14732                }
14733            }
14734        }
14735
14736        if (!onlyHistory && dumpAll) {
14737            pw.println();
14738            for (BroadcastQueue queue : mBroadcastQueues) {
14739                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14740                        + queue.mBroadcastsScheduled);
14741            }
14742            pw.println("  mHandler:");
14743            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14744            needSep = true;
14745            printedAnything = true;
14746        }
14747
14748        if (!printedAnything) {
14749            pw.println("  (nothing)");
14750        }
14751    }
14752
14753    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14754            int opti, boolean dumpAll, String dumpPackage) {
14755        boolean needSep;
14756        boolean printedAnything = false;
14757
14758        ItemMatcher matcher = new ItemMatcher();
14759        matcher.build(args, opti);
14760
14761        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14762
14763        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14764        printedAnything |= needSep;
14765
14766        if (mLaunchingProviders.size() > 0) {
14767            boolean printed = false;
14768            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14769                ContentProviderRecord r = mLaunchingProviders.get(i);
14770                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14771                    continue;
14772                }
14773                if (!printed) {
14774                    if (needSep) pw.println();
14775                    needSep = true;
14776                    pw.println("  Launching content providers:");
14777                    printed = true;
14778                    printedAnything = true;
14779                }
14780                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14781                        pw.println(r);
14782            }
14783        }
14784
14785        if (!printedAnything) {
14786            pw.println("  (nothing)");
14787        }
14788    }
14789
14790    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14791            int opti, boolean dumpAll, String dumpPackage) {
14792        boolean needSep = false;
14793        boolean printedAnything = false;
14794
14795        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14796
14797        if (mGrantedUriPermissions.size() > 0) {
14798            boolean printed = false;
14799            int dumpUid = -2;
14800            if (dumpPackage != null) {
14801                try {
14802                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14803                } catch (NameNotFoundException e) {
14804                    dumpUid = -1;
14805                }
14806            }
14807            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14808                int uid = mGrantedUriPermissions.keyAt(i);
14809                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14810                    continue;
14811                }
14812                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14813                if (!printed) {
14814                    if (needSep) pw.println();
14815                    needSep = true;
14816                    pw.println("  Granted Uri Permissions:");
14817                    printed = true;
14818                    printedAnything = true;
14819                }
14820                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14821                for (UriPermission perm : perms.values()) {
14822                    pw.print("    "); pw.println(perm);
14823                    if (dumpAll) {
14824                        perm.dump(pw, "      ");
14825                    }
14826                }
14827            }
14828        }
14829
14830        if (!printedAnything) {
14831            pw.println("  (nothing)");
14832        }
14833    }
14834
14835    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14836            int opti, boolean dumpAll, String dumpPackage) {
14837        boolean printed = false;
14838
14839        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14840
14841        if (mIntentSenderRecords.size() > 0) {
14842            Iterator<WeakReference<PendingIntentRecord>> it
14843                    = mIntentSenderRecords.values().iterator();
14844            while (it.hasNext()) {
14845                WeakReference<PendingIntentRecord> ref = it.next();
14846                PendingIntentRecord rec = ref != null ? ref.get(): null;
14847                if (dumpPackage != null && (rec == null
14848                        || !dumpPackage.equals(rec.key.packageName))) {
14849                    continue;
14850                }
14851                printed = true;
14852                if (rec != null) {
14853                    pw.print("  * "); pw.println(rec);
14854                    if (dumpAll) {
14855                        rec.dump(pw, "    ");
14856                    }
14857                } else {
14858                    pw.print("  * "); pw.println(ref);
14859                }
14860            }
14861        }
14862
14863        if (!printed) {
14864            pw.println("  (nothing)");
14865        }
14866    }
14867
14868    private static final int dumpProcessList(PrintWriter pw,
14869            ActivityManagerService service, List list,
14870            String prefix, String normalLabel, String persistentLabel,
14871            String dumpPackage) {
14872        int numPers = 0;
14873        final int N = list.size()-1;
14874        for (int i=N; i>=0; i--) {
14875            ProcessRecord r = (ProcessRecord)list.get(i);
14876            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14877                continue;
14878            }
14879            pw.println(String.format("%s%s #%2d: %s",
14880                    prefix, (r.persistent ? persistentLabel : normalLabel),
14881                    i, r.toString()));
14882            if (r.persistent) {
14883                numPers++;
14884            }
14885        }
14886        return numPers;
14887    }
14888
14889    private static final boolean dumpProcessOomList(PrintWriter pw,
14890            ActivityManagerService service, List<ProcessRecord> origList,
14891            String prefix, String normalLabel, String persistentLabel,
14892            boolean inclDetails, String dumpPackage) {
14893
14894        ArrayList<Pair<ProcessRecord, Integer>> list
14895                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14896        for (int i=0; i<origList.size(); i++) {
14897            ProcessRecord r = origList.get(i);
14898            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14899                continue;
14900            }
14901            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14902        }
14903
14904        if (list.size() <= 0) {
14905            return false;
14906        }
14907
14908        Comparator<Pair<ProcessRecord, Integer>> comparator
14909                = new Comparator<Pair<ProcessRecord, Integer>>() {
14910            @Override
14911            public int compare(Pair<ProcessRecord, Integer> object1,
14912                    Pair<ProcessRecord, Integer> object2) {
14913                if (object1.first.setAdj != object2.first.setAdj) {
14914                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14915                }
14916                if (object1.first.setProcState != object2.first.setProcState) {
14917                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14918                }
14919                if (object1.second.intValue() != object2.second.intValue()) {
14920                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14921                }
14922                return 0;
14923            }
14924        };
14925
14926        Collections.sort(list, comparator);
14927
14928        final long curRealtime = SystemClock.elapsedRealtime();
14929        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14930        final long curUptime = SystemClock.uptimeMillis();
14931        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14932
14933        for (int i=list.size()-1; i>=0; i--) {
14934            ProcessRecord r = list.get(i).first;
14935            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14936            char schedGroup;
14937            switch (r.setSchedGroup) {
14938                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14939                    schedGroup = 'B';
14940                    break;
14941                case Process.THREAD_GROUP_DEFAULT:
14942                    schedGroup = 'F';
14943                    break;
14944                default:
14945                    schedGroup = '?';
14946                    break;
14947            }
14948            char foreground;
14949            if (r.foregroundActivities) {
14950                foreground = 'A';
14951            } else if (r.foregroundServices) {
14952                foreground = 'S';
14953            } else {
14954                foreground = ' ';
14955            }
14956            String procState = ProcessList.makeProcStateString(r.curProcState);
14957            pw.print(prefix);
14958            pw.print(r.persistent ? persistentLabel : normalLabel);
14959            pw.print(" #");
14960            int num = (origList.size()-1)-list.get(i).second;
14961            if (num < 10) pw.print(' ');
14962            pw.print(num);
14963            pw.print(": ");
14964            pw.print(oomAdj);
14965            pw.print(' ');
14966            pw.print(schedGroup);
14967            pw.print('/');
14968            pw.print(foreground);
14969            pw.print('/');
14970            pw.print(procState);
14971            pw.print(" trm:");
14972            if (r.trimMemoryLevel < 10) pw.print(' ');
14973            pw.print(r.trimMemoryLevel);
14974            pw.print(' ');
14975            pw.print(r.toShortString());
14976            pw.print(" (");
14977            pw.print(r.adjType);
14978            pw.println(')');
14979            if (r.adjSource != null || r.adjTarget != null) {
14980                pw.print(prefix);
14981                pw.print("    ");
14982                if (r.adjTarget instanceof ComponentName) {
14983                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14984                } else if (r.adjTarget != null) {
14985                    pw.print(r.adjTarget.toString());
14986                } else {
14987                    pw.print("{null}");
14988                }
14989                pw.print("<=");
14990                if (r.adjSource instanceof ProcessRecord) {
14991                    pw.print("Proc{");
14992                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14993                    pw.println("}");
14994                } else if (r.adjSource != null) {
14995                    pw.println(r.adjSource.toString());
14996                } else {
14997                    pw.println("{null}");
14998                }
14999            }
15000            if (inclDetails) {
15001                pw.print(prefix);
15002                pw.print("    ");
15003                pw.print("oom: max="); pw.print(r.maxAdj);
15004                pw.print(" curRaw="); pw.print(r.curRawAdj);
15005                pw.print(" setRaw="); pw.print(r.setRawAdj);
15006                pw.print(" cur="); pw.print(r.curAdj);
15007                pw.print(" set="); pw.println(r.setAdj);
15008                pw.print(prefix);
15009                pw.print("    ");
15010                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15011                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15012                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15013                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15014                pw.println();
15015                pw.print(prefix);
15016                pw.print("    ");
15017                pw.print("cached="); pw.print(r.cached);
15018                pw.print(" empty="); pw.print(r.empty);
15019                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15020
15021                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15022                    if (r.lastWakeTime != 0) {
15023                        long wtime;
15024                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15025                        synchronized (stats) {
15026                            wtime = stats.getProcessWakeTime(r.info.uid,
15027                                    r.pid, curRealtime);
15028                        }
15029                        long timeUsed = wtime - r.lastWakeTime;
15030                        pw.print(prefix);
15031                        pw.print("    ");
15032                        pw.print("keep awake over ");
15033                        TimeUtils.formatDuration(realtimeSince, pw);
15034                        pw.print(" used ");
15035                        TimeUtils.formatDuration(timeUsed, pw);
15036                        pw.print(" (");
15037                        pw.print((timeUsed*100)/realtimeSince);
15038                        pw.println("%)");
15039                    }
15040                    if (r.lastCpuTime != 0) {
15041                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15042                        pw.print(prefix);
15043                        pw.print("    ");
15044                        pw.print("run cpu over ");
15045                        TimeUtils.formatDuration(uptimeSince, pw);
15046                        pw.print(" used ");
15047                        TimeUtils.formatDuration(timeUsed, pw);
15048                        pw.print(" (");
15049                        pw.print((timeUsed*100)/uptimeSince);
15050                        pw.println("%)");
15051                    }
15052                }
15053            }
15054        }
15055        return true;
15056    }
15057
15058    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15059            String[] args) {
15060        ArrayList<ProcessRecord> procs;
15061        synchronized (this) {
15062            if (args != null && args.length > start
15063                    && args[start].charAt(0) != '-') {
15064                procs = new ArrayList<ProcessRecord>();
15065                int pid = -1;
15066                try {
15067                    pid = Integer.parseInt(args[start]);
15068                } catch (NumberFormatException e) {
15069                }
15070                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15071                    ProcessRecord proc = mLruProcesses.get(i);
15072                    if (proc.pid == pid) {
15073                        procs.add(proc);
15074                    } else if (allPkgs && proc.pkgList != null
15075                            && proc.pkgList.containsKey(args[start])) {
15076                        procs.add(proc);
15077                    } else if (proc.processName.equals(args[start])) {
15078                        procs.add(proc);
15079                    }
15080                }
15081                if (procs.size() <= 0) {
15082                    return null;
15083                }
15084            } else {
15085                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15086            }
15087        }
15088        return procs;
15089    }
15090
15091    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15092            PrintWriter pw, String[] args) {
15093        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15094        if (procs == null) {
15095            pw.println("No process found for: " + args[0]);
15096            return;
15097        }
15098
15099        long uptime = SystemClock.uptimeMillis();
15100        long realtime = SystemClock.elapsedRealtime();
15101        pw.println("Applications Graphics Acceleration Info:");
15102        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15103
15104        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15105            ProcessRecord r = procs.get(i);
15106            if (r.thread != null) {
15107                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15108                pw.flush();
15109                try {
15110                    TransferPipe tp = new TransferPipe();
15111                    try {
15112                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15113                        tp.go(fd);
15114                    } finally {
15115                        tp.kill();
15116                    }
15117                } catch (IOException e) {
15118                    pw.println("Failure while dumping the app: " + r);
15119                    pw.flush();
15120                } catch (RemoteException e) {
15121                    pw.println("Got a RemoteException while dumping the app " + r);
15122                    pw.flush();
15123                }
15124            }
15125        }
15126    }
15127
15128    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15129        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15130        if (procs == null) {
15131            pw.println("No process found for: " + args[0]);
15132            return;
15133        }
15134
15135        pw.println("Applications Database Info:");
15136
15137        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15138            ProcessRecord r = procs.get(i);
15139            if (r.thread != null) {
15140                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15141                pw.flush();
15142                try {
15143                    TransferPipe tp = new TransferPipe();
15144                    try {
15145                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15146                        tp.go(fd);
15147                    } finally {
15148                        tp.kill();
15149                    }
15150                } catch (IOException e) {
15151                    pw.println("Failure while dumping the app: " + r);
15152                    pw.flush();
15153                } catch (RemoteException e) {
15154                    pw.println("Got a RemoteException while dumping the app " + r);
15155                    pw.flush();
15156                }
15157            }
15158        }
15159    }
15160
15161    final static class MemItem {
15162        final boolean isProc;
15163        final String label;
15164        final String shortLabel;
15165        final long pss;
15166        final int id;
15167        final boolean hasActivities;
15168        ArrayList<MemItem> subitems;
15169
15170        public MemItem(String _label, String _shortLabel, long _pss, int _id,
15171                boolean _hasActivities) {
15172            isProc = true;
15173            label = _label;
15174            shortLabel = _shortLabel;
15175            pss = _pss;
15176            id = _id;
15177            hasActivities = _hasActivities;
15178        }
15179
15180        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
15181            isProc = false;
15182            label = _label;
15183            shortLabel = _shortLabel;
15184            pss = _pss;
15185            id = _id;
15186            hasActivities = false;
15187        }
15188    }
15189
15190    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15191            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
15192        if (sort && !isCompact) {
15193            Collections.sort(items, new Comparator<MemItem>() {
15194                @Override
15195                public int compare(MemItem lhs, MemItem rhs) {
15196                    if (lhs.pss < rhs.pss) {
15197                        return 1;
15198                    } else if (lhs.pss > rhs.pss) {
15199                        return -1;
15200                    }
15201                    return 0;
15202                }
15203            });
15204        }
15205
15206        for (int i=0; i<items.size(); i++) {
15207            MemItem mi = items.get(i);
15208            if (!isCompact) {
15209                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15210            } else if (mi.isProc) {
15211                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15212                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
15213                pw.println(mi.hasActivities ? ",a" : ",e");
15214            } else {
15215                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15216                pw.println(mi.pss);
15217            }
15218            if (mi.subitems != null) {
15219                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
15220                        true, isCompact);
15221            }
15222        }
15223    }
15224
15225    // These are in KB.
15226    static final long[] DUMP_MEM_BUCKETS = new long[] {
15227        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15228        120*1024, 160*1024, 200*1024,
15229        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15230        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15231    };
15232
15233    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15234            boolean stackLike) {
15235        int start = label.lastIndexOf('.');
15236        if (start >= 0) start++;
15237        else start = 0;
15238        int end = label.length();
15239        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15240            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15241                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15242                out.append(bucket);
15243                out.append(stackLike ? "MB." : "MB ");
15244                out.append(label, start, end);
15245                return;
15246            }
15247        }
15248        out.append(memKB/1024);
15249        out.append(stackLike ? "MB." : "MB ");
15250        out.append(label, start, end);
15251    }
15252
15253    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15254            ProcessList.NATIVE_ADJ,
15255            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15256            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15257            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15258            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15259            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15260            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15261    };
15262    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15263            "Native",
15264            "System", "Persistent", "Persistent Service", "Foreground",
15265            "Visible", "Perceptible",
15266            "Heavy Weight", "Backup",
15267            "A Services", "Home",
15268            "Previous", "B Services", "Cached"
15269    };
15270    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15271            "native",
15272            "sys", "pers", "persvc", "fore",
15273            "vis", "percept",
15274            "heavy", "backup",
15275            "servicea", "home",
15276            "prev", "serviceb", "cached"
15277    };
15278
15279    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15280            long realtime, boolean isCheckinRequest, boolean isCompact) {
15281        if (isCheckinRequest || isCompact) {
15282            // short checkin version
15283            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15284        } else {
15285            pw.println("Applications Memory Usage (in Kilobytes):");
15286            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15287        }
15288    }
15289
15290    private static final int KSM_SHARED = 0;
15291    private static final int KSM_SHARING = 1;
15292    private static final int KSM_UNSHARED = 2;
15293    private static final int KSM_VOLATILE = 3;
15294
15295    private final long[] getKsmInfo() {
15296        long[] longOut = new long[4];
15297        final int[] SINGLE_LONG_FORMAT = new int[] {
15298            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15299        };
15300        long[] longTmp = new long[1];
15301        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15302                SINGLE_LONG_FORMAT, null, longTmp, null);
15303        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15304        longTmp[0] = 0;
15305        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15306                SINGLE_LONG_FORMAT, null, longTmp, null);
15307        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15308        longTmp[0] = 0;
15309        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15310                SINGLE_LONG_FORMAT, null, longTmp, null);
15311        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15312        longTmp[0] = 0;
15313        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15314                SINGLE_LONG_FORMAT, null, longTmp, null);
15315        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15316        return longOut;
15317    }
15318
15319    private static String stringifySize(long size, int order) {
15320        Locale locale = Locale.US;
15321        switch (order) {
15322            case 1:
15323                return String.format(locale, "%,13d", size);
15324            case 1024:
15325                return String.format(locale, "%,9dK", size / 1024);
15326            case 1024 * 1024:
15327                return String.format(locale, "%,5dM", size / 1024 / 1024);
15328            case 1024 * 1024 * 1024:
15329                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15330            default:
15331                throw new IllegalArgumentException("Invalid size order");
15332        }
15333    }
15334
15335    private static String stringifyKBSize(long size) {
15336        return stringifySize(size * 1024, 1024);
15337    }
15338
15339    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15340            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15341        boolean dumpDetails = false;
15342        boolean dumpFullDetails = false;
15343        boolean dumpDalvik = false;
15344        boolean dumpSummaryOnly = false;
15345        boolean oomOnly = false;
15346        boolean isCompact = false;
15347        boolean localOnly = false;
15348        boolean packages = false;
15349
15350        int opti = 0;
15351        while (opti < args.length) {
15352            String opt = args[opti];
15353            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15354                break;
15355            }
15356            opti++;
15357            if ("-a".equals(opt)) {
15358                dumpDetails = true;
15359                dumpFullDetails = true;
15360                dumpDalvik = true;
15361            } else if ("-d".equals(opt)) {
15362                dumpDalvik = true;
15363            } else if ("-c".equals(opt)) {
15364                isCompact = true;
15365            } else if ("-s".equals(opt)) {
15366                dumpDetails = true;
15367                dumpSummaryOnly = true;
15368            } else if ("--oom".equals(opt)) {
15369                oomOnly = true;
15370            } else if ("--local".equals(opt)) {
15371                localOnly = true;
15372            } else if ("--package".equals(opt)) {
15373                packages = true;
15374            } else if ("-h".equals(opt)) {
15375                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15376                pw.println("  -a: include all available information for each process.");
15377                pw.println("  -d: include dalvik details.");
15378                pw.println("  -c: dump in a compact machine-parseable representation.");
15379                pw.println("  -s: dump only summary of application memory usage.");
15380                pw.println("  --oom: only show processes organized by oom adj.");
15381                pw.println("  --local: only collect details locally, don't call process.");
15382                pw.println("  --package: interpret process arg as package, dumping all");
15383                pw.println("             processes that have loaded that package.");
15384                pw.println("If [process] is specified it can be the name or ");
15385                pw.println("pid of a specific process to dump.");
15386                return;
15387            } else {
15388                pw.println("Unknown argument: " + opt + "; use -h for help");
15389            }
15390        }
15391
15392        final boolean isCheckinRequest = scanArgs(args, "--checkin");
15393        long uptime = SystemClock.uptimeMillis();
15394        long realtime = SystemClock.elapsedRealtime();
15395        final long[] tmpLong = new long[1];
15396
15397        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15398        if (procs == null) {
15399            // No Java processes.  Maybe they want to print a native process.
15400            if (args != null && args.length > opti
15401                    && args[opti].charAt(0) != '-') {
15402                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15403                        = new ArrayList<ProcessCpuTracker.Stats>();
15404                updateCpuStatsNow();
15405                int findPid = -1;
15406                try {
15407                    findPid = Integer.parseInt(args[opti]);
15408                } catch (NumberFormatException e) {
15409                }
15410                synchronized (mProcessCpuTracker) {
15411                    final int N = mProcessCpuTracker.countStats();
15412                    for (int i=0; i<N; i++) {
15413                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15414                        if (st.pid == findPid || (st.baseName != null
15415                                && st.baseName.equals(args[opti]))) {
15416                            nativeProcs.add(st);
15417                        }
15418                    }
15419                }
15420                if (nativeProcs.size() > 0) {
15421                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15422                            isCompact);
15423                    Debug.MemoryInfo mi = null;
15424                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15425                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15426                        final int pid = r.pid;
15427                        if (!isCheckinRequest && dumpDetails) {
15428                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15429                        }
15430                        if (mi == null) {
15431                            mi = new Debug.MemoryInfo();
15432                        }
15433                        if (dumpDetails || (!brief && !oomOnly)) {
15434                            Debug.getMemoryInfo(pid, mi);
15435                        } else {
15436                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15437                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15438                        }
15439                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15440                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15441                        if (isCheckinRequest) {
15442                            pw.println();
15443                        }
15444                    }
15445                    return;
15446                }
15447            }
15448            pw.println("No process found for: " + args[opti]);
15449            return;
15450        }
15451
15452        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15453            dumpDetails = true;
15454        }
15455
15456        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15457
15458        String[] innerArgs = new String[args.length-opti];
15459        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15460
15461        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15462        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15463        long nativePss = 0;
15464        long dalvikPss = 0;
15465        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15466                EmptyArray.LONG;
15467        long otherPss = 0;
15468        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15469
15470        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15471        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15472                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15473
15474        long totalPss = 0;
15475        long cachedPss = 0;
15476
15477        Debug.MemoryInfo mi = null;
15478        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15479            final ProcessRecord r = procs.get(i);
15480            final IApplicationThread thread;
15481            final int pid;
15482            final int oomAdj;
15483            final boolean hasActivities;
15484            synchronized (this) {
15485                thread = r.thread;
15486                pid = r.pid;
15487                oomAdj = r.getSetAdjWithServices();
15488                hasActivities = r.activities.size() > 0;
15489            }
15490            if (thread != null) {
15491                if (!isCheckinRequest && dumpDetails) {
15492                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15493                }
15494                if (mi == null) {
15495                    mi = new Debug.MemoryInfo();
15496                }
15497                if (dumpDetails || (!brief && !oomOnly)) {
15498                    Debug.getMemoryInfo(pid, mi);
15499                } else {
15500                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15501                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15502                }
15503                if (dumpDetails) {
15504                    if (localOnly) {
15505                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15506                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15507                        if (isCheckinRequest) {
15508                            pw.println();
15509                        }
15510                    } else {
15511                        try {
15512                            pw.flush();
15513                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15514                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15515                        } catch (RemoteException e) {
15516                            if (!isCheckinRequest) {
15517                                pw.println("Got RemoteException!");
15518                                pw.flush();
15519                            }
15520                        }
15521                    }
15522                }
15523
15524                final long myTotalPss = mi.getTotalPss();
15525                final long myTotalUss = mi.getTotalUss();
15526
15527                synchronized (this) {
15528                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15529                        // Record this for posterity if the process has been stable.
15530                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15531                    }
15532                }
15533
15534                if (!isCheckinRequest && mi != null) {
15535                    totalPss += myTotalPss;
15536                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15537                            (hasActivities ? " / activities)" : ")"),
15538                            r.processName, myTotalPss, pid, hasActivities);
15539                    procMems.add(pssItem);
15540                    procMemsMap.put(pid, pssItem);
15541
15542                    nativePss += mi.nativePss;
15543                    dalvikPss += mi.dalvikPss;
15544                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15545                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15546                    }
15547                    otherPss += mi.otherPss;
15548                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15549                        long mem = mi.getOtherPss(j);
15550                        miscPss[j] += mem;
15551                        otherPss -= mem;
15552                    }
15553
15554                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15555                        cachedPss += myTotalPss;
15556                    }
15557
15558                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15559                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15560                                || oomIndex == (oomPss.length-1)) {
15561                            oomPss[oomIndex] += myTotalPss;
15562                            if (oomProcs[oomIndex] == null) {
15563                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15564                            }
15565                            oomProcs[oomIndex].add(pssItem);
15566                            break;
15567                        }
15568                    }
15569                }
15570            }
15571        }
15572
15573        long nativeProcTotalPss = 0;
15574
15575        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15576            // If we are showing aggregations, also look for native processes to
15577            // include so that our aggregations are more accurate.
15578            updateCpuStatsNow();
15579            mi = null;
15580            synchronized (mProcessCpuTracker) {
15581                final int N = mProcessCpuTracker.countStats();
15582                for (int i=0; i<N; i++) {
15583                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15584                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15585                        if (mi == null) {
15586                            mi = new Debug.MemoryInfo();
15587                        }
15588                        if (!brief && !oomOnly) {
15589                            Debug.getMemoryInfo(st.pid, mi);
15590                        } else {
15591                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15592                            mi.nativePrivateDirty = (int)tmpLong[0];
15593                        }
15594
15595                        final long myTotalPss = mi.getTotalPss();
15596                        totalPss += myTotalPss;
15597                        nativeProcTotalPss += myTotalPss;
15598
15599                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15600                                st.name, myTotalPss, st.pid, false);
15601                        procMems.add(pssItem);
15602
15603                        nativePss += mi.nativePss;
15604                        dalvikPss += mi.dalvikPss;
15605                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15606                            dalvikSubitemPss[j] += mi.getOtherPss(
15607                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15608                        }
15609                        otherPss += mi.otherPss;
15610                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15611                            long mem = mi.getOtherPss(j);
15612                            miscPss[j] += mem;
15613                            otherPss -= mem;
15614                        }
15615                        oomPss[0] += myTotalPss;
15616                        if (oomProcs[0] == null) {
15617                            oomProcs[0] = new ArrayList<MemItem>();
15618                        }
15619                        oomProcs[0].add(pssItem);
15620                    }
15621                }
15622            }
15623
15624            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15625
15626            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15627            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15628            if (dalvikSubitemPss.length > 0) {
15629                dalvikItem.subitems = new ArrayList<MemItem>();
15630                for (int j=0; j<dalvikSubitemPss.length; j++) {
15631                    final String name = Debug.MemoryInfo.getOtherLabel(
15632                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15633                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15634                }
15635            }
15636            catMems.add(dalvikItem);
15637            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15638            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15639                String label = Debug.MemoryInfo.getOtherLabel(j);
15640                catMems.add(new MemItem(label, label, miscPss[j], j));
15641            }
15642
15643            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15644            for (int j=0; j<oomPss.length; j++) {
15645                if (oomPss[j] != 0) {
15646                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15647                            : DUMP_MEM_OOM_LABEL[j];
15648                    MemItem item = new MemItem(label, label, oomPss[j],
15649                            DUMP_MEM_OOM_ADJ[j]);
15650                    item.subitems = oomProcs[j];
15651                    oomMems.add(item);
15652                }
15653            }
15654
15655            if (!brief && !oomOnly && !isCompact) {
15656                pw.println();
15657                pw.println("Total PSS by process:");
15658                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15659                pw.println();
15660            }
15661            if (!isCompact) {
15662                pw.println("Total PSS by OOM adjustment:");
15663            }
15664            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15665            if (!brief && !oomOnly) {
15666                PrintWriter out = categoryPw != null ? categoryPw : pw;
15667                if (!isCompact) {
15668                    out.println();
15669                    out.println("Total PSS by category:");
15670                }
15671                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15672            }
15673            if (!isCompact) {
15674                pw.println();
15675            }
15676            MemInfoReader memInfo = new MemInfoReader();
15677            memInfo.readMemInfo();
15678            if (nativeProcTotalPss > 0) {
15679                synchronized (this) {
15680                    final long cachedKb = memInfo.getCachedSizeKb();
15681                    final long freeKb = memInfo.getFreeSizeKb();
15682                    final long zramKb = memInfo.getZramTotalSizeKb();
15683                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15684                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15685                            kernelKb*1024, nativeProcTotalPss*1024);
15686                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15687                            nativeProcTotalPss);
15688                }
15689            }
15690            if (!brief) {
15691                if (!isCompact) {
15692                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15693                    pw.print(" (status ");
15694                    switch (mLastMemoryLevel) {
15695                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15696                            pw.println("normal)");
15697                            break;
15698                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15699                            pw.println("moderate)");
15700                            break;
15701                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15702                            pw.println("low)");
15703                            break;
15704                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15705                            pw.println("critical)");
15706                            break;
15707                        default:
15708                            pw.print(mLastMemoryLevel);
15709                            pw.println(")");
15710                            break;
15711                    }
15712                    pw.print(" Free RAM: ");
15713                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15714                            + memInfo.getFreeSizeKb()));
15715                    pw.print(" (");
15716                    pw.print(stringifyKBSize(cachedPss));
15717                    pw.print(" cached pss + ");
15718                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15719                    pw.print(" cached kernel + ");
15720                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15721                    pw.println(" free)");
15722                } else {
15723                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15724                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15725                            + memInfo.getFreeSizeKb()); pw.print(",");
15726                    pw.println(totalPss - cachedPss);
15727                }
15728            }
15729            if (!isCompact) {
15730                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15731                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15732                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15733                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15734                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15735                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15736                        - memInfo.getKernelUsedSizeKb()));
15737            } else {
15738                pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15739                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15740                        - memInfo.getKernelUsedSizeKb());
15741            }
15742            if (!brief) {
15743                if (memInfo.getZramTotalSizeKb() != 0) {
15744                    if (!isCompact) {
15745                        pw.print("     ZRAM: ");
15746                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15747                                pw.print(" physical used for ");
15748                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15749                                        - memInfo.getSwapFreeSizeKb()));
15750                                pw.print(" in swap (");
15751                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15752                                pw.println(" total swap)");
15753                    } else {
15754                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15755                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15756                                pw.println(memInfo.getSwapFreeSizeKb());
15757                    }
15758                }
15759                final long[] ksm = getKsmInfo();
15760                if (!isCompact) {
15761                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15762                            || ksm[KSM_VOLATILE] != 0) {
15763                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15764                                pw.print(" saved from shared ");
15765                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15766                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15767                                pw.print(" unshared; ");
15768                                pw.print(stringifyKBSize(
15769                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15770                    }
15771                    pw.print("   Tuning: ");
15772                    pw.print(ActivityManager.staticGetMemoryClass());
15773                    pw.print(" (large ");
15774                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15775                    pw.print("), oom ");
15776                    pw.print(stringifySize(
15777                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15778                    pw.print(", restore limit ");
15779                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15780                    if (ActivityManager.isLowRamDeviceStatic()) {
15781                        pw.print(" (low-ram)");
15782                    }
15783                    if (ActivityManager.isHighEndGfx()) {
15784                        pw.print(" (high-end-gfx)");
15785                    }
15786                    pw.println();
15787                } else {
15788                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15789                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15790                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15791                    pw.print("tuning,");
15792                    pw.print(ActivityManager.staticGetMemoryClass());
15793                    pw.print(',');
15794                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15795                    pw.print(',');
15796                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15797                    if (ActivityManager.isLowRamDeviceStatic()) {
15798                        pw.print(",low-ram");
15799                    }
15800                    if (ActivityManager.isHighEndGfx()) {
15801                        pw.print(",high-end-gfx");
15802                    }
15803                    pw.println();
15804                }
15805            }
15806        }
15807    }
15808
15809    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15810            long memtrack, String name) {
15811        sb.append("  ");
15812        sb.append(ProcessList.makeOomAdjString(oomAdj));
15813        sb.append(' ');
15814        sb.append(ProcessList.makeProcStateString(procState));
15815        sb.append(' ');
15816        ProcessList.appendRamKb(sb, pss);
15817        sb.append(": ");
15818        sb.append(name);
15819        if (memtrack > 0) {
15820            sb.append(" (");
15821            sb.append(stringifyKBSize(memtrack));
15822            sb.append(" memtrack)");
15823        }
15824    }
15825
15826    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15827        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15828        sb.append(" (pid ");
15829        sb.append(mi.pid);
15830        sb.append(") ");
15831        sb.append(mi.adjType);
15832        sb.append('\n');
15833        if (mi.adjReason != null) {
15834            sb.append("                      ");
15835            sb.append(mi.adjReason);
15836            sb.append('\n');
15837        }
15838    }
15839
15840    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15841        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15842        for (int i=0, N=memInfos.size(); i<N; i++) {
15843            ProcessMemInfo mi = memInfos.get(i);
15844            infoMap.put(mi.pid, mi);
15845        }
15846        updateCpuStatsNow();
15847        long[] memtrackTmp = new long[1];
15848        synchronized (mProcessCpuTracker) {
15849            final int N = mProcessCpuTracker.countStats();
15850            for (int i=0; i<N; i++) {
15851                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15852                if (st.vsize > 0) {
15853                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15854                    if (pss > 0) {
15855                        if (infoMap.indexOfKey(st.pid) < 0) {
15856                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15857                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15858                            mi.pss = pss;
15859                            mi.memtrack = memtrackTmp[0];
15860                            memInfos.add(mi);
15861                        }
15862                    }
15863                }
15864            }
15865        }
15866
15867        long totalPss = 0;
15868        long totalMemtrack = 0;
15869        for (int i=0, N=memInfos.size(); i<N; i++) {
15870            ProcessMemInfo mi = memInfos.get(i);
15871            if (mi.pss == 0) {
15872                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15873                mi.memtrack = memtrackTmp[0];
15874            }
15875            totalPss += mi.pss;
15876            totalMemtrack += mi.memtrack;
15877        }
15878        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15879            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15880                if (lhs.oomAdj != rhs.oomAdj) {
15881                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15882                }
15883                if (lhs.pss != rhs.pss) {
15884                    return lhs.pss < rhs.pss ? 1 : -1;
15885                }
15886                return 0;
15887            }
15888        });
15889
15890        StringBuilder tag = new StringBuilder(128);
15891        StringBuilder stack = new StringBuilder(128);
15892        tag.append("Low on memory -- ");
15893        appendMemBucket(tag, totalPss, "total", false);
15894        appendMemBucket(stack, totalPss, "total", true);
15895
15896        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15897        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15898        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15899
15900        boolean firstLine = true;
15901        int lastOomAdj = Integer.MIN_VALUE;
15902        long extraNativeRam = 0;
15903        long extraNativeMemtrack = 0;
15904        long cachedPss = 0;
15905        for (int i=0, N=memInfos.size(); i<N; i++) {
15906            ProcessMemInfo mi = memInfos.get(i);
15907
15908            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15909                cachedPss += mi.pss;
15910            }
15911
15912            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15913                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15914                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15915                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15916                if (lastOomAdj != mi.oomAdj) {
15917                    lastOomAdj = mi.oomAdj;
15918                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15919                        tag.append(" / ");
15920                    }
15921                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15922                        if (firstLine) {
15923                            stack.append(":");
15924                            firstLine = false;
15925                        }
15926                        stack.append("\n\t at ");
15927                    } else {
15928                        stack.append("$");
15929                    }
15930                } else {
15931                    tag.append(" ");
15932                    stack.append("$");
15933                }
15934                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15935                    appendMemBucket(tag, mi.pss, mi.name, false);
15936                }
15937                appendMemBucket(stack, mi.pss, mi.name, true);
15938                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15939                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15940                    stack.append("(");
15941                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15942                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15943                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15944                            stack.append(":");
15945                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15946                        }
15947                    }
15948                    stack.append(")");
15949                }
15950            }
15951
15952            appendMemInfo(fullNativeBuilder, mi);
15953            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15954                // The short form only has native processes that are >= 512K.
15955                if (mi.pss >= 512) {
15956                    appendMemInfo(shortNativeBuilder, mi);
15957                } else {
15958                    extraNativeRam += mi.pss;
15959                    extraNativeMemtrack += mi.memtrack;
15960                }
15961            } else {
15962                // Short form has all other details, but if we have collected RAM
15963                // from smaller native processes let's dump a summary of that.
15964                if (extraNativeRam > 0) {
15965                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15966                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15967                    shortNativeBuilder.append('\n');
15968                    extraNativeRam = 0;
15969                }
15970                appendMemInfo(fullJavaBuilder, mi);
15971            }
15972        }
15973
15974        fullJavaBuilder.append("           ");
15975        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15976        fullJavaBuilder.append(": TOTAL");
15977        if (totalMemtrack > 0) {
15978            fullJavaBuilder.append(" (");
15979            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15980            fullJavaBuilder.append(" memtrack)");
15981        } else {
15982        }
15983        fullJavaBuilder.append("\n");
15984
15985        MemInfoReader memInfo = new MemInfoReader();
15986        memInfo.readMemInfo();
15987        final long[] infos = memInfo.getRawInfo();
15988
15989        StringBuilder memInfoBuilder = new StringBuilder(1024);
15990        Debug.getMemInfo(infos);
15991        memInfoBuilder.append("  MemInfo: ");
15992        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15993        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15994        memInfoBuilder.append(stringifyKBSize(
15995                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15996        memInfoBuilder.append(stringifyKBSize(
15997                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15998        memInfoBuilder.append(stringifyKBSize(
15999                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16000        memInfoBuilder.append("           ");
16001        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16002        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16003        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16004        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16005        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16006            memInfoBuilder.append("  ZRAM: ");
16007            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16008            memInfoBuilder.append(" RAM, ");
16009            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16010            memInfoBuilder.append(" swap total, ");
16011            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16012            memInfoBuilder.append(" swap free\n");
16013        }
16014        final long[] ksm = getKsmInfo();
16015        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16016                || ksm[KSM_VOLATILE] != 0) {
16017            memInfoBuilder.append("  KSM: ");
16018            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16019            memInfoBuilder.append(" saved from shared ");
16020            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16021            memInfoBuilder.append("\n       ");
16022            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16023            memInfoBuilder.append(" unshared; ");
16024            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16025            memInfoBuilder.append(" volatile\n");
16026        }
16027        memInfoBuilder.append("  Free RAM: ");
16028        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16029                + memInfo.getFreeSizeKb()));
16030        memInfoBuilder.append("\n");
16031        memInfoBuilder.append("  Used RAM: ");
16032        memInfoBuilder.append(stringifyKBSize(
16033                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16034        memInfoBuilder.append("\n");
16035        memInfoBuilder.append("  Lost RAM: ");
16036        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16037                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16038                - memInfo.getKernelUsedSizeKb()));
16039        memInfoBuilder.append("\n");
16040        Slog.i(TAG, "Low on memory:");
16041        Slog.i(TAG, shortNativeBuilder.toString());
16042        Slog.i(TAG, fullJavaBuilder.toString());
16043        Slog.i(TAG, memInfoBuilder.toString());
16044
16045        StringBuilder dropBuilder = new StringBuilder(1024);
16046        /*
16047        StringWriter oomSw = new StringWriter();
16048        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16049        StringWriter catSw = new StringWriter();
16050        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16051        String[] emptyArgs = new String[] { };
16052        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16053        oomPw.flush();
16054        String oomString = oomSw.toString();
16055        */
16056        dropBuilder.append("Low on memory:");
16057        dropBuilder.append(stack);
16058        dropBuilder.append('\n');
16059        dropBuilder.append(fullNativeBuilder);
16060        dropBuilder.append(fullJavaBuilder);
16061        dropBuilder.append('\n');
16062        dropBuilder.append(memInfoBuilder);
16063        dropBuilder.append('\n');
16064        /*
16065        dropBuilder.append(oomString);
16066        dropBuilder.append('\n');
16067        */
16068        StringWriter catSw = new StringWriter();
16069        synchronized (ActivityManagerService.this) {
16070            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16071            String[] emptyArgs = new String[] { };
16072            catPw.println();
16073            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16074            catPw.println();
16075            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16076                    false, false, null);
16077            catPw.println();
16078            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16079            catPw.flush();
16080        }
16081        dropBuilder.append(catSw.toString());
16082        addErrorToDropBox("lowmem", null, "system_server", null,
16083                null, tag.toString(), dropBuilder.toString(), null, null);
16084        //Slog.i(TAG, "Sent to dropbox:");
16085        //Slog.i(TAG, dropBuilder.toString());
16086        synchronized (ActivityManagerService.this) {
16087            long now = SystemClock.uptimeMillis();
16088            if (mLastMemUsageReportTime < now) {
16089                mLastMemUsageReportTime = now;
16090            }
16091        }
16092    }
16093
16094    /**
16095     * Searches array of arguments for the specified string
16096     * @param args array of argument strings
16097     * @param value value to search for
16098     * @return true if the value is contained in the array
16099     */
16100    private static boolean scanArgs(String[] args, String value) {
16101        if (args != null) {
16102            for (String arg : args) {
16103                if (value.equals(arg)) {
16104                    return true;
16105                }
16106            }
16107        }
16108        return false;
16109    }
16110
16111    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16112            ContentProviderRecord cpr, boolean always) {
16113        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16114
16115        if (!inLaunching || always) {
16116            synchronized (cpr) {
16117                cpr.launchingApp = null;
16118                cpr.notifyAll();
16119            }
16120            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16121            String names[] = cpr.info.authority.split(";");
16122            for (int j = 0; j < names.length; j++) {
16123                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16124            }
16125        }
16126
16127        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16128            ContentProviderConnection conn = cpr.connections.get(i);
16129            if (conn.waiting) {
16130                // If this connection is waiting for the provider, then we don't
16131                // need to mess with its process unless we are always removing
16132                // or for some reason the provider is not currently launching.
16133                if (inLaunching && !always) {
16134                    continue;
16135                }
16136            }
16137            ProcessRecord capp = conn.client;
16138            conn.dead = true;
16139            if (conn.stableCount > 0) {
16140                if (!capp.persistent && capp.thread != null
16141                        && capp.pid != 0
16142                        && capp.pid != MY_PID) {
16143                    capp.kill("depends on provider "
16144                            + cpr.name.flattenToShortString()
16145                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16146                }
16147            } else if (capp.thread != null && conn.provider.provider != null) {
16148                try {
16149                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16150                } catch (RemoteException e) {
16151                }
16152                // In the protocol here, we don't expect the client to correctly
16153                // clean up this connection, we'll just remove it.
16154                cpr.connections.remove(i);
16155                if (conn.client.conProviders.remove(conn)) {
16156                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16157                }
16158            }
16159        }
16160
16161        if (inLaunching && always) {
16162            mLaunchingProviders.remove(cpr);
16163        }
16164        return inLaunching;
16165    }
16166
16167    /**
16168     * Main code for cleaning up a process when it has gone away.  This is
16169     * called both as a result of the process dying, or directly when stopping
16170     * a process when running in single process mode.
16171     *
16172     * @return Returns true if the given process has been restarted, so the
16173     * app that was passed in must remain on the process lists.
16174     */
16175    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16176            boolean restarting, boolean allowRestart, int index) {
16177        if (index >= 0) {
16178            removeLruProcessLocked(app);
16179            ProcessList.remove(app.pid);
16180        }
16181
16182        mProcessesToGc.remove(app);
16183        mPendingPssProcesses.remove(app);
16184
16185        // Dismiss any open dialogs.
16186        if (app.crashDialog != null && !app.forceCrashReport) {
16187            app.crashDialog.dismiss();
16188            app.crashDialog = null;
16189        }
16190        if (app.anrDialog != null) {
16191            app.anrDialog.dismiss();
16192            app.anrDialog = null;
16193        }
16194        if (app.waitDialog != null) {
16195            app.waitDialog.dismiss();
16196            app.waitDialog = null;
16197        }
16198
16199        app.crashing = false;
16200        app.notResponding = false;
16201
16202        app.resetPackageList(mProcessStats);
16203        app.unlinkDeathRecipient();
16204        app.makeInactive(mProcessStats);
16205        app.waitingToKill = null;
16206        app.forcingToForeground = null;
16207        updateProcessForegroundLocked(app, false, false);
16208        app.foregroundActivities = false;
16209        app.hasShownUi = false;
16210        app.treatLikeActivity = false;
16211        app.hasAboveClient = false;
16212        app.hasClientActivities = false;
16213
16214        mServices.killServicesLocked(app, allowRestart);
16215
16216        boolean restart = false;
16217
16218        // Remove published content providers.
16219        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16220            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16221            final boolean always = app.bad || !allowRestart;
16222            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16223            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16224                // We left the provider in the launching list, need to
16225                // restart it.
16226                restart = true;
16227            }
16228
16229            cpr.provider = null;
16230            cpr.proc = null;
16231        }
16232        app.pubProviders.clear();
16233
16234        // Take care of any launching providers waiting for this process.
16235        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16236            restart = true;
16237        }
16238
16239        // Unregister from connected content providers.
16240        if (!app.conProviders.isEmpty()) {
16241            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16242                ContentProviderConnection conn = app.conProviders.get(i);
16243                conn.provider.connections.remove(conn);
16244                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16245                        conn.provider.name);
16246            }
16247            app.conProviders.clear();
16248        }
16249
16250        // At this point there may be remaining entries in mLaunchingProviders
16251        // where we were the only one waiting, so they are no longer of use.
16252        // Look for these and clean up if found.
16253        // XXX Commented out for now.  Trying to figure out a way to reproduce
16254        // the actual situation to identify what is actually going on.
16255        if (false) {
16256            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16257                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16258                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16259                    synchronized (cpr) {
16260                        cpr.launchingApp = null;
16261                        cpr.notifyAll();
16262                    }
16263                }
16264            }
16265        }
16266
16267        skipCurrentReceiverLocked(app);
16268
16269        // Unregister any receivers.
16270        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16271            removeReceiverLocked(app.receivers.valueAt(i));
16272        }
16273        app.receivers.clear();
16274
16275        // If the app is undergoing backup, tell the backup manager about it
16276        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16277            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16278                    + mBackupTarget.appInfo + " died during backup");
16279            try {
16280                IBackupManager bm = IBackupManager.Stub.asInterface(
16281                        ServiceManager.getService(Context.BACKUP_SERVICE));
16282                bm.agentDisconnected(app.info.packageName);
16283            } catch (RemoteException e) {
16284                // can't happen; backup manager is local
16285            }
16286        }
16287
16288        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16289            ProcessChangeItem item = mPendingProcessChanges.get(i);
16290            if (item.pid == app.pid) {
16291                mPendingProcessChanges.remove(i);
16292                mAvailProcessChanges.add(item);
16293            }
16294        }
16295        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16296                null).sendToTarget();
16297
16298        // If the caller is restarting this app, then leave it in its
16299        // current lists and let the caller take care of it.
16300        if (restarting) {
16301            return false;
16302        }
16303
16304        if (!app.persistent || app.isolated) {
16305            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16306                    "Removing non-persistent process during cleanup: " + app);
16307            removeProcessNameLocked(app.processName, app.uid);
16308            if (mHeavyWeightProcess == app) {
16309                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16310                        mHeavyWeightProcess.userId, 0));
16311                mHeavyWeightProcess = null;
16312            }
16313        } else if (!app.removed) {
16314            // This app is persistent, so we need to keep its record around.
16315            // If it is not already on the pending app list, add it there
16316            // and start a new process for it.
16317            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16318                mPersistentStartingProcesses.add(app);
16319                restart = true;
16320            }
16321        }
16322        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16323                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16324        mProcessesOnHold.remove(app);
16325
16326        if (app == mHomeProcess) {
16327            mHomeProcess = null;
16328        }
16329        if (app == mPreviousProcess) {
16330            mPreviousProcess = null;
16331        }
16332
16333        if (restart && !app.isolated) {
16334            // We have components that still need to be running in the
16335            // process, so re-launch it.
16336            if (index < 0) {
16337                ProcessList.remove(app.pid);
16338            }
16339            addProcessNameLocked(app);
16340            startProcessLocked(app, "restart", app.processName);
16341            return true;
16342        } else if (app.pid > 0 && app.pid != MY_PID) {
16343            // Goodbye!
16344            boolean removed;
16345            synchronized (mPidsSelfLocked) {
16346                mPidsSelfLocked.remove(app.pid);
16347                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16348            }
16349            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16350            if (app.isolated) {
16351                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16352            }
16353            app.setPid(0);
16354        }
16355        return false;
16356    }
16357
16358    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16359        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16360            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16361            if (cpr.launchingApp == app) {
16362                return true;
16363            }
16364        }
16365        return false;
16366    }
16367
16368    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16369        // Look through the content providers we are waiting to have launched,
16370        // and if any run in this process then either schedule a restart of
16371        // the process or kill the client waiting for it if this process has
16372        // gone bad.
16373        boolean restart = false;
16374        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16375            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16376            if (cpr.launchingApp == app) {
16377                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16378                    restart = true;
16379                } else {
16380                    removeDyingProviderLocked(app, cpr, true);
16381                }
16382            }
16383        }
16384        return restart;
16385    }
16386
16387    // =========================================================
16388    // SERVICES
16389    // =========================================================
16390
16391    @Override
16392    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16393            int flags) {
16394        enforceNotIsolatedCaller("getServices");
16395        synchronized (this) {
16396            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16397        }
16398    }
16399
16400    @Override
16401    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16402        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16403        synchronized (this) {
16404            return mServices.getRunningServiceControlPanelLocked(name);
16405        }
16406    }
16407
16408    @Override
16409    public ComponentName startService(IApplicationThread caller, Intent service,
16410            String resolvedType, String callingPackage, int userId)
16411            throws TransactionTooLargeException {
16412        enforceNotIsolatedCaller("startService");
16413        // Refuse possible leaked file descriptors
16414        if (service != null && service.hasFileDescriptors() == true) {
16415            throw new IllegalArgumentException("File descriptors passed in Intent");
16416        }
16417
16418        if (callingPackage == null) {
16419            throw new IllegalArgumentException("callingPackage cannot be null");
16420        }
16421
16422        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16423                "startService: " + service + " type=" + resolvedType);
16424        synchronized(this) {
16425            final int callingPid = Binder.getCallingPid();
16426            final int callingUid = Binder.getCallingUid();
16427            final long origId = Binder.clearCallingIdentity();
16428            ComponentName res = mServices.startServiceLocked(caller, service,
16429                    resolvedType, callingPid, callingUid, callingPackage, userId);
16430            Binder.restoreCallingIdentity(origId);
16431            return res;
16432        }
16433    }
16434
16435    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16436            String callingPackage, int userId)
16437            throws TransactionTooLargeException {
16438        synchronized(this) {
16439            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16440                    "startServiceInPackage: " + service + " type=" + resolvedType);
16441            final long origId = Binder.clearCallingIdentity();
16442            ComponentName res = mServices.startServiceLocked(null, service,
16443                    resolvedType, -1, uid, callingPackage, userId);
16444            Binder.restoreCallingIdentity(origId);
16445            return res;
16446        }
16447    }
16448
16449    @Override
16450    public int stopService(IApplicationThread caller, Intent service,
16451            String resolvedType, int userId) {
16452        enforceNotIsolatedCaller("stopService");
16453        // Refuse possible leaked file descriptors
16454        if (service != null && service.hasFileDescriptors() == true) {
16455            throw new IllegalArgumentException("File descriptors passed in Intent");
16456        }
16457
16458        synchronized(this) {
16459            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16460        }
16461    }
16462
16463    @Override
16464    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16465        enforceNotIsolatedCaller("peekService");
16466        // Refuse possible leaked file descriptors
16467        if (service != null && service.hasFileDescriptors() == true) {
16468            throw new IllegalArgumentException("File descriptors passed in Intent");
16469        }
16470
16471        if (callingPackage == null) {
16472            throw new IllegalArgumentException("callingPackage cannot be null");
16473        }
16474
16475        synchronized(this) {
16476            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16477        }
16478    }
16479
16480    @Override
16481    public boolean stopServiceToken(ComponentName className, IBinder token,
16482            int startId) {
16483        synchronized(this) {
16484            return mServices.stopServiceTokenLocked(className, token, startId);
16485        }
16486    }
16487
16488    @Override
16489    public void setServiceForeground(ComponentName className, IBinder token,
16490            int id, Notification notification, boolean removeNotification) {
16491        synchronized(this) {
16492            mServices.setServiceForegroundLocked(className, token, id, notification,
16493                    removeNotification);
16494        }
16495    }
16496
16497    @Override
16498    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16499            boolean requireFull, String name, String callerPackage) {
16500        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16501                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16502    }
16503
16504    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16505            String className, int flags) {
16506        boolean result = false;
16507        // For apps that don't have pre-defined UIDs, check for permission
16508        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16509            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16510                if (ActivityManager.checkUidPermission(
16511                        INTERACT_ACROSS_USERS,
16512                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16513                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16514                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16515                            + " requests FLAG_SINGLE_USER, but app does not hold "
16516                            + INTERACT_ACROSS_USERS;
16517                    Slog.w(TAG, msg);
16518                    throw new SecurityException(msg);
16519                }
16520                // Permission passed
16521                result = true;
16522            }
16523        } else if ("system".equals(componentProcessName)) {
16524            result = true;
16525        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16526            // Phone app and persistent apps are allowed to export singleuser providers.
16527            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16528                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16529        }
16530        if (DEBUG_MU) Slog.v(TAG_MU,
16531                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16532                + Integer.toHexString(flags) + ") = " + result);
16533        return result;
16534    }
16535
16536    /**
16537     * Checks to see if the caller is in the same app as the singleton
16538     * component, or the component is in a special app. It allows special apps
16539     * to export singleton components but prevents exporting singleton
16540     * components for regular apps.
16541     */
16542    boolean isValidSingletonCall(int callingUid, int componentUid) {
16543        int componentAppId = UserHandle.getAppId(componentUid);
16544        return UserHandle.isSameApp(callingUid, componentUid)
16545                || componentAppId == Process.SYSTEM_UID
16546                || componentAppId == Process.PHONE_UID
16547                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16548                        == PackageManager.PERMISSION_GRANTED;
16549    }
16550
16551    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16552            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16553            int userId) throws TransactionTooLargeException {
16554        enforceNotIsolatedCaller("bindService");
16555
16556        // Refuse possible leaked file descriptors
16557        if (service != null && service.hasFileDescriptors() == true) {
16558            throw new IllegalArgumentException("File descriptors passed in Intent");
16559        }
16560
16561        if (callingPackage == null) {
16562            throw new IllegalArgumentException("callingPackage cannot be null");
16563        }
16564
16565        synchronized(this) {
16566            return mServices.bindServiceLocked(caller, token, service,
16567                    resolvedType, connection, flags, callingPackage, userId);
16568        }
16569    }
16570
16571    public boolean unbindService(IServiceConnection connection) {
16572        synchronized (this) {
16573            return mServices.unbindServiceLocked(connection);
16574        }
16575    }
16576
16577    public void publishService(IBinder token, Intent intent, IBinder service) {
16578        // Refuse possible leaked file descriptors
16579        if (intent != null && intent.hasFileDescriptors() == true) {
16580            throw new IllegalArgumentException("File descriptors passed in Intent");
16581        }
16582
16583        synchronized(this) {
16584            if (!(token instanceof ServiceRecord)) {
16585                throw new IllegalArgumentException("Invalid service token");
16586            }
16587            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16588        }
16589    }
16590
16591    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16592        // Refuse possible leaked file descriptors
16593        if (intent != null && intent.hasFileDescriptors() == true) {
16594            throw new IllegalArgumentException("File descriptors passed in Intent");
16595        }
16596
16597        synchronized(this) {
16598            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16599        }
16600    }
16601
16602    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16603        synchronized(this) {
16604            if (!(token instanceof ServiceRecord)) {
16605                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16606                throw new IllegalArgumentException("Invalid service token");
16607            }
16608            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16609        }
16610    }
16611
16612    // =========================================================
16613    // BACKUP AND RESTORE
16614    // =========================================================
16615
16616    // Cause the target app to be launched if necessary and its backup agent
16617    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16618    // activity manager to announce its creation.
16619    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16620        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16621                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16622        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16623
16624        synchronized(this) {
16625            // !!! TODO: currently no check here that we're already bound
16626            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16627            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16628            synchronized (stats) {
16629                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16630            }
16631
16632            // Backup agent is now in use, its package can't be stopped.
16633            try {
16634                AppGlobals.getPackageManager().setPackageStoppedState(
16635                        app.packageName, false, UserHandle.getUserId(app.uid));
16636            } catch (RemoteException e) {
16637            } catch (IllegalArgumentException e) {
16638                Slog.w(TAG, "Failed trying to unstop package "
16639                        + app.packageName + ": " + e);
16640            }
16641
16642            BackupRecord r = new BackupRecord(ss, app, backupMode);
16643            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16644                    ? new ComponentName(app.packageName, app.backupAgentName)
16645                    : new ComponentName("android", "FullBackupAgent");
16646            // startProcessLocked() returns existing proc's record if it's already running
16647            ProcessRecord proc = startProcessLocked(app.processName, app,
16648                    false, 0, "backup", hostingName, false, false, false);
16649            if (proc == null) {
16650                Slog.e(TAG, "Unable to start backup agent process " + r);
16651                return false;
16652            }
16653
16654            r.app = proc;
16655            mBackupTarget = r;
16656            mBackupAppName = app.packageName;
16657
16658            // Try not to kill the process during backup
16659            updateOomAdjLocked(proc);
16660
16661            // If the process is already attached, schedule the creation of the backup agent now.
16662            // If it is not yet live, this will be done when it attaches to the framework.
16663            if (proc.thread != null) {
16664                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16665                try {
16666                    proc.thread.scheduleCreateBackupAgent(app,
16667                            compatibilityInfoForPackageLocked(app), backupMode);
16668                } catch (RemoteException e) {
16669                    // Will time out on the backup manager side
16670                }
16671            } else {
16672                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16673            }
16674            // Invariants: at this point, the target app process exists and the application
16675            // is either already running or in the process of coming up.  mBackupTarget and
16676            // mBackupAppName describe the app, so that when it binds back to the AM we
16677            // know that it's scheduled for a backup-agent operation.
16678        }
16679
16680        return true;
16681    }
16682
16683    @Override
16684    public void clearPendingBackup() {
16685        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16686        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16687
16688        synchronized (this) {
16689            mBackupTarget = null;
16690            mBackupAppName = null;
16691        }
16692    }
16693
16694    // A backup agent has just come up
16695    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16696        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16697                + " = " + agent);
16698
16699        synchronized(this) {
16700            if (!agentPackageName.equals(mBackupAppName)) {
16701                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16702                return;
16703            }
16704        }
16705
16706        long oldIdent = Binder.clearCallingIdentity();
16707        try {
16708            IBackupManager bm = IBackupManager.Stub.asInterface(
16709                    ServiceManager.getService(Context.BACKUP_SERVICE));
16710            bm.agentConnected(agentPackageName, agent);
16711        } catch (RemoteException e) {
16712            // can't happen; the backup manager service is local
16713        } catch (Exception e) {
16714            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16715            e.printStackTrace();
16716        } finally {
16717            Binder.restoreCallingIdentity(oldIdent);
16718        }
16719    }
16720
16721    // done with this agent
16722    public void unbindBackupAgent(ApplicationInfo appInfo) {
16723        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16724        if (appInfo == null) {
16725            Slog.w(TAG, "unbind backup agent for null app");
16726            return;
16727        }
16728
16729        synchronized(this) {
16730            try {
16731                if (mBackupAppName == null) {
16732                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16733                    return;
16734                }
16735
16736                if (!mBackupAppName.equals(appInfo.packageName)) {
16737                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16738                    return;
16739                }
16740
16741                // Not backing this app up any more; reset its OOM adjustment
16742                final ProcessRecord proc = mBackupTarget.app;
16743                updateOomAdjLocked(proc);
16744
16745                // If the app crashed during backup, 'thread' will be null here
16746                if (proc.thread != null) {
16747                    try {
16748                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16749                                compatibilityInfoForPackageLocked(appInfo));
16750                    } catch (Exception e) {
16751                        Slog.e(TAG, "Exception when unbinding backup agent:");
16752                        e.printStackTrace();
16753                    }
16754                }
16755            } finally {
16756                mBackupTarget = null;
16757                mBackupAppName = null;
16758            }
16759        }
16760    }
16761    // =========================================================
16762    // BROADCASTS
16763    // =========================================================
16764
16765    boolean isPendingBroadcastProcessLocked(int pid) {
16766        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16767                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16768    }
16769
16770    void skipPendingBroadcastLocked(int pid) {
16771            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16772            for (BroadcastQueue queue : mBroadcastQueues) {
16773                queue.skipPendingBroadcastLocked(pid);
16774            }
16775    }
16776
16777    // The app just attached; send any pending broadcasts that it should receive
16778    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16779        boolean didSomething = false;
16780        for (BroadcastQueue queue : mBroadcastQueues) {
16781            didSomething |= queue.sendPendingBroadcastsLocked(app);
16782        }
16783        return didSomething;
16784    }
16785
16786    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16787            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16788        enforceNotIsolatedCaller("registerReceiver");
16789        ArrayList<Intent> stickyIntents = null;
16790        ProcessRecord callerApp = null;
16791        int callingUid;
16792        int callingPid;
16793        synchronized(this) {
16794            if (caller != null) {
16795                callerApp = getRecordForAppLocked(caller);
16796                if (callerApp == null) {
16797                    throw new SecurityException(
16798                            "Unable to find app for caller " + caller
16799                            + " (pid=" + Binder.getCallingPid()
16800                            + ") when registering receiver " + receiver);
16801                }
16802                if (callerApp.info.uid != Process.SYSTEM_UID &&
16803                        !callerApp.pkgList.containsKey(callerPackage) &&
16804                        !"android".equals(callerPackage)) {
16805                    throw new SecurityException("Given caller package " + callerPackage
16806                            + " is not running in process " + callerApp);
16807                }
16808                callingUid = callerApp.info.uid;
16809                callingPid = callerApp.pid;
16810            } else {
16811                callerPackage = null;
16812                callingUid = Binder.getCallingUid();
16813                callingPid = Binder.getCallingPid();
16814            }
16815
16816            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16817                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16818
16819            Iterator<String> actions = filter.actionsIterator();
16820            if (actions == null) {
16821                ArrayList<String> noAction = new ArrayList<String>(1);
16822                noAction.add(null);
16823                actions = noAction.iterator();
16824            }
16825
16826            // Collect stickies of users
16827            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16828            while (actions.hasNext()) {
16829                String action = actions.next();
16830                for (int id : userIds) {
16831                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16832                    if (stickies != null) {
16833                        ArrayList<Intent> intents = stickies.get(action);
16834                        if (intents != null) {
16835                            if (stickyIntents == null) {
16836                                stickyIntents = new ArrayList<Intent>();
16837                            }
16838                            stickyIntents.addAll(intents);
16839                        }
16840                    }
16841                }
16842            }
16843        }
16844
16845        ArrayList<Intent> allSticky = null;
16846        if (stickyIntents != null) {
16847            final ContentResolver resolver = mContext.getContentResolver();
16848            // Look for any matching sticky broadcasts...
16849            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16850                Intent intent = stickyIntents.get(i);
16851                // If intent has scheme "content", it will need to acccess
16852                // provider that needs to lock mProviderMap in ActivityThread
16853                // and also it may need to wait application response, so we
16854                // cannot lock ActivityManagerService here.
16855                if (filter.match(resolver, intent, true, TAG) >= 0) {
16856                    if (allSticky == null) {
16857                        allSticky = new ArrayList<Intent>();
16858                    }
16859                    allSticky.add(intent);
16860                }
16861            }
16862        }
16863
16864        // The first sticky in the list is returned directly back to the client.
16865        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16866        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16867        if (receiver == null) {
16868            return sticky;
16869        }
16870
16871        synchronized (this) {
16872            if (callerApp != null && (callerApp.thread == null
16873                    || callerApp.thread.asBinder() != caller.asBinder())) {
16874                // Original caller already died
16875                return null;
16876            }
16877            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16878            if (rl == null) {
16879                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16880                        userId, receiver);
16881                if (rl.app != null) {
16882                    rl.app.receivers.add(rl);
16883                } else {
16884                    try {
16885                        receiver.asBinder().linkToDeath(rl, 0);
16886                    } catch (RemoteException e) {
16887                        return sticky;
16888                    }
16889                    rl.linkedToDeath = true;
16890                }
16891                mRegisteredReceivers.put(receiver.asBinder(), rl);
16892            } else if (rl.uid != callingUid) {
16893                throw new IllegalArgumentException(
16894                        "Receiver requested to register for uid " + callingUid
16895                        + " was previously registered for uid " + rl.uid);
16896            } else if (rl.pid != callingPid) {
16897                throw new IllegalArgumentException(
16898                        "Receiver requested to register for pid " + callingPid
16899                        + " was previously registered for pid " + rl.pid);
16900            } else if (rl.userId != userId) {
16901                throw new IllegalArgumentException(
16902                        "Receiver requested to register for user " + userId
16903                        + " was previously registered for user " + rl.userId);
16904            }
16905            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16906                    permission, callingUid, userId);
16907            rl.add(bf);
16908            if (!bf.debugCheck()) {
16909                Slog.w(TAG, "==> For Dynamic broadcast");
16910            }
16911            mReceiverResolver.addFilter(bf);
16912
16913            // Enqueue broadcasts for all existing stickies that match
16914            // this filter.
16915            if (allSticky != null) {
16916                ArrayList receivers = new ArrayList();
16917                receivers.add(bf);
16918
16919                final int stickyCount = allSticky.size();
16920                for (int i = 0; i < stickyCount; i++) {
16921                    Intent intent = allSticky.get(i);
16922                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16923                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16924                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16925                            null, 0, null, null, false, true, true, -1);
16926                    queue.enqueueParallelBroadcastLocked(r);
16927                    queue.scheduleBroadcastsLocked();
16928                }
16929            }
16930
16931            return sticky;
16932        }
16933    }
16934
16935    public void unregisterReceiver(IIntentReceiver receiver) {
16936        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16937
16938        final long origId = Binder.clearCallingIdentity();
16939        try {
16940            boolean doTrim = false;
16941
16942            synchronized(this) {
16943                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16944                if (rl != null) {
16945                    final BroadcastRecord r = rl.curBroadcast;
16946                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16947                        final boolean doNext = r.queue.finishReceiverLocked(
16948                                r, r.resultCode, r.resultData, r.resultExtras,
16949                                r.resultAbort, false);
16950                        if (doNext) {
16951                            doTrim = true;
16952                            r.queue.processNextBroadcast(false);
16953                        }
16954                    }
16955
16956                    if (rl.app != null) {
16957                        rl.app.receivers.remove(rl);
16958                    }
16959                    removeReceiverLocked(rl);
16960                    if (rl.linkedToDeath) {
16961                        rl.linkedToDeath = false;
16962                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16963                    }
16964                }
16965            }
16966
16967            // If we actually concluded any broadcasts, we might now be able
16968            // to trim the recipients' apps from our working set
16969            if (doTrim) {
16970                trimApplications();
16971                return;
16972            }
16973
16974        } finally {
16975            Binder.restoreCallingIdentity(origId);
16976        }
16977    }
16978
16979    void removeReceiverLocked(ReceiverList rl) {
16980        mRegisteredReceivers.remove(rl.receiver.asBinder());
16981        for (int i = rl.size() - 1; i >= 0; i--) {
16982            mReceiverResolver.removeFilter(rl.get(i));
16983        }
16984    }
16985
16986    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16987        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16988            ProcessRecord r = mLruProcesses.get(i);
16989            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16990                try {
16991                    r.thread.dispatchPackageBroadcast(cmd, packages);
16992                } catch (RemoteException ex) {
16993                }
16994            }
16995        }
16996    }
16997
16998    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16999            int callingUid, int[] users) {
17000        // TODO: come back and remove this assumption to triage all broadcasts
17001        int pmFlags = STOCK_PM_FLAGS | PackageManager.MATCH_ENCRYPTION_DEFAULT;
17002
17003        List<ResolveInfo> receivers = null;
17004        try {
17005            HashSet<ComponentName> singleUserReceivers = null;
17006            boolean scannedFirstReceivers = false;
17007            for (int user : users) {
17008                // Skip users that have Shell restrictions
17009                if (callingUid == Process.SHELL_UID
17010                        && mUserController.hasUserRestriction(
17011                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
17012                    continue;
17013                }
17014                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17015                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
17016                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17017                    // If this is not the system user, we need to check for
17018                    // any receivers that should be filtered out.
17019                    for (int i=0; i<newReceivers.size(); i++) {
17020                        ResolveInfo ri = newReceivers.get(i);
17021                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17022                            newReceivers.remove(i);
17023                            i--;
17024                        }
17025                    }
17026                }
17027                if (newReceivers != null && newReceivers.size() == 0) {
17028                    newReceivers = null;
17029                }
17030                if (receivers == null) {
17031                    receivers = newReceivers;
17032                } else if (newReceivers != null) {
17033                    // We need to concatenate the additional receivers
17034                    // found with what we have do far.  This would be easy,
17035                    // but we also need to de-dup any receivers that are
17036                    // singleUser.
17037                    if (!scannedFirstReceivers) {
17038                        // Collect any single user receivers we had already retrieved.
17039                        scannedFirstReceivers = true;
17040                        for (int i=0; i<receivers.size(); i++) {
17041                            ResolveInfo ri = receivers.get(i);
17042                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17043                                ComponentName cn = new ComponentName(
17044                                        ri.activityInfo.packageName, ri.activityInfo.name);
17045                                if (singleUserReceivers == null) {
17046                                    singleUserReceivers = new HashSet<ComponentName>();
17047                                }
17048                                singleUserReceivers.add(cn);
17049                            }
17050                        }
17051                    }
17052                    // Add the new results to the existing results, tracking
17053                    // and de-dupping single user receivers.
17054                    for (int i=0; i<newReceivers.size(); i++) {
17055                        ResolveInfo ri = newReceivers.get(i);
17056                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17057                            ComponentName cn = new ComponentName(
17058                                    ri.activityInfo.packageName, ri.activityInfo.name);
17059                            if (singleUserReceivers == null) {
17060                                singleUserReceivers = new HashSet<ComponentName>();
17061                            }
17062                            if (!singleUserReceivers.contains(cn)) {
17063                                singleUserReceivers.add(cn);
17064                                receivers.add(ri);
17065                            }
17066                        } else {
17067                            receivers.add(ri);
17068                        }
17069                    }
17070                }
17071            }
17072        } catch (RemoteException ex) {
17073            // pm is in same process, this will never happen.
17074        }
17075        return receivers;
17076    }
17077
17078    final int broadcastIntentLocked(ProcessRecord callerApp,
17079            String callerPackage, Intent intent, String resolvedType,
17080            IIntentReceiver resultTo, int resultCode, String resultData,
17081            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17082            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17083        intent = new Intent(intent);
17084
17085        // By default broadcasts do not go to stopped apps.
17086        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17087
17088        // If we have not finished booting, don't allow this to launch new processes.
17089        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17090            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17091        }
17092
17093        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17094                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17095                + " ordered=" + ordered + " userid=" + userId);
17096        if ((resultTo != null) && !ordered) {
17097            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17098        }
17099
17100        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17101                ALLOW_NON_FULL, "broadcast", callerPackage);
17102
17103        // Make sure that the user who is receiving this broadcast is running.
17104        // If not, we will just skip it. Make an exception for shutdown broadcasts
17105        // and upgrade steps.
17106
17107        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17108            if ((callingUid != Process.SYSTEM_UID
17109                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17110                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17111                Slog.w(TAG, "Skipping broadcast of " + intent
17112                        + ": user " + userId + " is stopped");
17113                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17114            }
17115        }
17116
17117        BroadcastOptions brOptions = null;
17118        if (bOptions != null) {
17119            brOptions = new BroadcastOptions(bOptions);
17120            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17121                // See if the caller is allowed to do this.  Note we are checking against
17122                // the actual real caller (not whoever provided the operation as say a
17123                // PendingIntent), because that who is actually supplied the arguments.
17124                if (checkComponentPermission(
17125                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17126                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17127                        != PackageManager.PERMISSION_GRANTED) {
17128                    String msg = "Permission Denial: " + intent.getAction()
17129                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17130                            + ", uid=" + callingUid + ")"
17131                            + " requires "
17132                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17133                    Slog.w(TAG, msg);
17134                    throw new SecurityException(msg);
17135                }
17136            }
17137        }
17138
17139        // Verify that protected broadcasts are only being sent by system code,
17140        // and that system code is only sending protected broadcasts.
17141        final String action = intent.getAction();
17142        final boolean isProtectedBroadcast;
17143        try {
17144            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17145        } catch (RemoteException e) {
17146            Slog.w(TAG, "Remote exception", e);
17147            return ActivityManager.BROADCAST_SUCCESS;
17148        }
17149
17150        final boolean isCallerSystem;
17151        switch (UserHandle.getAppId(callingUid)) {
17152            case Process.ROOT_UID:
17153            case Process.SYSTEM_UID:
17154            case Process.PHONE_UID:
17155            case Process.SHELL_UID:
17156            case Process.BLUETOOTH_UID:
17157            case Process.NFC_UID:
17158                isCallerSystem = true;
17159                break;
17160            default:
17161                isCallerSystem = (callerApp != null) && callerApp.persistent;
17162                break;
17163        }
17164
17165        if (isCallerSystem) {
17166            if (isProtectedBroadcast
17167                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17168                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17169                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17170                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17171                // Broadcast is either protected, or it's a public action that
17172                // we've relaxed, so it's fine for system internals to send.
17173            } else {
17174                // The vast majority of broadcasts sent from system internals
17175                // should be protected to avoid security holes, so yell loudly
17176                // to ensure we examine these cases.
17177                Log.wtf(TAG, "Sending non-protected broadcast " + action
17178                        + " from system", new Throwable());
17179            }
17180
17181        } else {
17182            if (isProtectedBroadcast) {
17183                String msg = "Permission Denial: not allowed to send broadcast "
17184                        + action + " from pid="
17185                        + callingPid + ", uid=" + callingUid;
17186                Slog.w(TAG, msg);
17187                throw new SecurityException(msg);
17188
17189            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17190                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17191                // Special case for compatibility: we don't want apps to send this,
17192                // but historically it has not been protected and apps may be using it
17193                // to poke their own app widget.  So, instead of making it protected,
17194                // just limit it to the caller.
17195                if (callerApp == null) {
17196                    String msg = "Permission Denial: not allowed to send broadcast "
17197                            + action + " from unknown caller.";
17198                    Slog.w(TAG, msg);
17199                    throw new SecurityException(msg);
17200                } else if (intent.getComponent() != null) {
17201                    // They are good enough to send to an explicit component...  verify
17202                    // it is being sent to the calling app.
17203                    if (!intent.getComponent().getPackageName().equals(
17204                            callerApp.info.packageName)) {
17205                        String msg = "Permission Denial: not allowed to send broadcast "
17206                                + action + " to "
17207                                + intent.getComponent().getPackageName() + " from "
17208                                + callerApp.info.packageName;
17209                        Slog.w(TAG, msg);
17210                        throw new SecurityException(msg);
17211                    }
17212                } else {
17213                    // Limit broadcast to their own package.
17214                    intent.setPackage(callerApp.info.packageName);
17215                }
17216            }
17217        }
17218
17219        if (action != null) {
17220            switch (action) {
17221                case Intent.ACTION_UID_REMOVED:
17222                case Intent.ACTION_PACKAGE_REMOVED:
17223                case Intent.ACTION_PACKAGE_CHANGED:
17224                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17225                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17226                    // Handle special intents: if this broadcast is from the package
17227                    // manager about a package being removed, we need to remove all of
17228                    // its activities from the history stack.
17229                    if (checkComponentPermission(
17230                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17231                            callingPid, callingUid, -1, true)
17232                            != PackageManager.PERMISSION_GRANTED) {
17233                        String msg = "Permission Denial: " + intent.getAction()
17234                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17235                                + ", uid=" + callingUid + ")"
17236                                + " requires "
17237                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17238                        Slog.w(TAG, msg);
17239                        throw new SecurityException(msg);
17240                    }
17241                    switch (action) {
17242                        case Intent.ACTION_UID_REMOVED:
17243                            final Bundle intentExtras = intent.getExtras();
17244                            final int uid = intentExtras != null
17245                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17246                            if (uid >= 0) {
17247                                mBatteryStatsService.removeUid(uid);
17248                                mAppOpsService.uidRemoved(uid);
17249                            }
17250                            break;
17251                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17252                            // If resources are unavailable just force stop all those packages
17253                            // and flush the attribute cache as well.
17254                            String list[] =
17255                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17256                            if (list != null && list.length > 0) {
17257                                for (int i = 0; i < list.length; i++) {
17258                                    forceStopPackageLocked(list[i], -1, false, true, true,
17259                                            false, false, userId, "storage unmount");
17260                                }
17261                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17262                                sendPackageBroadcastLocked(
17263                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17264                                        userId);
17265                            }
17266                            break;
17267                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17268                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17269                            break;
17270                        case Intent.ACTION_PACKAGE_REMOVED:
17271                        case Intent.ACTION_PACKAGE_CHANGED:
17272                            Uri data = intent.getData();
17273                            String ssp;
17274                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17275                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17276                                boolean fullUninstall = removed &&
17277                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17278                                final boolean killProcess =
17279                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17280                                if (killProcess) {
17281                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17282                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17283                                            false, true, true, false, fullUninstall, userId,
17284                                            removed ? "pkg removed" : "pkg changed");
17285                                }
17286                                if (removed) {
17287                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17288                                            new String[] {ssp}, userId);
17289                                    if (fullUninstall) {
17290                                        mAppOpsService.packageRemoved(
17291                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17292
17293                                        // Remove all permissions granted from/to this package
17294                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17295
17296                                        removeTasksByPackageNameLocked(ssp, userId);
17297                                        mBatteryStatsService.notePackageUninstalled(ssp);
17298                                    }
17299                                } else {
17300                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17301                                            intent.getStringArrayExtra(
17302                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17303                                }
17304                            }
17305                            break;
17306                    }
17307                    break;
17308                case Intent.ACTION_PACKAGE_ADDED:
17309                    // Special case for adding a package: by default turn on compatibility mode.
17310                    Uri data = intent.getData();
17311                    String ssp;
17312                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17313                        final boolean replacing =
17314                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17315                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17316
17317                        try {
17318                            ApplicationInfo ai = AppGlobals.getPackageManager().
17319                                    getApplicationInfo(ssp, 0, 0);
17320                            mBatteryStatsService.notePackageInstalled(ssp,
17321                                    ai != null ? ai.versionCode : 0);
17322                        } catch (RemoteException e) {
17323                        }
17324                    }
17325                    break;
17326                case Intent.ACTION_TIMEZONE_CHANGED:
17327                    // If this is the time zone changed action, queue up a message that will reset
17328                    // the timezone of all currently running processes. This message will get
17329                    // queued up before the broadcast happens.
17330                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17331                    break;
17332                case Intent.ACTION_TIME_CHANGED:
17333                    // If the user set the time, let all running processes know.
17334                    final int is24Hour =
17335                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17336                                    : 0;
17337                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17338                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17339                    synchronized (stats) {
17340                        stats.noteCurrentTimeChangedLocked();
17341                    }
17342                    break;
17343                case Intent.ACTION_CLEAR_DNS_CACHE:
17344                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17345                    break;
17346                case Proxy.PROXY_CHANGE_ACTION:
17347                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17348                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17349                    break;
17350            }
17351        }
17352
17353        // Add to the sticky list if requested.
17354        if (sticky) {
17355            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17356                    callingPid, callingUid)
17357                    != PackageManager.PERMISSION_GRANTED) {
17358                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17359                        + callingPid + ", uid=" + callingUid
17360                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17361                Slog.w(TAG, msg);
17362                throw new SecurityException(msg);
17363            }
17364            if (requiredPermissions != null && requiredPermissions.length > 0) {
17365                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17366                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17367                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17368            }
17369            if (intent.getComponent() != null) {
17370                throw new SecurityException(
17371                        "Sticky broadcasts can't target a specific component");
17372            }
17373            // We use userId directly here, since the "all" target is maintained
17374            // as a separate set of sticky broadcasts.
17375            if (userId != UserHandle.USER_ALL) {
17376                // But first, if this is not a broadcast to all users, then
17377                // make sure it doesn't conflict with an existing broadcast to
17378                // all users.
17379                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17380                        UserHandle.USER_ALL);
17381                if (stickies != null) {
17382                    ArrayList<Intent> list = stickies.get(intent.getAction());
17383                    if (list != null) {
17384                        int N = list.size();
17385                        int i;
17386                        for (i=0; i<N; i++) {
17387                            if (intent.filterEquals(list.get(i))) {
17388                                throw new IllegalArgumentException(
17389                                        "Sticky broadcast " + intent + " for user "
17390                                        + userId + " conflicts with existing global broadcast");
17391                            }
17392                        }
17393                    }
17394                }
17395            }
17396            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17397            if (stickies == null) {
17398                stickies = new ArrayMap<>();
17399                mStickyBroadcasts.put(userId, stickies);
17400            }
17401            ArrayList<Intent> list = stickies.get(intent.getAction());
17402            if (list == null) {
17403                list = new ArrayList<>();
17404                stickies.put(intent.getAction(), list);
17405            }
17406            final int stickiesCount = list.size();
17407            int i;
17408            for (i = 0; i < stickiesCount; i++) {
17409                if (intent.filterEquals(list.get(i))) {
17410                    // This sticky already exists, replace it.
17411                    list.set(i, new Intent(intent));
17412                    break;
17413                }
17414            }
17415            if (i >= stickiesCount) {
17416                list.add(new Intent(intent));
17417            }
17418        }
17419
17420        int[] users;
17421        if (userId == UserHandle.USER_ALL) {
17422            // Caller wants broadcast to go to all started users.
17423            users = mUserController.getStartedUserArrayLocked();
17424        } else {
17425            // Caller wants broadcast to go to one specific user.
17426            users = new int[] {userId};
17427        }
17428
17429        // Figure out who all will receive this broadcast.
17430        List receivers = null;
17431        List<BroadcastFilter> registeredReceivers = null;
17432        // Need to resolve the intent to interested receivers...
17433        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17434                 == 0) {
17435            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17436        }
17437        if (intent.getComponent() == null) {
17438            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17439                // Query one target user at a time, excluding shell-restricted users
17440                for (int i = 0; i < users.length; i++) {
17441                    if (mUserController.hasUserRestriction(
17442                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17443                        continue;
17444                    }
17445                    List<BroadcastFilter> registeredReceiversForUser =
17446                            mReceiverResolver.queryIntent(intent,
17447                                    resolvedType, false, users[i]);
17448                    if (registeredReceivers == null) {
17449                        registeredReceivers = registeredReceiversForUser;
17450                    } else if (registeredReceiversForUser != null) {
17451                        registeredReceivers.addAll(registeredReceiversForUser);
17452                    }
17453                }
17454            } else {
17455                registeredReceivers = mReceiverResolver.queryIntent(intent,
17456                        resolvedType, false, userId);
17457            }
17458        }
17459
17460        final boolean replacePending =
17461                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17462
17463        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17464                + " replacePending=" + replacePending);
17465
17466        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17467        if (!ordered && NR > 0) {
17468            // If we are not serializing this broadcast, then send the
17469            // registered receivers separately so they don't wait for the
17470            // components to be launched.
17471            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17472            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17473                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17474                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17475                    resultExtras, ordered, sticky, false, userId);
17476            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17477            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17478            if (!replaced) {
17479                queue.enqueueParallelBroadcastLocked(r);
17480                queue.scheduleBroadcastsLocked();
17481            }
17482            registeredReceivers = null;
17483            NR = 0;
17484        }
17485
17486        // Merge into one list.
17487        int ir = 0;
17488        if (receivers != null) {
17489            // A special case for PACKAGE_ADDED: do not allow the package
17490            // being added to see this broadcast.  This prevents them from
17491            // using this as a back door to get run as soon as they are
17492            // installed.  Maybe in the future we want to have a special install
17493            // broadcast or such for apps, but we'd like to deliberately make
17494            // this decision.
17495            String skipPackages[] = null;
17496            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17497                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17498                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17499                Uri data = intent.getData();
17500                if (data != null) {
17501                    String pkgName = data.getSchemeSpecificPart();
17502                    if (pkgName != null) {
17503                        skipPackages = new String[] { pkgName };
17504                    }
17505                }
17506            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17507                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17508            }
17509            if (skipPackages != null && (skipPackages.length > 0)) {
17510                for (String skipPackage : skipPackages) {
17511                    if (skipPackage != null) {
17512                        int NT = receivers.size();
17513                        for (int it=0; it<NT; it++) {
17514                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17515                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17516                                receivers.remove(it);
17517                                it--;
17518                                NT--;
17519                            }
17520                        }
17521                    }
17522                }
17523            }
17524
17525            int NT = receivers != null ? receivers.size() : 0;
17526            int it = 0;
17527            ResolveInfo curt = null;
17528            BroadcastFilter curr = null;
17529            while (it < NT && ir < NR) {
17530                if (curt == null) {
17531                    curt = (ResolveInfo)receivers.get(it);
17532                }
17533                if (curr == null) {
17534                    curr = registeredReceivers.get(ir);
17535                }
17536                if (curr.getPriority() >= curt.priority) {
17537                    // Insert this broadcast record into the final list.
17538                    receivers.add(it, curr);
17539                    ir++;
17540                    curr = null;
17541                    it++;
17542                    NT++;
17543                } else {
17544                    // Skip to the next ResolveInfo in the final list.
17545                    it++;
17546                    curt = null;
17547                }
17548            }
17549        }
17550        while (ir < NR) {
17551            if (receivers == null) {
17552                receivers = new ArrayList();
17553            }
17554            receivers.add(registeredReceivers.get(ir));
17555            ir++;
17556        }
17557
17558        if ((receivers != null && receivers.size() > 0)
17559                || resultTo != null) {
17560            BroadcastQueue queue = broadcastQueueForIntent(intent);
17561            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17562                    callerPackage, callingPid, callingUid, resolvedType,
17563                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17564                    resultData, resultExtras, ordered, sticky, false, userId);
17565
17566            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17567                    + ": prev had " + queue.mOrderedBroadcasts.size());
17568            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17569                    "Enqueueing broadcast " + r.intent.getAction());
17570
17571            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17572            if (!replaced) {
17573                queue.enqueueOrderedBroadcastLocked(r);
17574                queue.scheduleBroadcastsLocked();
17575            }
17576        }
17577
17578        return ActivityManager.BROADCAST_SUCCESS;
17579    }
17580
17581    final Intent verifyBroadcastLocked(Intent intent) {
17582        // Refuse possible leaked file descriptors
17583        if (intent != null && intent.hasFileDescriptors() == true) {
17584            throw new IllegalArgumentException("File descriptors passed in Intent");
17585        }
17586
17587        int flags = intent.getFlags();
17588
17589        if (!mProcessesReady) {
17590            // if the caller really truly claims to know what they're doing, go
17591            // ahead and allow the broadcast without launching any receivers
17592            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17593                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17594            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17595                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17596                        + " before boot completion");
17597                throw new IllegalStateException("Cannot broadcast before boot completed");
17598            }
17599        }
17600
17601        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17602            throw new IllegalArgumentException(
17603                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17604        }
17605
17606        return intent;
17607    }
17608
17609    public final int broadcastIntent(IApplicationThread caller,
17610            Intent intent, String resolvedType, IIntentReceiver resultTo,
17611            int resultCode, String resultData, Bundle resultExtras,
17612            String[] requiredPermissions, int appOp, Bundle bOptions,
17613            boolean serialized, boolean sticky, int userId) {
17614        enforceNotIsolatedCaller("broadcastIntent");
17615        synchronized(this) {
17616            intent = verifyBroadcastLocked(intent);
17617
17618            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17619            final int callingPid = Binder.getCallingPid();
17620            final int callingUid = Binder.getCallingUid();
17621            final long origId = Binder.clearCallingIdentity();
17622            int res = broadcastIntentLocked(callerApp,
17623                    callerApp != null ? callerApp.info.packageName : null,
17624                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17625                    requiredPermissions, appOp, null, serialized, sticky,
17626                    callingPid, callingUid, userId);
17627            Binder.restoreCallingIdentity(origId);
17628            return res;
17629        }
17630    }
17631
17632
17633    int broadcastIntentInPackage(String packageName, int uid,
17634            Intent intent, String resolvedType, IIntentReceiver resultTo,
17635            int resultCode, String resultData, Bundle resultExtras,
17636            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17637            int userId) {
17638        synchronized(this) {
17639            intent = verifyBroadcastLocked(intent);
17640
17641            final long origId = Binder.clearCallingIdentity();
17642            String[] requiredPermissions = requiredPermission == null ? null
17643                    : new String[] {requiredPermission};
17644            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17645                    resultTo, resultCode, resultData, resultExtras,
17646                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17647                    sticky, -1, uid, userId);
17648            Binder.restoreCallingIdentity(origId);
17649            return res;
17650        }
17651    }
17652
17653    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17654        // Refuse possible leaked file descriptors
17655        if (intent != null && intent.hasFileDescriptors() == true) {
17656            throw new IllegalArgumentException("File descriptors passed in Intent");
17657        }
17658
17659        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17660                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17661
17662        synchronized(this) {
17663            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17664                    != PackageManager.PERMISSION_GRANTED) {
17665                String msg = "Permission Denial: unbroadcastIntent() from pid="
17666                        + Binder.getCallingPid()
17667                        + ", uid=" + Binder.getCallingUid()
17668                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17669                Slog.w(TAG, msg);
17670                throw new SecurityException(msg);
17671            }
17672            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17673            if (stickies != null) {
17674                ArrayList<Intent> list = stickies.get(intent.getAction());
17675                if (list != null) {
17676                    int N = list.size();
17677                    int i;
17678                    for (i=0; i<N; i++) {
17679                        if (intent.filterEquals(list.get(i))) {
17680                            list.remove(i);
17681                            break;
17682                        }
17683                    }
17684                    if (list.size() <= 0) {
17685                        stickies.remove(intent.getAction());
17686                    }
17687                }
17688                if (stickies.size() <= 0) {
17689                    mStickyBroadcasts.remove(userId);
17690                }
17691            }
17692        }
17693    }
17694
17695    void backgroundServicesFinishedLocked(int userId) {
17696        for (BroadcastQueue queue : mBroadcastQueues) {
17697            queue.backgroundServicesFinishedLocked(userId);
17698        }
17699    }
17700
17701    public void finishReceiver(IBinder who, int resultCode, String resultData,
17702            Bundle resultExtras, boolean resultAbort, int flags) {
17703        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17704
17705        // Refuse possible leaked file descriptors
17706        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17707            throw new IllegalArgumentException("File descriptors passed in Bundle");
17708        }
17709
17710        final long origId = Binder.clearCallingIdentity();
17711        try {
17712            boolean doNext = false;
17713            BroadcastRecord r;
17714
17715            synchronized(this) {
17716                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17717                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17718                r = queue.getMatchingOrderedReceiver(who);
17719                if (r != null) {
17720                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17721                        resultData, resultExtras, resultAbort, true);
17722                }
17723            }
17724
17725            if (doNext) {
17726                r.queue.processNextBroadcast(false);
17727            }
17728            trimApplications();
17729        } finally {
17730            Binder.restoreCallingIdentity(origId);
17731        }
17732    }
17733
17734    // =========================================================
17735    // INSTRUMENTATION
17736    // =========================================================
17737
17738    public boolean startInstrumentation(ComponentName className,
17739            String profileFile, int flags, Bundle arguments,
17740            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17741            int userId, String abiOverride) {
17742        enforceNotIsolatedCaller("startInstrumentation");
17743        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17744                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17745        // Refuse possible leaked file descriptors
17746        if (arguments != null && arguments.hasFileDescriptors()) {
17747            throw new IllegalArgumentException("File descriptors passed in Bundle");
17748        }
17749
17750        synchronized(this) {
17751            InstrumentationInfo ii = null;
17752            ApplicationInfo ai = null;
17753            try {
17754                ii = mContext.getPackageManager().getInstrumentationInfo(
17755                    className, STOCK_PM_FLAGS);
17756                ai = AppGlobals.getPackageManager().getApplicationInfo(
17757                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17758            } catch (PackageManager.NameNotFoundException e) {
17759            } catch (RemoteException e) {
17760            }
17761            if (ii == null) {
17762                reportStartInstrumentationFailure(watcher, className,
17763                        "Unable to find instrumentation info for: " + className);
17764                return false;
17765            }
17766            if (ai == null) {
17767                reportStartInstrumentationFailure(watcher, className,
17768                        "Unable to find instrumentation target package: " + ii.targetPackage);
17769                return false;
17770            }
17771
17772            int match = mContext.getPackageManager().checkSignatures(
17773                    ii.targetPackage, ii.packageName);
17774            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17775                String msg = "Permission Denial: starting instrumentation "
17776                        + className + " from pid="
17777                        + Binder.getCallingPid()
17778                        + ", uid=" + Binder.getCallingPid()
17779                        + " not allowed because package " + ii.packageName
17780                        + " does not have a signature matching the target "
17781                        + ii.targetPackage;
17782                reportStartInstrumentationFailure(watcher, className, msg);
17783                throw new SecurityException(msg);
17784            }
17785
17786            final long origId = Binder.clearCallingIdentity();
17787            // Instrumentation can kill and relaunch even persistent processes
17788            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17789                    "start instr");
17790            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17791            app.instrumentationClass = className;
17792            app.instrumentationInfo = ai;
17793            app.instrumentationProfileFile = profileFile;
17794            app.instrumentationArguments = arguments;
17795            app.instrumentationWatcher = watcher;
17796            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17797            app.instrumentationResultClass = className;
17798            Binder.restoreCallingIdentity(origId);
17799        }
17800
17801        return true;
17802    }
17803
17804    /**
17805     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17806     * error to the logs, but if somebody is watching, send the report there too.  This enables
17807     * the "am" command to report errors with more information.
17808     *
17809     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17810     * @param cn The component name of the instrumentation.
17811     * @param report The error report.
17812     */
17813    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17814            ComponentName cn, String report) {
17815        Slog.w(TAG, report);
17816        try {
17817            if (watcher != null) {
17818                Bundle results = new Bundle();
17819                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17820                results.putString("Error", report);
17821                watcher.instrumentationStatus(cn, -1, results);
17822            }
17823        } catch (RemoteException e) {
17824            Slog.w(TAG, e);
17825        }
17826    }
17827
17828    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17829        if (app.instrumentationWatcher != null) {
17830            try {
17831                // NOTE:  IInstrumentationWatcher *must* be oneway here
17832                app.instrumentationWatcher.instrumentationFinished(
17833                    app.instrumentationClass,
17834                    resultCode,
17835                    results);
17836            } catch (RemoteException e) {
17837            }
17838        }
17839
17840        // Can't call out of the system process with a lock held, so post a message.
17841        if (app.instrumentationUiAutomationConnection != null) {
17842            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17843                    app.instrumentationUiAutomationConnection).sendToTarget();
17844        }
17845
17846        app.instrumentationWatcher = null;
17847        app.instrumentationUiAutomationConnection = null;
17848        app.instrumentationClass = null;
17849        app.instrumentationInfo = null;
17850        app.instrumentationProfileFile = null;
17851        app.instrumentationArguments = null;
17852
17853        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17854                "finished inst");
17855    }
17856
17857    public void finishInstrumentation(IApplicationThread target,
17858            int resultCode, Bundle results) {
17859        int userId = UserHandle.getCallingUserId();
17860        // Refuse possible leaked file descriptors
17861        if (results != null && results.hasFileDescriptors()) {
17862            throw new IllegalArgumentException("File descriptors passed in Intent");
17863        }
17864
17865        synchronized(this) {
17866            ProcessRecord app = getRecordForAppLocked(target);
17867            if (app == null) {
17868                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17869                return;
17870            }
17871            final long origId = Binder.clearCallingIdentity();
17872            finishInstrumentationLocked(app, resultCode, results);
17873            Binder.restoreCallingIdentity(origId);
17874        }
17875    }
17876
17877    // =========================================================
17878    // CONFIGURATION
17879    // =========================================================
17880
17881    public ConfigurationInfo getDeviceConfigurationInfo() {
17882        ConfigurationInfo config = new ConfigurationInfo();
17883        synchronized (this) {
17884            config.reqTouchScreen = mConfiguration.touchscreen;
17885            config.reqKeyboardType = mConfiguration.keyboard;
17886            config.reqNavigation = mConfiguration.navigation;
17887            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17888                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17889                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17890            }
17891            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17892                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17893                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17894            }
17895            config.reqGlEsVersion = GL_ES_VERSION;
17896        }
17897        return config;
17898    }
17899
17900    ActivityStack getFocusedStack() {
17901        return mStackSupervisor.getFocusedStack();
17902    }
17903
17904    @Override
17905    public int getFocusedStackId() throws RemoteException {
17906        ActivityStack focusedStack = getFocusedStack();
17907        if (focusedStack != null) {
17908            return focusedStack.getStackId();
17909        }
17910        return -1;
17911    }
17912
17913    public Configuration getConfiguration() {
17914        Configuration ci;
17915        synchronized(this) {
17916            ci = new Configuration(mConfiguration);
17917            ci.userSetLocale = false;
17918        }
17919        return ci;
17920    }
17921
17922    @Override
17923    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17924        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17925                "suppressResizeConfigChanges()");
17926        synchronized (this) {
17927            mSuppressResizeConfigChanges = suppress;
17928        }
17929    }
17930
17931    @Override
17932    public void moveTasksToFullscreenStack(int fromStackId) {
17933        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17934                "moveTasksToFullscreenStack()");
17935        if (fromStackId == HOME_STACK_ID) {
17936            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17937        }
17938        synchronized (this) {
17939            final long origId = Binder.clearCallingIdentity();
17940            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17941            if (stack != null) {
17942                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17943                for (int i = tasks.size() - 1; i >= 0; i--) {
17944                    mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17945                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
17946                }
17947            }
17948            Binder.restoreCallingIdentity(origId);
17949        }
17950    }
17951
17952    @Override
17953    public void updatePersistentConfiguration(Configuration values) {
17954        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17955                "updateConfiguration()");
17956        enforceWriteSettingsPermission("updateConfiguration()");
17957        if (values == null) {
17958            throw new NullPointerException("Configuration must not be null");
17959        }
17960
17961        int userId = UserHandle.getCallingUserId();
17962
17963        synchronized(this) {
17964            final long origId = Binder.clearCallingIdentity();
17965            updateConfigurationLocked(values, null, false, true, userId);
17966            Binder.restoreCallingIdentity(origId);
17967        }
17968    }
17969
17970    private void enforceWriteSettingsPermission(String func) {
17971        int uid = Binder.getCallingUid();
17972        if (uid == Process.ROOT_UID) {
17973            return;
17974        }
17975
17976        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17977                Settings.getPackageNameForUid(mContext, uid), false)) {
17978            return;
17979        }
17980
17981        String msg = "Permission Denial: " + func + " from pid="
17982                + Binder.getCallingPid()
17983                + ", uid=" + uid
17984                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17985        Slog.w(TAG, msg);
17986        throw new SecurityException(msg);
17987    }
17988
17989    public void updateConfiguration(Configuration values) {
17990        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17991                "updateConfiguration()");
17992
17993        synchronized(this) {
17994            if (values == null && mWindowManager != null) {
17995                // sentinel: fetch the current configuration from the window manager
17996                values = mWindowManager.computeNewConfiguration();
17997            }
17998
17999            if (mWindowManager != null) {
18000                mProcessList.applyDisplaySize(mWindowManager);
18001            }
18002
18003            final long origId = Binder.clearCallingIdentity();
18004            if (values != null) {
18005                Settings.System.clearConfiguration(values);
18006            }
18007            updateConfigurationLocked(values, null, false);
18008            Binder.restoreCallingIdentity(origId);
18009        }
18010    }
18011
18012    void updateUserConfigurationLocked() {
18013        Configuration configuration = new Configuration(mConfiguration);
18014        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18015                mUserController.getCurrentUserIdLocked());
18016        updateConfigurationLocked(configuration, null, false);
18017    }
18018
18019    boolean updateConfigurationLocked(Configuration values,
18020            ActivityRecord starting, boolean initLocale) {
18021        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18022        return updateConfigurationLocked(values, starting, initLocale, false,
18023                UserHandle.USER_NULL);
18024    }
18025
18026    // To cache the list of supported system locales
18027    private String[] mSupportedSystemLocales = null;
18028
18029    /**
18030     * Do either or both things: (1) change the current configuration, and (2)
18031     * make sure the given activity is running with the (now) current
18032     * configuration.  Returns true if the activity has been left running, or
18033     * false if <var>starting</var> is being destroyed to match the new
18034     * configuration.
18035     *
18036     * @param userId is only used when persistent parameter is set to true to persist configuration
18037     *               for that particular user
18038     */
18039    private boolean updateConfigurationLocked(Configuration values,
18040            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18041        int changes = 0;
18042
18043        if (values != null) {
18044            Configuration newConfig = new Configuration(mConfiguration);
18045            changes = newConfig.updateFrom(values);
18046            if (changes != 0) {
18047                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18048                        "Updating configuration to: " + values);
18049
18050                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18051
18052                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18053                    final Locale locale;
18054                    if (values.getLocales().size() == 1) {
18055                        // This is an optimization to avoid the JNI call when the result of
18056                        // getFirstMatch() does not depend on the supported locales.
18057                        locale = values.getLocales().getPrimary();
18058                    } else {
18059                        if (mSupportedSystemLocales == null) {
18060                            mSupportedSystemLocales =
18061                                    Resources.getSystem().getAssets().getLocales();
18062                        }
18063                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18064                    }
18065                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18066                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18067                            locale));
18068                }
18069
18070                mConfigurationSeq++;
18071                if (mConfigurationSeq <= 0) {
18072                    mConfigurationSeq = 1;
18073                }
18074                newConfig.seq = mConfigurationSeq;
18075                mConfiguration = newConfig;
18076                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18077                mUsageStatsService.reportConfigurationChange(newConfig,
18078                        mUserController.getCurrentUserIdLocked());
18079                //mUsageStatsService.noteStartConfig(newConfig);
18080
18081                final Configuration configCopy = new Configuration(mConfiguration);
18082
18083                // TODO: If our config changes, should we auto dismiss any currently
18084                // showing dialogs?
18085                mShowDialogs = shouldShowDialogs(newConfig);
18086
18087                AttributeCache ac = AttributeCache.instance();
18088                if (ac != null) {
18089                    ac.updateConfiguration(configCopy);
18090                }
18091
18092                // Make sure all resources in our process are updated
18093                // right now, so that anyone who is going to retrieve
18094                // resource values after we return will be sure to get
18095                // the new ones.  This is especially important during
18096                // boot, where the first config change needs to guarantee
18097                // all resources have that config before following boot
18098                // code is executed.
18099                mSystemThread.applyConfigurationToResources(configCopy);
18100
18101                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18102                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18103                    msg.obj = new Configuration(configCopy);
18104                    msg.arg1 = userId;
18105                    mHandler.sendMessage(msg);
18106                }
18107
18108                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18109                    ProcessRecord app = mLruProcesses.get(i);
18110                    try {
18111                        if (app.thread != null) {
18112                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18113                                    + app.processName + " new config " + mConfiguration);
18114                            app.thread.scheduleConfigurationChanged(configCopy);
18115                        }
18116                    } catch (Exception e) {
18117                    }
18118                }
18119                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18120                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18121                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18122                        | Intent.FLAG_RECEIVER_FOREGROUND);
18123                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18124                        null, AppOpsManager.OP_NONE, null, false, false,
18125                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18126                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18127                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18128                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18129                    if (!mProcessesReady) {
18130                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18131                    }
18132                    broadcastIntentLocked(null, null, intent,
18133                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18134                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18135                }
18136            }
18137        }
18138
18139        boolean kept = true;
18140        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18141        // mainStack is null during startup.
18142        if (mainStack != null) {
18143            if (changes != 0 && starting == null) {
18144                // If the configuration changed, and the caller is not already
18145                // in the process of starting an activity, then find the top
18146                // activity to check if its configuration needs to change.
18147                starting = mainStack.topRunningActivityLocked();
18148            }
18149
18150            if (starting != null) {
18151                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18152                // And we need to make sure at this point that all other activities
18153                // are made visible with the correct configuration.
18154                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18155                        !PRESERVE_WINDOWS);
18156            }
18157        }
18158
18159        if (values != null && mWindowManager != null) {
18160            mWindowManager.setNewConfiguration(mConfiguration);
18161        }
18162
18163        return kept;
18164    }
18165
18166    /**
18167     * Decide based on the configuration whether we should shouw the ANR,
18168     * crash, etc dialogs.  The idea is that if there is no affordnace to
18169     * press the on-screen buttons, we shouldn't show the dialog.
18170     *
18171     * A thought: SystemUI might also want to get told about this, the Power
18172     * dialog / global actions also might want different behaviors.
18173     */
18174    private static final boolean shouldShowDialogs(Configuration config) {
18175        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18176                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18177                && config.navigation == Configuration.NAVIGATION_NONAV);
18178    }
18179
18180    @Override
18181    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18182        synchronized (this) {
18183            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18184            if (srec != null) {
18185                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18186            }
18187        }
18188        return false;
18189    }
18190
18191    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18192            Intent resultData) {
18193
18194        synchronized (this) {
18195            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18196            if (r != null) {
18197                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18198            }
18199            return false;
18200        }
18201    }
18202
18203    public int getLaunchedFromUid(IBinder activityToken) {
18204        ActivityRecord srec;
18205        synchronized (this) {
18206            srec = ActivityRecord.forTokenLocked(activityToken);
18207        }
18208        if (srec == null) {
18209            return -1;
18210        }
18211        return srec.launchedFromUid;
18212    }
18213
18214    public String getLaunchedFromPackage(IBinder activityToken) {
18215        ActivityRecord srec;
18216        synchronized (this) {
18217            srec = ActivityRecord.forTokenLocked(activityToken);
18218        }
18219        if (srec == null) {
18220            return null;
18221        }
18222        return srec.launchedFromPackage;
18223    }
18224
18225    // =========================================================
18226    // LIFETIME MANAGEMENT
18227    // =========================================================
18228
18229    // Returns which broadcast queue the app is the current [or imminent] receiver
18230    // on, or 'null' if the app is not an active broadcast recipient.
18231    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18232        BroadcastRecord r = app.curReceiver;
18233        if (r != null) {
18234            return r.queue;
18235        }
18236
18237        // It's not the current receiver, but it might be starting up to become one
18238        synchronized (this) {
18239            for (BroadcastQueue queue : mBroadcastQueues) {
18240                r = queue.mPendingBroadcast;
18241                if (r != null && r.curApp == app) {
18242                    // found it; report which queue it's in
18243                    return queue;
18244                }
18245            }
18246        }
18247
18248        return null;
18249    }
18250
18251    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18252            ComponentName targetComponent, String targetProcess) {
18253        if (!mTrackingAssociations) {
18254            return null;
18255        }
18256        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18257                = mAssociations.get(targetUid);
18258        if (components == null) {
18259            components = new ArrayMap<>();
18260            mAssociations.put(targetUid, components);
18261        }
18262        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18263        if (sourceUids == null) {
18264            sourceUids = new SparseArray<>();
18265            components.put(targetComponent, sourceUids);
18266        }
18267        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18268        if (sourceProcesses == null) {
18269            sourceProcesses = new ArrayMap<>();
18270            sourceUids.put(sourceUid, sourceProcesses);
18271        }
18272        Association ass = sourceProcesses.get(sourceProcess);
18273        if (ass == null) {
18274            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18275                    targetProcess);
18276            sourceProcesses.put(sourceProcess, ass);
18277        }
18278        ass.mCount++;
18279        ass.mNesting++;
18280        if (ass.mNesting == 1) {
18281            ass.mStartTime = SystemClock.uptimeMillis();
18282        }
18283        return ass;
18284    }
18285
18286    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18287            ComponentName targetComponent) {
18288        if (!mTrackingAssociations) {
18289            return;
18290        }
18291        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18292                = mAssociations.get(targetUid);
18293        if (components == null) {
18294            return;
18295        }
18296        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18297        if (sourceUids == null) {
18298            return;
18299        }
18300        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18301        if (sourceProcesses == null) {
18302            return;
18303        }
18304        Association ass = sourceProcesses.get(sourceProcess);
18305        if (ass == null || ass.mNesting <= 0) {
18306            return;
18307        }
18308        ass.mNesting--;
18309        if (ass.mNesting == 0) {
18310            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18311        }
18312    }
18313
18314    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18315            boolean doingAll, long now) {
18316        if (mAdjSeq == app.adjSeq) {
18317            // This adjustment has already been computed.
18318            return app.curRawAdj;
18319        }
18320
18321        if (app.thread == null) {
18322            app.adjSeq = mAdjSeq;
18323            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18324            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18325            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18326        }
18327
18328        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18329        app.adjSource = null;
18330        app.adjTarget = null;
18331        app.empty = false;
18332        app.cached = false;
18333
18334        final int activitiesSize = app.activities.size();
18335
18336        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18337            // The max adjustment doesn't allow this app to be anything
18338            // below foreground, so it is not worth doing work for it.
18339            app.adjType = "fixed";
18340            app.adjSeq = mAdjSeq;
18341            app.curRawAdj = app.maxAdj;
18342            app.foregroundActivities = false;
18343            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18344            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18345            // System processes can do UI, and when they do we want to have
18346            // them trim their memory after the user leaves the UI.  To
18347            // facilitate this, here we need to determine whether or not it
18348            // is currently showing UI.
18349            app.systemNoUi = true;
18350            if (app == TOP_APP) {
18351                app.systemNoUi = false;
18352            } else if (activitiesSize > 0) {
18353                for (int j = 0; j < activitiesSize; j++) {
18354                    final ActivityRecord r = app.activities.get(j);
18355                    if (r.visible) {
18356                        app.systemNoUi = false;
18357                    }
18358                }
18359            }
18360            if (!app.systemNoUi) {
18361                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18362            }
18363            return (app.curAdj=app.maxAdj);
18364        }
18365
18366        app.systemNoUi = false;
18367
18368        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18369
18370        // Determine the importance of the process, starting with most
18371        // important to least, and assign an appropriate OOM adjustment.
18372        int adj;
18373        int schedGroup;
18374        int procState;
18375        boolean foregroundActivities = false;
18376        BroadcastQueue queue;
18377        if (app == TOP_APP) {
18378            // The last app on the list is the foreground app.
18379            adj = ProcessList.FOREGROUND_APP_ADJ;
18380            schedGroup = Process.THREAD_GROUP_DEFAULT;
18381            app.adjType = "top-activity";
18382            foregroundActivities = true;
18383            procState = PROCESS_STATE_CUR_TOP;
18384        } else if (app.instrumentationClass != null) {
18385            // Don't want to kill running instrumentation.
18386            adj = ProcessList.FOREGROUND_APP_ADJ;
18387            schedGroup = Process.THREAD_GROUP_DEFAULT;
18388            app.adjType = "instrumentation";
18389            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18390        } else if ((queue = isReceivingBroadcast(app)) != null) {
18391            // An app that is currently receiving a broadcast also
18392            // counts as being in the foreground for OOM killer purposes.
18393            // It's placed in a sched group based on the nature of the
18394            // broadcast as reflected by which queue it's active in.
18395            adj = ProcessList.FOREGROUND_APP_ADJ;
18396            schedGroup = (queue == mFgBroadcastQueue)
18397                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18398            app.adjType = "broadcast";
18399            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18400        } else if (app.executingServices.size() > 0) {
18401            // An app that is currently executing a service callback also
18402            // counts as being in the foreground.
18403            adj = ProcessList.FOREGROUND_APP_ADJ;
18404            schedGroup = app.execServicesFg ?
18405                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18406            app.adjType = "exec-service";
18407            procState = ActivityManager.PROCESS_STATE_SERVICE;
18408            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18409        } else {
18410            // As far as we know the process is empty.  We may change our mind later.
18411            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18412            // At this point we don't actually know the adjustment.  Use the cached adj
18413            // value that the caller wants us to.
18414            adj = cachedAdj;
18415            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18416            app.cached = true;
18417            app.empty = true;
18418            app.adjType = "cch-empty";
18419        }
18420
18421        // Examine all activities if not already foreground.
18422        if (!foregroundActivities && activitiesSize > 0) {
18423            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18424            for (int j = 0; j < activitiesSize; j++) {
18425                final ActivityRecord r = app.activities.get(j);
18426                if (r.app != app) {
18427                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18428                            + app + "?!? Using " + r.app + " instead.");
18429                    continue;
18430                }
18431                if (r.visible) {
18432                    // App has a visible activity; only upgrade adjustment.
18433                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18434                        adj = ProcessList.VISIBLE_APP_ADJ;
18435                        app.adjType = "visible";
18436                    }
18437                    if (procState > PROCESS_STATE_CUR_TOP) {
18438                        procState = PROCESS_STATE_CUR_TOP;
18439                    }
18440                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18441                    app.cached = false;
18442                    app.empty = false;
18443                    foregroundActivities = true;
18444                    if (r.task != null && minLayer > 0) {
18445                        final int layer = r.task.mLayerRank;
18446                        if (layer >= 0 && minLayer > layer) {
18447                            minLayer = layer;
18448                        }
18449                    }
18450                    break;
18451                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18452                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18453                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18454                        app.adjType = "pausing";
18455                    }
18456                    if (procState > PROCESS_STATE_CUR_TOP) {
18457                        procState = PROCESS_STATE_CUR_TOP;
18458                    }
18459                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18460                    app.cached = false;
18461                    app.empty = false;
18462                    foregroundActivities = true;
18463                } else if (r.state == ActivityState.STOPPING) {
18464                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18465                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18466                        app.adjType = "stopping";
18467                    }
18468                    // For the process state, we will at this point consider the
18469                    // process to be cached.  It will be cached either as an activity
18470                    // or empty depending on whether the activity is finishing.  We do
18471                    // this so that we can treat the process as cached for purposes of
18472                    // memory trimming (determing current memory level, trim command to
18473                    // send to process) since there can be an arbitrary number of stopping
18474                    // processes and they should soon all go into the cached state.
18475                    if (!r.finishing) {
18476                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18477                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18478                        }
18479                    }
18480                    app.cached = false;
18481                    app.empty = false;
18482                    foregroundActivities = true;
18483                } else {
18484                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18485                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18486                        app.adjType = "cch-act";
18487                    }
18488                }
18489            }
18490            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18491                adj += minLayer;
18492            }
18493        }
18494
18495        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18496                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18497            if (app.foregroundServices) {
18498                // The user is aware of this app, so make it visible.
18499                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18500                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18501                app.cached = false;
18502                app.adjType = "fg-service";
18503                schedGroup = Process.THREAD_GROUP_DEFAULT;
18504            } else if (app.forcingToForeground != null) {
18505                // The user is aware of this app, so make it visible.
18506                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18507                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18508                app.cached = false;
18509                app.adjType = "force-fg";
18510                app.adjSource = app.forcingToForeground;
18511                schedGroup = Process.THREAD_GROUP_DEFAULT;
18512            }
18513        }
18514
18515        if (app == mHeavyWeightProcess) {
18516            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18517                // We don't want to kill the current heavy-weight process.
18518                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18519                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18520                app.cached = false;
18521                app.adjType = "heavy";
18522            }
18523            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18524                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18525            }
18526        }
18527
18528        if (app == mHomeProcess) {
18529            if (adj > ProcessList.HOME_APP_ADJ) {
18530                // This process is hosting what we currently consider to be the
18531                // home app, so we don't want to let it go into the background.
18532                adj = ProcessList.HOME_APP_ADJ;
18533                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18534                app.cached = false;
18535                app.adjType = "home";
18536            }
18537            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18538                procState = ActivityManager.PROCESS_STATE_HOME;
18539            }
18540        }
18541
18542        if (app == mPreviousProcess && app.activities.size() > 0) {
18543            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18544                // This was the previous process that showed UI to the user.
18545                // We want to try to keep it around more aggressively, to give
18546                // a good experience around switching between two apps.
18547                adj = ProcessList.PREVIOUS_APP_ADJ;
18548                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18549                app.cached = false;
18550                app.adjType = "previous";
18551            }
18552            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18553                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18554            }
18555        }
18556
18557        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18558                + " reason=" + app.adjType);
18559
18560        // By default, we use the computed adjustment.  It may be changed if
18561        // there are applications dependent on our services or providers, but
18562        // this gives us a baseline and makes sure we don't get into an
18563        // infinite recursion.
18564        app.adjSeq = mAdjSeq;
18565        app.curRawAdj = adj;
18566        app.hasStartedServices = false;
18567
18568        if (mBackupTarget != null && app == mBackupTarget.app) {
18569            // If possible we want to avoid killing apps while they're being backed up
18570            if (adj > ProcessList.BACKUP_APP_ADJ) {
18571                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18572                adj = ProcessList.BACKUP_APP_ADJ;
18573                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18574                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18575                }
18576                app.adjType = "backup";
18577                app.cached = false;
18578            }
18579            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18580                procState = ActivityManager.PROCESS_STATE_BACKUP;
18581            }
18582        }
18583
18584        boolean mayBeTop = false;
18585
18586        for (int is = app.services.size()-1;
18587                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18588                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18589                        || procState > ActivityManager.PROCESS_STATE_TOP);
18590                is--) {
18591            ServiceRecord s = app.services.valueAt(is);
18592            if (s.startRequested) {
18593                app.hasStartedServices = true;
18594                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18595                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18596                }
18597                if (app.hasShownUi && app != mHomeProcess) {
18598                    // If this process has shown some UI, let it immediately
18599                    // go to the LRU list because it may be pretty heavy with
18600                    // UI stuff.  We'll tag it with a label just to help
18601                    // debug and understand what is going on.
18602                    if (adj > ProcessList.SERVICE_ADJ) {
18603                        app.adjType = "cch-started-ui-services";
18604                    }
18605                } else {
18606                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18607                        // This service has seen some activity within
18608                        // recent memory, so we will keep its process ahead
18609                        // of the background processes.
18610                        if (adj > ProcessList.SERVICE_ADJ) {
18611                            adj = ProcessList.SERVICE_ADJ;
18612                            app.adjType = "started-services";
18613                            app.cached = false;
18614                        }
18615                    }
18616                    // If we have let the service slide into the background
18617                    // state, still have some text describing what it is doing
18618                    // even though the service no longer has an impact.
18619                    if (adj > ProcessList.SERVICE_ADJ) {
18620                        app.adjType = "cch-started-services";
18621                    }
18622                }
18623            }
18624            for (int conni = s.connections.size()-1;
18625                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18626                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18627                            || procState > ActivityManager.PROCESS_STATE_TOP);
18628                    conni--) {
18629                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18630                for (int i = 0;
18631                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18632                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18633                                || procState > ActivityManager.PROCESS_STATE_TOP);
18634                        i++) {
18635                    // XXX should compute this based on the max of
18636                    // all connected clients.
18637                    ConnectionRecord cr = clist.get(i);
18638                    if (cr.binding.client == app) {
18639                        // Binding to ourself is not interesting.
18640                        continue;
18641                    }
18642                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18643                        ProcessRecord client = cr.binding.client;
18644                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18645                                TOP_APP, doingAll, now);
18646                        int clientProcState = client.curProcState;
18647                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18648                            // If the other app is cached for any reason, for purposes here
18649                            // we are going to consider it empty.  The specific cached state
18650                            // doesn't propagate except under certain conditions.
18651                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18652                        }
18653                        String adjType = null;
18654                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18655                            // Not doing bind OOM management, so treat
18656                            // this guy more like a started service.
18657                            if (app.hasShownUi && app != mHomeProcess) {
18658                                // If this process has shown some UI, let it immediately
18659                                // go to the LRU list because it may be pretty heavy with
18660                                // UI stuff.  We'll tag it with a label just to help
18661                                // debug and understand what is going on.
18662                                if (adj > clientAdj) {
18663                                    adjType = "cch-bound-ui-services";
18664                                }
18665                                app.cached = false;
18666                                clientAdj = adj;
18667                                clientProcState = procState;
18668                            } else {
18669                                if (now >= (s.lastActivity
18670                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18671                                    // This service has not seen activity within
18672                                    // recent memory, so allow it to drop to the
18673                                    // LRU list if there is no other reason to keep
18674                                    // it around.  We'll also tag it with a label just
18675                                    // to help debug and undertand what is going on.
18676                                    if (adj > clientAdj) {
18677                                        adjType = "cch-bound-services";
18678                                    }
18679                                    clientAdj = adj;
18680                                }
18681                            }
18682                        }
18683                        if (adj > clientAdj) {
18684                            // If this process has recently shown UI, and
18685                            // the process that is binding to it is less
18686                            // important than being visible, then we don't
18687                            // care about the binding as much as we care
18688                            // about letting this process get into the LRU
18689                            // list to be killed and restarted if needed for
18690                            // memory.
18691                            if (app.hasShownUi && app != mHomeProcess
18692                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18693                                adjType = "cch-bound-ui-services";
18694                            } else {
18695                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18696                                        |Context.BIND_IMPORTANT)) != 0) {
18697                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18698                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18699                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18700                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18701                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18702                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18703                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18704                                    adj = clientAdj;
18705                                } else {
18706                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18707                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18708                                    }
18709                                }
18710                                if (!client.cached) {
18711                                    app.cached = false;
18712                                }
18713                                adjType = "service";
18714                            }
18715                        }
18716                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18717                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18718                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18719                            }
18720                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18721                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18722                                    // Special handling of clients who are in the top state.
18723                                    // We *may* want to consider this process to be in the
18724                                    // top state as well, but only if there is not another
18725                                    // reason for it to be running.  Being on the top is a
18726                                    // special state, meaning you are specifically running
18727                                    // for the current top app.  If the process is already
18728                                    // running in the background for some other reason, it
18729                                    // is more important to continue considering it to be
18730                                    // in the background state.
18731                                    mayBeTop = true;
18732                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18733                                } else {
18734                                    // Special handling for above-top states (persistent
18735                                    // processes).  These should not bring the current process
18736                                    // into the top state, since they are not on top.  Instead
18737                                    // give them the best state after that.
18738                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18739                                        clientProcState =
18740                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18741                                    } else if (mWakefulness
18742                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18743                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18744                                                    != 0) {
18745                                        clientProcState =
18746                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18747                                    } else {
18748                                        clientProcState =
18749                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18750                                    }
18751                                }
18752                            }
18753                        } else {
18754                            if (clientProcState <
18755                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18756                                clientProcState =
18757                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18758                            }
18759                        }
18760                        if (procState > clientProcState) {
18761                            procState = clientProcState;
18762                        }
18763                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18764                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18765                            app.pendingUiClean = true;
18766                        }
18767                        if (adjType != null) {
18768                            app.adjType = adjType;
18769                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18770                                    .REASON_SERVICE_IN_USE;
18771                            app.adjSource = cr.binding.client;
18772                            app.adjSourceProcState = clientProcState;
18773                            app.adjTarget = s.name;
18774                        }
18775                    }
18776                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18777                        app.treatLikeActivity = true;
18778                    }
18779                    final ActivityRecord a = cr.activity;
18780                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18781                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18782                                (a.visible || a.state == ActivityState.RESUMED
18783                                 || a.state == ActivityState.PAUSING)) {
18784                            adj = ProcessList.FOREGROUND_APP_ADJ;
18785                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18786                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18787                            }
18788                            app.cached = false;
18789                            app.adjType = "service";
18790                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18791                                    .REASON_SERVICE_IN_USE;
18792                            app.adjSource = a;
18793                            app.adjSourceProcState = procState;
18794                            app.adjTarget = s.name;
18795                        }
18796                    }
18797                }
18798            }
18799        }
18800
18801        for (int provi = app.pubProviders.size()-1;
18802                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18803                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18804                        || procState > ActivityManager.PROCESS_STATE_TOP);
18805                provi--) {
18806            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18807            for (int i = cpr.connections.size()-1;
18808                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18809                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18810                            || procState > ActivityManager.PROCESS_STATE_TOP);
18811                    i--) {
18812                ContentProviderConnection conn = cpr.connections.get(i);
18813                ProcessRecord client = conn.client;
18814                if (client == app) {
18815                    // Being our own client is not interesting.
18816                    continue;
18817                }
18818                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18819                int clientProcState = client.curProcState;
18820                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18821                    // If the other app is cached for any reason, for purposes here
18822                    // we are going to consider it empty.
18823                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18824                }
18825                if (adj > clientAdj) {
18826                    if (app.hasShownUi && app != mHomeProcess
18827                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18828                        app.adjType = "cch-ui-provider";
18829                    } else {
18830                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18831                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18832                        app.adjType = "provider";
18833                    }
18834                    app.cached &= client.cached;
18835                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18836                            .REASON_PROVIDER_IN_USE;
18837                    app.adjSource = client;
18838                    app.adjSourceProcState = clientProcState;
18839                    app.adjTarget = cpr.name;
18840                }
18841                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18842                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18843                        // Special handling of clients who are in the top state.
18844                        // We *may* want to consider this process to be in the
18845                        // top state as well, but only if there is not another
18846                        // reason for it to be running.  Being on the top is a
18847                        // special state, meaning you are specifically running
18848                        // for the current top app.  If the process is already
18849                        // running in the background for some other reason, it
18850                        // is more important to continue considering it to be
18851                        // in the background state.
18852                        mayBeTop = true;
18853                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18854                    } else {
18855                        // Special handling for above-top states (persistent
18856                        // processes).  These should not bring the current process
18857                        // into the top state, since they are not on top.  Instead
18858                        // give them the best state after that.
18859                        clientProcState =
18860                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18861                    }
18862                }
18863                if (procState > clientProcState) {
18864                    procState = clientProcState;
18865                }
18866                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18867                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18868                }
18869            }
18870            // If the provider has external (non-framework) process
18871            // dependencies, ensure that its adjustment is at least
18872            // FOREGROUND_APP_ADJ.
18873            if (cpr.hasExternalProcessHandles()) {
18874                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18875                    adj = ProcessList.FOREGROUND_APP_ADJ;
18876                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18877                    app.cached = false;
18878                    app.adjType = "provider";
18879                    app.adjTarget = cpr.name;
18880                }
18881                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18882                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18883                }
18884            }
18885        }
18886
18887        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18888            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18889                adj = ProcessList.PREVIOUS_APP_ADJ;
18890                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18891                app.cached = false;
18892                app.adjType = "provider";
18893            }
18894            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18895                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18896            }
18897        }
18898
18899        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18900            // A client of one of our services or providers is in the top state.  We
18901            // *may* want to be in the top state, but not if we are already running in
18902            // the background for some other reason.  For the decision here, we are going
18903            // to pick out a few specific states that we want to remain in when a client
18904            // is top (states that tend to be longer-term) and otherwise allow it to go
18905            // to the top state.
18906            switch (procState) {
18907                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18908                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18909                case ActivityManager.PROCESS_STATE_SERVICE:
18910                    // These all are longer-term states, so pull them up to the top
18911                    // of the background states, but not all the way to the top state.
18912                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18913                    break;
18914                default:
18915                    // Otherwise, top is a better choice, so take it.
18916                    procState = ActivityManager.PROCESS_STATE_TOP;
18917                    break;
18918            }
18919        }
18920
18921        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18922            if (app.hasClientActivities) {
18923                // This is a cached process, but with client activities.  Mark it so.
18924                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18925                app.adjType = "cch-client-act";
18926            } else if (app.treatLikeActivity) {
18927                // This is a cached process, but somebody wants us to treat it like it has
18928                // an activity, okay!
18929                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18930                app.adjType = "cch-as-act";
18931            }
18932        }
18933
18934        if (adj == ProcessList.SERVICE_ADJ) {
18935            if (doingAll) {
18936                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18937                mNewNumServiceProcs++;
18938                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18939                if (!app.serviceb) {
18940                    // This service isn't far enough down on the LRU list to
18941                    // normally be a B service, but if we are low on RAM and it
18942                    // is large we want to force it down since we would prefer to
18943                    // keep launcher over it.
18944                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18945                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18946                        app.serviceHighRam = true;
18947                        app.serviceb = true;
18948                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18949                    } else {
18950                        mNewNumAServiceProcs++;
18951                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18952                    }
18953                } else {
18954                    app.serviceHighRam = false;
18955                }
18956            }
18957            if (app.serviceb) {
18958                adj = ProcessList.SERVICE_B_ADJ;
18959            }
18960        }
18961
18962        app.curRawAdj = adj;
18963
18964        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18965        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18966        if (adj > app.maxAdj) {
18967            adj = app.maxAdj;
18968            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18969                schedGroup = Process.THREAD_GROUP_DEFAULT;
18970            }
18971        }
18972
18973        // Do final modification to adj.  Everything we do between here and applying
18974        // the final setAdj must be done in this function, because we will also use
18975        // it when computing the final cached adj later.  Note that we don't need to
18976        // worry about this for max adj above, since max adj will always be used to
18977        // keep it out of the cached vaues.
18978        app.curAdj = app.modifyRawOomAdj(adj);
18979        app.curSchedGroup = schedGroup;
18980        app.curProcState = procState;
18981        app.foregroundActivities = foregroundActivities;
18982
18983        return app.curRawAdj;
18984    }
18985
18986    /**
18987     * Record new PSS sample for a process.
18988     */
18989    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18990        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18991        proc.lastPssTime = now;
18992        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18993        if (DEBUG_PSS) Slog.d(TAG_PSS,
18994                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18995                + " state=" + ProcessList.makeProcStateString(procState));
18996        if (proc.initialIdlePss == 0) {
18997            proc.initialIdlePss = pss;
18998        }
18999        proc.lastPss = pss;
19000        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19001            proc.lastCachedPss = pss;
19002        }
19003
19004        final SparseArray<Pair<Long, String>> watchUids
19005                = mMemWatchProcesses.getMap().get(proc.processName);
19006        Long check = null;
19007        if (watchUids != null) {
19008            Pair<Long, String> val = watchUids.get(proc.uid);
19009            if (val == null) {
19010                val = watchUids.get(0);
19011            }
19012            if (val != null) {
19013                check = val.first;
19014            }
19015        }
19016        if (check != null) {
19017            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19018                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19019                if (!isDebuggable) {
19020                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19021                        isDebuggable = true;
19022                    }
19023                }
19024                if (isDebuggable) {
19025                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19026                    final ProcessRecord myProc = proc;
19027                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19028                    mMemWatchDumpProcName = proc.processName;
19029                    mMemWatchDumpFile = heapdumpFile.toString();
19030                    mMemWatchDumpPid = proc.pid;
19031                    mMemWatchDumpUid = proc.uid;
19032                    BackgroundThread.getHandler().post(new Runnable() {
19033                        @Override
19034                        public void run() {
19035                            revokeUriPermission(ActivityThread.currentActivityThread()
19036                                            .getApplicationThread(),
19037                                    DumpHeapActivity.JAVA_URI,
19038                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19039                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19040                                    UserHandle.myUserId());
19041                            ParcelFileDescriptor fd = null;
19042                            try {
19043                                heapdumpFile.delete();
19044                                fd = ParcelFileDescriptor.open(heapdumpFile,
19045                                        ParcelFileDescriptor.MODE_CREATE |
19046                                                ParcelFileDescriptor.MODE_TRUNCATE |
19047                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19048                                                ParcelFileDescriptor.MODE_APPEND);
19049                                IApplicationThread thread = myProc.thread;
19050                                if (thread != null) {
19051                                    try {
19052                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19053                                                "Requesting dump heap from "
19054                                                + myProc + " to " + heapdumpFile);
19055                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19056                                    } catch (RemoteException e) {
19057                                    }
19058                                }
19059                            } catch (FileNotFoundException e) {
19060                                e.printStackTrace();
19061                            } finally {
19062                                if (fd != null) {
19063                                    try {
19064                                        fd.close();
19065                                    } catch (IOException e) {
19066                                    }
19067                                }
19068                            }
19069                        }
19070                    });
19071                } else {
19072                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19073                            + ", but debugging not enabled");
19074                }
19075            }
19076        }
19077    }
19078
19079    /**
19080     * Schedule PSS collection of a process.
19081     */
19082    void requestPssLocked(ProcessRecord proc, int procState) {
19083        if (mPendingPssProcesses.contains(proc)) {
19084            return;
19085        }
19086        if (mPendingPssProcesses.size() == 0) {
19087            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19088        }
19089        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19090        proc.pssProcState = procState;
19091        mPendingPssProcesses.add(proc);
19092    }
19093
19094    /**
19095     * Schedule PSS collection of all processes.
19096     */
19097    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19098        if (!always) {
19099            if (now < (mLastFullPssTime +
19100                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19101                return;
19102            }
19103        }
19104        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19105        mLastFullPssTime = now;
19106        mFullPssPending = true;
19107        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19108        mPendingPssProcesses.clear();
19109        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19110            ProcessRecord app = mLruProcesses.get(i);
19111            if (app.thread == null
19112                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19113                continue;
19114            }
19115            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19116                app.pssProcState = app.setProcState;
19117                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19118                        mTestPssMode, isSleeping(), now);
19119                mPendingPssProcesses.add(app);
19120            }
19121        }
19122        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19123    }
19124
19125    public void setTestPssMode(boolean enabled) {
19126        synchronized (this) {
19127            mTestPssMode = enabled;
19128            if (enabled) {
19129                // Whenever we enable the mode, we want to take a snapshot all of current
19130                // process mem use.
19131                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19132            }
19133        }
19134    }
19135
19136    /**
19137     * Ask a given process to GC right now.
19138     */
19139    final void performAppGcLocked(ProcessRecord app) {
19140        try {
19141            app.lastRequestedGc = SystemClock.uptimeMillis();
19142            if (app.thread != null) {
19143                if (app.reportLowMemory) {
19144                    app.reportLowMemory = false;
19145                    app.thread.scheduleLowMemory();
19146                } else {
19147                    app.thread.processInBackground();
19148                }
19149            }
19150        } catch (Exception e) {
19151            // whatever.
19152        }
19153    }
19154
19155    /**
19156     * Returns true if things are idle enough to perform GCs.
19157     */
19158    private final boolean canGcNowLocked() {
19159        boolean processingBroadcasts = false;
19160        for (BroadcastQueue q : mBroadcastQueues) {
19161            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19162                processingBroadcasts = true;
19163            }
19164        }
19165        return !processingBroadcasts
19166                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19167    }
19168
19169    /**
19170     * Perform GCs on all processes that are waiting for it, but only
19171     * if things are idle.
19172     */
19173    final void performAppGcsLocked() {
19174        final int N = mProcessesToGc.size();
19175        if (N <= 0) {
19176            return;
19177        }
19178        if (canGcNowLocked()) {
19179            while (mProcessesToGc.size() > 0) {
19180                ProcessRecord proc = mProcessesToGc.remove(0);
19181                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19182                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19183                            <= SystemClock.uptimeMillis()) {
19184                        // To avoid spamming the system, we will GC processes one
19185                        // at a time, waiting a few seconds between each.
19186                        performAppGcLocked(proc);
19187                        scheduleAppGcsLocked();
19188                        return;
19189                    } else {
19190                        // It hasn't been long enough since we last GCed this
19191                        // process...  put it in the list to wait for its time.
19192                        addProcessToGcListLocked(proc);
19193                        break;
19194                    }
19195                }
19196            }
19197
19198            scheduleAppGcsLocked();
19199        }
19200    }
19201
19202    /**
19203     * If all looks good, perform GCs on all processes waiting for them.
19204     */
19205    final void performAppGcsIfAppropriateLocked() {
19206        if (canGcNowLocked()) {
19207            performAppGcsLocked();
19208            return;
19209        }
19210        // Still not idle, wait some more.
19211        scheduleAppGcsLocked();
19212    }
19213
19214    /**
19215     * Schedule the execution of all pending app GCs.
19216     */
19217    final void scheduleAppGcsLocked() {
19218        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19219
19220        if (mProcessesToGc.size() > 0) {
19221            // Schedule a GC for the time to the next process.
19222            ProcessRecord proc = mProcessesToGc.get(0);
19223            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19224
19225            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19226            long now = SystemClock.uptimeMillis();
19227            if (when < (now+GC_TIMEOUT)) {
19228                when = now + GC_TIMEOUT;
19229            }
19230            mHandler.sendMessageAtTime(msg, when);
19231        }
19232    }
19233
19234    /**
19235     * Add a process to the array of processes waiting to be GCed.  Keeps the
19236     * list in sorted order by the last GC time.  The process can't already be
19237     * on the list.
19238     */
19239    final void addProcessToGcListLocked(ProcessRecord proc) {
19240        boolean added = false;
19241        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19242            if (mProcessesToGc.get(i).lastRequestedGc <
19243                    proc.lastRequestedGc) {
19244                added = true;
19245                mProcessesToGc.add(i+1, proc);
19246                break;
19247            }
19248        }
19249        if (!added) {
19250            mProcessesToGc.add(0, proc);
19251        }
19252    }
19253
19254    /**
19255     * Set up to ask a process to GC itself.  This will either do it
19256     * immediately, or put it on the list of processes to gc the next
19257     * time things are idle.
19258     */
19259    final void scheduleAppGcLocked(ProcessRecord app) {
19260        long now = SystemClock.uptimeMillis();
19261        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19262            return;
19263        }
19264        if (!mProcessesToGc.contains(app)) {
19265            addProcessToGcListLocked(app);
19266            scheduleAppGcsLocked();
19267        }
19268    }
19269
19270    final void checkExcessivePowerUsageLocked(boolean doKills) {
19271        updateCpuStatsNow();
19272
19273        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19274        boolean doWakeKills = doKills;
19275        boolean doCpuKills = doKills;
19276        if (mLastPowerCheckRealtime == 0) {
19277            doWakeKills = false;
19278        }
19279        if (mLastPowerCheckUptime == 0) {
19280            doCpuKills = false;
19281        }
19282        if (stats.isScreenOn()) {
19283            doWakeKills = false;
19284        }
19285        final long curRealtime = SystemClock.elapsedRealtime();
19286        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19287        final long curUptime = SystemClock.uptimeMillis();
19288        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19289        mLastPowerCheckRealtime = curRealtime;
19290        mLastPowerCheckUptime = curUptime;
19291        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19292            doWakeKills = false;
19293        }
19294        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19295            doCpuKills = false;
19296        }
19297        int i = mLruProcesses.size();
19298        while (i > 0) {
19299            i--;
19300            ProcessRecord app = mLruProcesses.get(i);
19301            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19302                long wtime;
19303                synchronized (stats) {
19304                    wtime = stats.getProcessWakeTime(app.info.uid,
19305                            app.pid, curRealtime);
19306                }
19307                long wtimeUsed = wtime - app.lastWakeTime;
19308                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19309                if (DEBUG_POWER) {
19310                    StringBuilder sb = new StringBuilder(128);
19311                    sb.append("Wake for ");
19312                    app.toShortString(sb);
19313                    sb.append(": over ");
19314                    TimeUtils.formatDuration(realtimeSince, sb);
19315                    sb.append(" used ");
19316                    TimeUtils.formatDuration(wtimeUsed, sb);
19317                    sb.append(" (");
19318                    sb.append((wtimeUsed*100)/realtimeSince);
19319                    sb.append("%)");
19320                    Slog.i(TAG_POWER, sb.toString());
19321                    sb.setLength(0);
19322                    sb.append("CPU for ");
19323                    app.toShortString(sb);
19324                    sb.append(": over ");
19325                    TimeUtils.formatDuration(uptimeSince, sb);
19326                    sb.append(" used ");
19327                    TimeUtils.formatDuration(cputimeUsed, sb);
19328                    sb.append(" (");
19329                    sb.append((cputimeUsed*100)/uptimeSince);
19330                    sb.append("%)");
19331                    Slog.i(TAG_POWER, sb.toString());
19332                }
19333                // If a process has held a wake lock for more
19334                // than 50% of the time during this period,
19335                // that sounds bad.  Kill!
19336                if (doWakeKills && realtimeSince > 0
19337                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19338                    synchronized (stats) {
19339                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19340                                realtimeSince, wtimeUsed);
19341                    }
19342                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19343                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19344                } else if (doCpuKills && uptimeSince > 0
19345                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19346                    synchronized (stats) {
19347                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19348                                uptimeSince, cputimeUsed);
19349                    }
19350                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19351                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19352                } else {
19353                    app.lastWakeTime = wtime;
19354                    app.lastCpuTime = app.curCpuTime;
19355                }
19356            }
19357        }
19358    }
19359
19360    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19361            long nowElapsed) {
19362        boolean success = true;
19363
19364        if (app.curRawAdj != app.setRawAdj) {
19365            app.setRawAdj = app.curRawAdj;
19366        }
19367
19368        int changes = 0;
19369
19370        if (app.curAdj != app.setAdj) {
19371            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19372            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19373                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19374                    + app.adjType);
19375            app.setAdj = app.curAdj;
19376        }
19377
19378        if (app.setSchedGroup != app.curSchedGroup) {
19379            app.setSchedGroup = app.curSchedGroup;
19380            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19381                    "Setting process group of " + app.processName
19382                    + " to " + app.curSchedGroup);
19383            if (app.waitingToKill != null && app.curReceiver == null
19384                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19385                app.kill(app.waitingToKill, true);
19386                success = false;
19387            } else {
19388                if (true) {
19389                    long oldId = Binder.clearCallingIdentity();
19390                    try {
19391                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19392                    } catch (Exception e) {
19393                        Slog.w(TAG, "Failed setting process group of " + app.pid
19394                                + " to " + app.curSchedGroup);
19395                        e.printStackTrace();
19396                    } finally {
19397                        Binder.restoreCallingIdentity(oldId);
19398                    }
19399                } else {
19400                    if (app.thread != null) {
19401                        try {
19402                            app.thread.setSchedulingGroup(app.curSchedGroup);
19403                        } catch (RemoteException e) {
19404                        }
19405                    }
19406                }
19407            }
19408        }
19409        if (app.repForegroundActivities != app.foregroundActivities) {
19410            app.repForegroundActivities = app.foregroundActivities;
19411            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19412        }
19413        if (app.repProcState != app.curProcState) {
19414            app.repProcState = app.curProcState;
19415            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19416            if (app.thread != null) {
19417                try {
19418                    if (false) {
19419                        //RuntimeException h = new RuntimeException("here");
19420                        Slog.i(TAG, "Sending new process state " + app.repProcState
19421                                + " to " + app /*, h*/);
19422                    }
19423                    app.thread.setProcessState(app.repProcState);
19424                } catch (RemoteException e) {
19425                }
19426            }
19427        }
19428        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19429                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19430            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19431                // Experimental code to more aggressively collect pss while
19432                // running test...  the problem is that this tends to collect
19433                // the data right when a process is transitioning between process
19434                // states, which well tend to give noisy data.
19435                long start = SystemClock.uptimeMillis();
19436                long pss = Debug.getPss(app.pid, mTmpLong, null);
19437                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19438                mPendingPssProcesses.remove(app);
19439                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19440                        + " to " + app.curProcState + ": "
19441                        + (SystemClock.uptimeMillis()-start) + "ms");
19442            }
19443            app.lastStateTime = now;
19444            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19445                    mTestPssMode, isSleeping(), now);
19446            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19447                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19448                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19449                    + (app.nextPssTime-now) + ": " + app);
19450        } else {
19451            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19452                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19453                    mTestPssMode)))) {
19454                requestPssLocked(app, app.setProcState);
19455                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19456                        mTestPssMode, isSleeping(), now);
19457            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19458                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19459        }
19460        if (app.setProcState != app.curProcState) {
19461            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19462                    "Proc state change of " + app.processName
19463                            + " to " + app.curProcState);
19464            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19465            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19466            if (setImportant && !curImportant) {
19467                // This app is no longer something we consider important enough to allow to
19468                // use arbitrary amounts of battery power.  Note
19469                // its current wake lock time to later know to kill it if
19470                // it is not behaving well.
19471                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19472                synchronized (stats) {
19473                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19474                            app.pid, nowElapsed);
19475                }
19476                app.lastCpuTime = app.curCpuTime;
19477
19478            }
19479            // Inform UsageStats of important process state change
19480            // Must be called before updating setProcState
19481            maybeUpdateUsageStatsLocked(app, nowElapsed);
19482
19483            app.setProcState = app.curProcState;
19484            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19485                app.notCachedSinceIdle = false;
19486            }
19487            if (!doingAll) {
19488                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19489            } else {
19490                app.procStateChanged = true;
19491            }
19492        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19493                > USAGE_STATS_INTERACTION_INTERVAL) {
19494            // For apps that sit around for a long time in the interactive state, we need
19495            // to report this at least once a day so they don't go idle.
19496            maybeUpdateUsageStatsLocked(app, nowElapsed);
19497        }
19498
19499        if (changes != 0) {
19500            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19501                    "Changes in " + app + ": " + changes);
19502            int i = mPendingProcessChanges.size()-1;
19503            ProcessChangeItem item = null;
19504            while (i >= 0) {
19505                item = mPendingProcessChanges.get(i);
19506                if (item.pid == app.pid) {
19507                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19508                            "Re-using existing item: " + item);
19509                    break;
19510                }
19511                i--;
19512            }
19513            if (i < 0) {
19514                // No existing item in pending changes; need a new one.
19515                final int NA = mAvailProcessChanges.size();
19516                if (NA > 0) {
19517                    item = mAvailProcessChanges.remove(NA-1);
19518                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19519                            "Retrieving available item: " + item);
19520                } else {
19521                    item = new ProcessChangeItem();
19522                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19523                            "Allocating new item: " + item);
19524                }
19525                item.changes = 0;
19526                item.pid = app.pid;
19527                item.uid = app.info.uid;
19528                if (mPendingProcessChanges.size() == 0) {
19529                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19530                            "*** Enqueueing dispatch processes changed!");
19531                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19532                }
19533                mPendingProcessChanges.add(item);
19534            }
19535            item.changes |= changes;
19536            item.processState = app.repProcState;
19537            item.foregroundActivities = app.repForegroundActivities;
19538            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19539                    "Item " + Integer.toHexString(System.identityHashCode(item))
19540                    + " " + app.toShortString() + ": changes=" + item.changes
19541                    + " procState=" + item.processState
19542                    + " foreground=" + item.foregroundActivities
19543                    + " type=" + app.adjType + " source=" + app.adjSource
19544                    + " target=" + app.adjTarget);
19545        }
19546
19547        return success;
19548    }
19549
19550    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19551        final UidRecord.ChangeItem pendingChange;
19552        if (uidRec == null || uidRec.pendingChange == null) {
19553            if (mPendingUidChanges.size() == 0) {
19554                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19555                        "*** Enqueueing dispatch uid changed!");
19556                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19557            }
19558            final int NA = mAvailUidChanges.size();
19559            if (NA > 0) {
19560                pendingChange = mAvailUidChanges.remove(NA-1);
19561                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19562                        "Retrieving available item: " + pendingChange);
19563            } else {
19564                pendingChange = new UidRecord.ChangeItem();
19565                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19566                        "Allocating new item: " + pendingChange);
19567            }
19568            if (uidRec != null) {
19569                uidRec.pendingChange = pendingChange;
19570                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19571                    // If this uid is going away, and we haven't yet reported it is gone,
19572                    // then do so now.
19573                    change = UidRecord.CHANGE_GONE_IDLE;
19574                }
19575            } else if (uid < 0) {
19576                throw new IllegalArgumentException("No UidRecord or uid");
19577            }
19578            pendingChange.uidRecord = uidRec;
19579            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19580            mPendingUidChanges.add(pendingChange);
19581        } else {
19582            pendingChange = uidRec.pendingChange;
19583            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19584                change = UidRecord.CHANGE_GONE_IDLE;
19585            }
19586        }
19587        pendingChange.change = change;
19588        pendingChange.processState = uidRec != null
19589                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19590    }
19591
19592    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19593            String authority) {
19594        if (app == null) return;
19595        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19596            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19597            if (userState == null) return;
19598            final long now = SystemClock.elapsedRealtime();
19599            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19600            if (lastReported == null || lastReported < now - 60 * 1000L) {
19601                mUsageStatsService.reportContentProviderUsage(
19602                        authority, providerPkgName, app.userId);
19603                userState.mProviderLastReportedFg.put(authority, now);
19604            }
19605        }
19606    }
19607
19608    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19609        if (DEBUG_USAGE_STATS) {
19610            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19611                    + "] state changes: old = " + app.setProcState + ", new = "
19612                    + app.curProcState);
19613        }
19614        if (mUsageStatsService == null) {
19615            return;
19616        }
19617        boolean isInteraction;
19618        // To avoid some abuse patterns, we are going to be careful about what we consider
19619        // to be an app interaction.  Being the top activity doesn't count while the display
19620        // is sleeping, nor do short foreground services.
19621        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19622            isInteraction = true;
19623            app.fgInteractionTime = 0;
19624        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19625            if (app.fgInteractionTime == 0) {
19626                app.fgInteractionTime = nowElapsed;
19627                isInteraction = false;
19628            } else {
19629                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19630            }
19631        } else {
19632            isInteraction = app.curProcState
19633                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19634            app.fgInteractionTime = 0;
19635        }
19636        if (isInteraction && (!app.reportedInteraction
19637                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19638            app.interactionEventTime = nowElapsed;
19639            String[] packages = app.getPackageList();
19640            if (packages != null) {
19641                for (int i = 0; i < packages.length; i++) {
19642                    mUsageStatsService.reportEvent(packages[i], app.userId,
19643                            UsageEvents.Event.SYSTEM_INTERACTION);
19644                }
19645            }
19646        }
19647        app.reportedInteraction = isInteraction;
19648        if (!isInteraction) {
19649            app.interactionEventTime = 0;
19650        }
19651    }
19652
19653    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19654        if (proc.thread != null) {
19655            if (proc.baseProcessTracker != null) {
19656                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19657            }
19658        }
19659    }
19660
19661    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19662            ProcessRecord TOP_APP, boolean doingAll, long now) {
19663        if (app.thread == null) {
19664            return false;
19665        }
19666
19667        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19668
19669        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19670    }
19671
19672    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19673            boolean oomAdj) {
19674        if (isForeground != proc.foregroundServices) {
19675            proc.foregroundServices = isForeground;
19676            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19677                    proc.info.uid);
19678            if (isForeground) {
19679                if (curProcs == null) {
19680                    curProcs = new ArrayList<ProcessRecord>();
19681                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19682                }
19683                if (!curProcs.contains(proc)) {
19684                    curProcs.add(proc);
19685                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19686                            proc.info.packageName, proc.info.uid);
19687                }
19688            } else {
19689                if (curProcs != null) {
19690                    if (curProcs.remove(proc)) {
19691                        mBatteryStatsService.noteEvent(
19692                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19693                                proc.info.packageName, proc.info.uid);
19694                        if (curProcs.size() <= 0) {
19695                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19696                        }
19697                    }
19698                }
19699            }
19700            if (oomAdj) {
19701                updateOomAdjLocked();
19702            }
19703        }
19704    }
19705
19706    private final ActivityRecord resumedAppLocked() {
19707        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19708        String pkg;
19709        int uid;
19710        if (act != null) {
19711            pkg = act.packageName;
19712            uid = act.info.applicationInfo.uid;
19713        } else {
19714            pkg = null;
19715            uid = -1;
19716        }
19717        // Has the UID or resumed package name changed?
19718        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19719                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19720            if (mCurResumedPackage != null) {
19721                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19722                        mCurResumedPackage, mCurResumedUid);
19723            }
19724            mCurResumedPackage = pkg;
19725            mCurResumedUid = uid;
19726            if (mCurResumedPackage != null) {
19727                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19728                        mCurResumedPackage, mCurResumedUid);
19729            }
19730        }
19731        return act;
19732    }
19733
19734    final boolean updateOomAdjLocked(ProcessRecord app) {
19735        final ActivityRecord TOP_ACT = resumedAppLocked();
19736        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19737        final boolean wasCached = app.cached;
19738
19739        mAdjSeq++;
19740
19741        // This is the desired cached adjusment we want to tell it to use.
19742        // If our app is currently cached, we know it, and that is it.  Otherwise,
19743        // we don't know it yet, and it needs to now be cached we will then
19744        // need to do a complete oom adj.
19745        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19746                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19747        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19748                SystemClock.uptimeMillis());
19749        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19750            // Changed to/from cached state, so apps after it in the LRU
19751            // list may also be changed.
19752            updateOomAdjLocked();
19753        }
19754        return success;
19755    }
19756
19757    final void updateOomAdjLocked() {
19758        final ActivityRecord TOP_ACT = resumedAppLocked();
19759        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19760        final long now = SystemClock.uptimeMillis();
19761        final long nowElapsed = SystemClock.elapsedRealtime();
19762        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19763        final int N = mLruProcesses.size();
19764
19765        if (false) {
19766            RuntimeException e = new RuntimeException();
19767            e.fillInStackTrace();
19768            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19769        }
19770
19771        // Reset state in all uid records.
19772        for (int i=mActiveUids.size()-1; i>=0; i--) {
19773            final UidRecord uidRec = mActiveUids.valueAt(i);
19774            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19775                    "Starting update of " + uidRec);
19776            uidRec.reset();
19777        }
19778
19779        mStackSupervisor.rankTaskLayersIfNeeded();
19780
19781        mAdjSeq++;
19782        mNewNumServiceProcs = 0;
19783        mNewNumAServiceProcs = 0;
19784
19785        final int emptyProcessLimit;
19786        final int cachedProcessLimit;
19787        if (mProcessLimit <= 0) {
19788            emptyProcessLimit = cachedProcessLimit = 0;
19789        } else if (mProcessLimit == 1) {
19790            emptyProcessLimit = 1;
19791            cachedProcessLimit = 0;
19792        } else {
19793            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19794            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19795        }
19796
19797        // Let's determine how many processes we have running vs.
19798        // how many slots we have for background processes; we may want
19799        // to put multiple processes in a slot of there are enough of
19800        // them.
19801        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19802                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19803        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19804        if (numEmptyProcs > cachedProcessLimit) {
19805            // If there are more empty processes than our limit on cached
19806            // processes, then use the cached process limit for the factor.
19807            // This ensures that the really old empty processes get pushed
19808            // down to the bottom, so if we are running low on memory we will
19809            // have a better chance at keeping around more cached processes
19810            // instead of a gazillion empty processes.
19811            numEmptyProcs = cachedProcessLimit;
19812        }
19813        int emptyFactor = numEmptyProcs/numSlots;
19814        if (emptyFactor < 1) emptyFactor = 1;
19815        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19816        if (cachedFactor < 1) cachedFactor = 1;
19817        int stepCached = 0;
19818        int stepEmpty = 0;
19819        int numCached = 0;
19820        int numEmpty = 0;
19821        int numTrimming = 0;
19822
19823        mNumNonCachedProcs = 0;
19824        mNumCachedHiddenProcs = 0;
19825
19826        // First update the OOM adjustment for each of the
19827        // application processes based on their current state.
19828        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19829        int nextCachedAdj = curCachedAdj+1;
19830        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19831        int nextEmptyAdj = curEmptyAdj+2;
19832        for (int i=N-1; i>=0; i--) {
19833            ProcessRecord app = mLruProcesses.get(i);
19834            if (!app.killedByAm && app.thread != null) {
19835                app.procStateChanged = false;
19836                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19837
19838                // If we haven't yet assigned the final cached adj
19839                // to the process, do that now.
19840                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19841                    switch (app.curProcState) {
19842                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19843                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19844                            // This process is a cached process holding activities...
19845                            // assign it the next cached value for that type, and then
19846                            // step that cached level.
19847                            app.curRawAdj = curCachedAdj;
19848                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19849                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19850                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19851                                    + ")");
19852                            if (curCachedAdj != nextCachedAdj) {
19853                                stepCached++;
19854                                if (stepCached >= cachedFactor) {
19855                                    stepCached = 0;
19856                                    curCachedAdj = nextCachedAdj;
19857                                    nextCachedAdj += 2;
19858                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19859                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19860                                    }
19861                                }
19862                            }
19863                            break;
19864                        default:
19865                            // For everything else, assign next empty cached process
19866                            // level and bump that up.  Note that this means that
19867                            // long-running services that have dropped down to the
19868                            // cached level will be treated as empty (since their process
19869                            // state is still as a service), which is what we want.
19870                            app.curRawAdj = curEmptyAdj;
19871                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19872                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19873                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19874                                    + ")");
19875                            if (curEmptyAdj != nextEmptyAdj) {
19876                                stepEmpty++;
19877                                if (stepEmpty >= emptyFactor) {
19878                                    stepEmpty = 0;
19879                                    curEmptyAdj = nextEmptyAdj;
19880                                    nextEmptyAdj += 2;
19881                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19882                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19883                                    }
19884                                }
19885                            }
19886                            break;
19887                    }
19888                }
19889
19890                applyOomAdjLocked(app, true, now, nowElapsed);
19891
19892                // Count the number of process types.
19893                switch (app.curProcState) {
19894                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19895                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19896                        mNumCachedHiddenProcs++;
19897                        numCached++;
19898                        if (numCached > cachedProcessLimit) {
19899                            app.kill("cached #" + numCached, true);
19900                        }
19901                        break;
19902                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19903                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19904                                && app.lastActivityTime < oldTime) {
19905                            app.kill("empty for "
19906                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19907                                    / 1000) + "s", true);
19908                        } else {
19909                            numEmpty++;
19910                            if (numEmpty > emptyProcessLimit) {
19911                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19912                            }
19913                        }
19914                        break;
19915                    default:
19916                        mNumNonCachedProcs++;
19917                        break;
19918                }
19919
19920                if (app.isolated && app.services.size() <= 0) {
19921                    // If this is an isolated process, and there are no
19922                    // services running in it, then the process is no longer
19923                    // needed.  We agressively kill these because we can by
19924                    // definition not re-use the same process again, and it is
19925                    // good to avoid having whatever code was running in them
19926                    // left sitting around after no longer needed.
19927                    app.kill("isolated not needed", true);
19928                } else {
19929                    // Keeping this process, update its uid.
19930                    final UidRecord uidRec = app.uidRecord;
19931                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19932                        uidRec.curProcState = app.curProcState;
19933                    }
19934                }
19935
19936                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19937                        && !app.killedByAm) {
19938                    numTrimming++;
19939                }
19940            }
19941        }
19942
19943        mNumServiceProcs = mNewNumServiceProcs;
19944
19945        // Now determine the memory trimming level of background processes.
19946        // Unfortunately we need to start at the back of the list to do this
19947        // properly.  We only do this if the number of background apps we
19948        // are managing to keep around is less than half the maximum we desire;
19949        // if we are keeping a good number around, we'll let them use whatever
19950        // memory they want.
19951        final int numCachedAndEmpty = numCached + numEmpty;
19952        int memFactor;
19953        if (numCached <= ProcessList.TRIM_CACHED_APPS
19954                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19955            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19956                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19957            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19958                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19959            } else {
19960                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19961            }
19962        } else {
19963            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19964        }
19965        // We always allow the memory level to go up (better).  We only allow it to go
19966        // down if we are in a state where that is allowed, *and* the total number of processes
19967        // has gone down since last time.
19968        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19969                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19970                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19971        if (memFactor > mLastMemoryLevel) {
19972            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19973                memFactor = mLastMemoryLevel;
19974                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19975            }
19976        }
19977        mLastMemoryLevel = memFactor;
19978        mLastNumProcesses = mLruProcesses.size();
19979        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19980        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19981        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19982            if (mLowRamStartTime == 0) {
19983                mLowRamStartTime = now;
19984            }
19985            int step = 0;
19986            int fgTrimLevel;
19987            switch (memFactor) {
19988                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19989                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19990                    break;
19991                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19992                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19993                    break;
19994                default:
19995                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19996                    break;
19997            }
19998            int factor = numTrimming/3;
19999            int minFactor = 2;
20000            if (mHomeProcess != null) minFactor++;
20001            if (mPreviousProcess != null) minFactor++;
20002            if (factor < minFactor) factor = minFactor;
20003            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20004            for (int i=N-1; i>=0; i--) {
20005                ProcessRecord app = mLruProcesses.get(i);
20006                if (allChanged || app.procStateChanged) {
20007                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20008                    app.procStateChanged = false;
20009                }
20010                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20011                        && !app.killedByAm) {
20012                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20013                        try {
20014                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20015                                    "Trimming memory of " + app.processName + " to " + curLevel);
20016                            app.thread.scheduleTrimMemory(curLevel);
20017                        } catch (RemoteException e) {
20018                        }
20019                        if (false) {
20020                            // For now we won't do this; our memory trimming seems
20021                            // to be good enough at this point that destroying
20022                            // activities causes more harm than good.
20023                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20024                                    && app != mHomeProcess && app != mPreviousProcess) {
20025                                // Need to do this on its own message because the stack may not
20026                                // be in a consistent state at this point.
20027                                // For these apps we will also finish their activities
20028                                // to help them free memory.
20029                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20030                            }
20031                        }
20032                    }
20033                    app.trimMemoryLevel = curLevel;
20034                    step++;
20035                    if (step >= factor) {
20036                        step = 0;
20037                        switch (curLevel) {
20038                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20039                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20040                                break;
20041                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20042                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20043                                break;
20044                        }
20045                    }
20046                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20047                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20048                            && app.thread != null) {
20049                        try {
20050                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20051                                    "Trimming memory of heavy-weight " + app.processName
20052                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20053                            app.thread.scheduleTrimMemory(
20054                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20055                        } catch (RemoteException e) {
20056                        }
20057                    }
20058                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20059                } else {
20060                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20061                            || app.systemNoUi) && app.pendingUiClean) {
20062                        // If this application is now in the background and it
20063                        // had done UI, then give it the special trim level to
20064                        // have it free UI resources.
20065                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20066                        if (app.trimMemoryLevel < level && app.thread != null) {
20067                            try {
20068                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20069                                        "Trimming memory of bg-ui " + app.processName
20070                                        + " to " + level);
20071                                app.thread.scheduleTrimMemory(level);
20072                            } catch (RemoteException e) {
20073                            }
20074                        }
20075                        app.pendingUiClean = false;
20076                    }
20077                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20078                        try {
20079                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20080                                    "Trimming memory of fg " + app.processName
20081                                    + " to " + fgTrimLevel);
20082                            app.thread.scheduleTrimMemory(fgTrimLevel);
20083                        } catch (RemoteException e) {
20084                        }
20085                    }
20086                    app.trimMemoryLevel = fgTrimLevel;
20087                }
20088            }
20089        } else {
20090            if (mLowRamStartTime != 0) {
20091                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20092                mLowRamStartTime = 0;
20093            }
20094            for (int i=N-1; i>=0; i--) {
20095                ProcessRecord app = mLruProcesses.get(i);
20096                if (allChanged || app.procStateChanged) {
20097                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20098                    app.procStateChanged = false;
20099                }
20100                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20101                        || app.systemNoUi) && app.pendingUiClean) {
20102                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20103                            && app.thread != null) {
20104                        try {
20105                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20106                                    "Trimming memory of ui hidden " + app.processName
20107                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20108                            app.thread.scheduleTrimMemory(
20109                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20110                        } catch (RemoteException e) {
20111                        }
20112                    }
20113                    app.pendingUiClean = false;
20114                }
20115                app.trimMemoryLevel = 0;
20116            }
20117        }
20118
20119        if (mAlwaysFinishActivities) {
20120            // Need to do this on its own message because the stack may not
20121            // be in a consistent state at this point.
20122            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20123        }
20124
20125        if (allChanged) {
20126            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20127        }
20128
20129        // Update from any uid changes.
20130        for (int i=mActiveUids.size()-1; i>=0; i--) {
20131            final UidRecord uidRec = mActiveUids.valueAt(i);
20132            int uidChange = UidRecord.CHANGE_PROCSTATE;
20133            if (uidRec.setProcState != uidRec.curProcState) {
20134                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20135                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20136                        + " to " + uidRec.curProcState);
20137                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20138                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20139                        uidRec.lastBackgroundTime = nowElapsed;
20140                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20141                            // Note: the background settle time is in elapsed realtime, while
20142                            // the handler time base is uptime.  All this means is that we may
20143                            // stop background uids later than we had intended, but that only
20144                            // happens because the device was sleeping so we are okay anyway.
20145                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20146                        }
20147                    }
20148                } else {
20149                    if (uidRec.idle) {
20150                        uidChange = UidRecord.CHANGE_ACTIVE;
20151                        uidRec.idle = false;
20152                    }
20153                    uidRec.lastBackgroundTime = 0;
20154                }
20155                uidRec.setProcState = uidRec.curProcState;
20156                enqueueUidChangeLocked(uidRec, -1, uidChange);
20157                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20158            }
20159        }
20160
20161        if (mProcessStats.shouldWriteNowLocked(now)) {
20162            mHandler.post(new Runnable() {
20163                @Override public void run() {
20164                    synchronized (ActivityManagerService.this) {
20165                        mProcessStats.writeStateAsyncLocked();
20166                    }
20167                }
20168            });
20169        }
20170
20171        if (DEBUG_OOM_ADJ) {
20172            final long duration = SystemClock.uptimeMillis() - now;
20173            if (false) {
20174                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20175                        new RuntimeException("here").fillInStackTrace());
20176            } else {
20177                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20178            }
20179        }
20180    }
20181
20182    final void idleUids() {
20183        synchronized (this) {
20184            final long nowElapsed = SystemClock.elapsedRealtime();
20185            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20186            long nextTime = 0;
20187            for (int i=mActiveUids.size()-1; i>=0; i--) {
20188                final UidRecord uidRec = mActiveUids.valueAt(i);
20189                final long bgTime = uidRec.lastBackgroundTime;
20190                if (bgTime > 0 && !uidRec.idle) {
20191                    if (bgTime <= maxBgTime) {
20192                        uidRec.idle = true;
20193                        doStopUidLocked(uidRec.uid, uidRec);
20194                    } else {
20195                        if (nextTime == 0 || nextTime > bgTime) {
20196                            nextTime = bgTime;
20197                        }
20198                    }
20199                }
20200            }
20201            if (nextTime > 0) {
20202                mHandler.removeMessages(IDLE_UIDS_MSG);
20203                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20204                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20205            }
20206        }
20207    }
20208
20209    final void runInBackgroundDisabled(int uid) {
20210        synchronized (this) {
20211            UidRecord uidRec = mActiveUids.get(uid);
20212            if (uidRec != null) {
20213                // This uid is actually running...  should it be considered background now?
20214                if (uidRec.idle) {
20215                    doStopUidLocked(uidRec.uid, uidRec);
20216                }
20217            } else {
20218                // This uid isn't actually running...  still send a report about it being "stopped".
20219                doStopUidLocked(uid, null);
20220            }
20221        }
20222    }
20223
20224    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20225        mServices.stopInBackgroundLocked(uid);
20226        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20227    }
20228
20229    final void trimApplications() {
20230        synchronized (this) {
20231            int i;
20232
20233            // First remove any unused application processes whose package
20234            // has been removed.
20235            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20236                final ProcessRecord app = mRemovedProcesses.get(i);
20237                if (app.activities.size() == 0
20238                        && app.curReceiver == null && app.services.size() == 0) {
20239                    Slog.i(
20240                        TAG, "Exiting empty application process "
20241                        + app.processName + " ("
20242                        + (app.thread != null ? app.thread.asBinder() : null)
20243                        + ")\n");
20244                    if (app.pid > 0 && app.pid != MY_PID) {
20245                        app.kill("empty", false);
20246                    } else {
20247                        try {
20248                            app.thread.scheduleExit();
20249                        } catch (Exception e) {
20250                            // Ignore exceptions.
20251                        }
20252                    }
20253                    cleanUpApplicationRecordLocked(app, false, true, -1);
20254                    mRemovedProcesses.remove(i);
20255
20256                    if (app.persistent) {
20257                        addAppLocked(app.info, false, null /* ABI override */);
20258                    }
20259                }
20260            }
20261
20262            // Now update the oom adj for all processes.
20263            updateOomAdjLocked();
20264        }
20265    }
20266
20267    /** This method sends the specified signal to each of the persistent apps */
20268    public void signalPersistentProcesses(int sig) throws RemoteException {
20269        if (sig != Process.SIGNAL_USR1) {
20270            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20271        }
20272
20273        synchronized (this) {
20274            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20275                    != PackageManager.PERMISSION_GRANTED) {
20276                throw new SecurityException("Requires permission "
20277                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20278            }
20279
20280            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20281                ProcessRecord r = mLruProcesses.get(i);
20282                if (r.thread != null && r.persistent) {
20283                    Process.sendSignal(r.pid, sig);
20284                }
20285            }
20286        }
20287    }
20288
20289    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20290        if (proc == null || proc == mProfileProc) {
20291            proc = mProfileProc;
20292            profileType = mProfileType;
20293            clearProfilerLocked();
20294        }
20295        if (proc == null) {
20296            return;
20297        }
20298        try {
20299            proc.thread.profilerControl(false, null, profileType);
20300        } catch (RemoteException e) {
20301            throw new IllegalStateException("Process disappeared");
20302        }
20303    }
20304
20305    private void clearProfilerLocked() {
20306        if (mProfileFd != null) {
20307            try {
20308                mProfileFd.close();
20309            } catch (IOException e) {
20310            }
20311        }
20312        mProfileApp = null;
20313        mProfileProc = null;
20314        mProfileFile = null;
20315        mProfileType = 0;
20316        mAutoStopProfiler = false;
20317        mSamplingInterval = 0;
20318    }
20319
20320    public boolean profileControl(String process, int userId, boolean start,
20321            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20322
20323        try {
20324            synchronized (this) {
20325                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20326                // its own permission.
20327                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20328                        != PackageManager.PERMISSION_GRANTED) {
20329                    throw new SecurityException("Requires permission "
20330                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20331                }
20332
20333                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20334                    throw new IllegalArgumentException("null profile info or fd");
20335                }
20336
20337                ProcessRecord proc = null;
20338                if (process != null) {
20339                    proc = findProcessLocked(process, userId, "profileControl");
20340                }
20341
20342                if (start && (proc == null || proc.thread == null)) {
20343                    throw new IllegalArgumentException("Unknown process: " + process);
20344                }
20345
20346                if (start) {
20347                    stopProfilerLocked(null, 0);
20348                    setProfileApp(proc.info, proc.processName, profilerInfo);
20349                    mProfileProc = proc;
20350                    mProfileType = profileType;
20351                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20352                    try {
20353                        fd = fd.dup();
20354                    } catch (IOException e) {
20355                        fd = null;
20356                    }
20357                    profilerInfo.profileFd = fd;
20358                    proc.thread.profilerControl(start, profilerInfo, profileType);
20359                    fd = null;
20360                    mProfileFd = null;
20361                } else {
20362                    stopProfilerLocked(proc, profileType);
20363                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20364                        try {
20365                            profilerInfo.profileFd.close();
20366                        } catch (IOException e) {
20367                        }
20368                    }
20369                }
20370
20371                return true;
20372            }
20373        } catch (RemoteException e) {
20374            throw new IllegalStateException("Process disappeared");
20375        } finally {
20376            if (profilerInfo != null && profilerInfo.profileFd != null) {
20377                try {
20378                    profilerInfo.profileFd.close();
20379                } catch (IOException e) {
20380                }
20381            }
20382        }
20383    }
20384
20385    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20386        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20387                userId, true, ALLOW_FULL_ONLY, callName, null);
20388        ProcessRecord proc = null;
20389        try {
20390            int pid = Integer.parseInt(process);
20391            synchronized (mPidsSelfLocked) {
20392                proc = mPidsSelfLocked.get(pid);
20393            }
20394        } catch (NumberFormatException e) {
20395        }
20396
20397        if (proc == null) {
20398            ArrayMap<String, SparseArray<ProcessRecord>> all
20399                    = mProcessNames.getMap();
20400            SparseArray<ProcessRecord> procs = all.get(process);
20401            if (procs != null && procs.size() > 0) {
20402                proc = procs.valueAt(0);
20403                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20404                    for (int i=1; i<procs.size(); i++) {
20405                        ProcessRecord thisProc = procs.valueAt(i);
20406                        if (thisProc.userId == userId) {
20407                            proc = thisProc;
20408                            break;
20409                        }
20410                    }
20411                }
20412            }
20413        }
20414
20415        return proc;
20416    }
20417
20418    public boolean dumpHeap(String process, int userId, boolean managed,
20419            String path, ParcelFileDescriptor fd) throws RemoteException {
20420
20421        try {
20422            synchronized (this) {
20423                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20424                // its own permission (same as profileControl).
20425                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20426                        != PackageManager.PERMISSION_GRANTED) {
20427                    throw new SecurityException("Requires permission "
20428                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20429                }
20430
20431                if (fd == null) {
20432                    throw new IllegalArgumentException("null fd");
20433                }
20434
20435                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20436                if (proc == null || proc.thread == null) {
20437                    throw new IllegalArgumentException("Unknown process: " + process);
20438                }
20439
20440                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20441                if (!isDebuggable) {
20442                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20443                        throw new SecurityException("Process not debuggable: " + proc);
20444                    }
20445                }
20446
20447                proc.thread.dumpHeap(managed, path, fd);
20448                fd = null;
20449                return true;
20450            }
20451        } catch (RemoteException e) {
20452            throw new IllegalStateException("Process disappeared");
20453        } finally {
20454            if (fd != null) {
20455                try {
20456                    fd.close();
20457                } catch (IOException e) {
20458                }
20459            }
20460        }
20461    }
20462
20463    @Override
20464    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20465            String reportPackage) {
20466        if (processName != null) {
20467            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20468                    "setDumpHeapDebugLimit()");
20469        } else {
20470            synchronized (mPidsSelfLocked) {
20471                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20472                if (proc == null) {
20473                    throw new SecurityException("No process found for calling pid "
20474                            + Binder.getCallingPid());
20475                }
20476                if (!Build.IS_DEBUGGABLE
20477                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20478                    throw new SecurityException("Not running a debuggable build");
20479                }
20480                processName = proc.processName;
20481                uid = proc.uid;
20482                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20483                    throw new SecurityException("Package " + reportPackage + " is not running in "
20484                            + proc);
20485                }
20486            }
20487        }
20488        synchronized (this) {
20489            if (maxMemSize > 0) {
20490                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20491            } else {
20492                if (uid != 0) {
20493                    mMemWatchProcesses.remove(processName, uid);
20494                } else {
20495                    mMemWatchProcesses.getMap().remove(processName);
20496                }
20497            }
20498        }
20499    }
20500
20501    @Override
20502    public void dumpHeapFinished(String path) {
20503        synchronized (this) {
20504            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20505                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20506                        + " does not match last pid " + mMemWatchDumpPid);
20507                return;
20508            }
20509            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20510                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20511                        + " does not match last path " + mMemWatchDumpFile);
20512                return;
20513            }
20514            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20515            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20516        }
20517    }
20518
20519    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20520    public void monitor() {
20521        synchronized (this) { }
20522    }
20523
20524    void onCoreSettingsChange(Bundle settings) {
20525        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20526            ProcessRecord processRecord = mLruProcesses.get(i);
20527            try {
20528                if (processRecord.thread != null) {
20529                    processRecord.thread.setCoreSettings(settings);
20530                }
20531            } catch (RemoteException re) {
20532                /* ignore */
20533            }
20534        }
20535    }
20536
20537    // Multi-user methods
20538
20539    /**
20540     * Start user, if its not already running, but don't bring it to foreground.
20541     */
20542    @Override
20543    public boolean startUserInBackground(final int userId) {
20544        return mUserController.startUser(userId, /* foreground */ false);
20545    }
20546
20547    @Override
20548    public boolean unlockUser(int userId, byte[] token) {
20549        return mUserController.unlockUser(userId, token);
20550    }
20551
20552    @Override
20553    public boolean switchUser(final int targetUserId) {
20554        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20555        UserInfo currentUserInfo;
20556        UserInfo targetUserInfo;
20557        synchronized (this) {
20558            int currentUserId = mUserController.getCurrentUserIdLocked();
20559            currentUserInfo = mUserController.getUserInfo(currentUserId);
20560            targetUserInfo = mUserController.getUserInfo(targetUserId);
20561            if (targetUserInfo == null) {
20562                Slog.w(TAG, "No user info for user #" + targetUserId);
20563                return false;
20564            }
20565            if (targetUserInfo.isManagedProfile()) {
20566                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20567                return false;
20568            }
20569            mUserController.setTargetUserIdLocked(targetUserId);
20570        }
20571        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20572        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20573        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20574        return true;
20575    }
20576
20577    void scheduleStartProfilesLocked() {
20578        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20579            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20580                    DateUtils.SECOND_IN_MILLIS);
20581        }
20582    }
20583
20584    @Override
20585    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20586        return mUserController.stopUser(userId, force, callback);
20587    }
20588
20589    void onUserRemovedLocked(int userId) {
20590        mRecentTasks.removeTasksForUserLocked(userId);
20591    }
20592
20593    @Override
20594    public UserInfo getCurrentUser() {
20595        return mUserController.getCurrentUser();
20596    }
20597
20598    @Override
20599    public boolean isUserRunning(int userId, int flags) {
20600        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20601                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20602            String msg = "Permission Denial: isUserRunning() from pid="
20603                    + Binder.getCallingPid()
20604                    + ", uid=" + Binder.getCallingUid()
20605                    + " requires " + INTERACT_ACROSS_USERS;
20606            Slog.w(TAG, msg);
20607            throw new SecurityException(msg);
20608        }
20609        synchronized (this) {
20610            return mUserController.isUserRunningLocked(userId, flags);
20611        }
20612    }
20613
20614    @Override
20615    public int[] getRunningUserIds() {
20616        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20617                != PackageManager.PERMISSION_GRANTED) {
20618            String msg = "Permission Denial: isUserRunning() from pid="
20619                    + Binder.getCallingPid()
20620                    + ", uid=" + Binder.getCallingUid()
20621                    + " requires " + INTERACT_ACROSS_USERS;
20622            Slog.w(TAG, msg);
20623            throw new SecurityException(msg);
20624        }
20625        synchronized (this) {
20626            return mUserController.getStartedUserArrayLocked();
20627        }
20628    }
20629
20630    @Override
20631    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20632        mUserController.registerUserSwitchObserver(observer);
20633    }
20634
20635    @Override
20636    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20637        mUserController.unregisterUserSwitchObserver(observer);
20638    }
20639
20640    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20641        if (info == null) return null;
20642        ApplicationInfo newInfo = new ApplicationInfo(info);
20643        newInfo.initForUser(userId);
20644        return newInfo;
20645    }
20646
20647    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20648        if (aInfo == null
20649                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20650            return aInfo;
20651        }
20652
20653        ActivityInfo info = new ActivityInfo(aInfo);
20654        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20655        return info;
20656    }
20657
20658    private boolean processSanityChecksLocked(ProcessRecord process) {
20659        if (process == null || process.thread == null) {
20660            return false;
20661        }
20662
20663        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20664        if (!isDebuggable) {
20665            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20666                return false;
20667            }
20668        }
20669
20670        return true;
20671    }
20672
20673    public boolean startBinderTracking() throws RemoteException {
20674        synchronized (this) {
20675            mBinderTransactionTrackingEnabled = true;
20676            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20677            // permission (same as profileControl).
20678            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20679                    != PackageManager.PERMISSION_GRANTED) {
20680                throw new SecurityException("Requires permission "
20681                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20682            }
20683
20684            for (int i = 0; i < mLruProcesses.size(); i++) {
20685                ProcessRecord process = mLruProcesses.get(i);
20686                if (!processSanityChecksLocked(process)) {
20687                    continue;
20688                }
20689                try {
20690                    process.thread.startBinderTracking();
20691                } catch (RemoteException e) {
20692                    Log.v(TAG, "Process disappared");
20693                }
20694            }
20695            return true;
20696        }
20697    }
20698
20699    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20700        try {
20701            synchronized (this) {
20702                mBinderTransactionTrackingEnabled = false;
20703                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20704                // permission (same as profileControl).
20705                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20706                        != PackageManager.PERMISSION_GRANTED) {
20707                    throw new SecurityException("Requires permission "
20708                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20709                }
20710
20711                if (fd == null) {
20712                    throw new IllegalArgumentException("null fd");
20713                }
20714
20715                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20716                pw.println("Binder transaction traces for all processes.\n");
20717                for (ProcessRecord process : mLruProcesses) {
20718                    if (!processSanityChecksLocked(process)) {
20719                        continue;
20720                    }
20721
20722                    pw.println("Traces for process: " + process.processName);
20723                    pw.flush();
20724                    try {
20725                        TransferPipe tp = new TransferPipe();
20726                        try {
20727                            process.thread.stopBinderTrackingAndDump(
20728                                    tp.getWriteFd().getFileDescriptor());
20729                            tp.go(fd.getFileDescriptor());
20730                        } finally {
20731                            tp.kill();
20732                        }
20733                    } catch (IOException e) {
20734                        pw.println("Failure while dumping IPC traces from " + process +
20735                                ".  Exception: " + e);
20736                        pw.flush();
20737                    } catch (RemoteException e) {
20738                        pw.println("Got a RemoteException while dumping IPC traces from " +
20739                                process + ".  Exception: " + e);
20740                        pw.flush();
20741                    }
20742                }
20743                fd = null;
20744                return true;
20745            }
20746        } finally {
20747            if (fd != null) {
20748                try {
20749                    fd.close();
20750                } catch (IOException e) {
20751                }
20752            }
20753        }
20754    }
20755
20756    void stopReportingCrashesLocked(ProcessRecord proc) {
20757        if (mAppsNotReportingCrashes == null) {
20758            mAppsNotReportingCrashes = new ArraySet<>();
20759        }
20760        mAppsNotReportingCrashes.add(proc.info.packageName);
20761    }
20762
20763    private final class LocalService extends ActivityManagerInternal {
20764        @Override
20765        public void onWakefulnessChanged(int wakefulness) {
20766            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20767        }
20768
20769        @Override
20770        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20771                String processName, String abiOverride, int uid, Runnable crashHandler) {
20772            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20773                    processName, abiOverride, uid, crashHandler);
20774        }
20775
20776        @Override
20777        public SleepToken acquireSleepToken(String tag) {
20778            Preconditions.checkNotNull(tag);
20779
20780            synchronized (ActivityManagerService.this) {
20781                SleepTokenImpl token = new SleepTokenImpl(tag);
20782                mSleepTokens.add(token);
20783                updateSleepIfNeededLocked();
20784                return token;
20785            }
20786        }
20787
20788        @Override
20789        public ComponentName getHomeActivityForUser(int userId) {
20790            synchronized (ActivityManagerService.this) {
20791                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20792                return homeActivity == null ? null : homeActivity.realActivity;
20793            }
20794        }
20795
20796        @Override
20797        public void onUserRemoved(int userId) {
20798            synchronized (ActivityManagerService.this) {
20799                ActivityManagerService.this.onUserRemovedLocked(userId);
20800            }
20801        }
20802    }
20803
20804    private final class SleepTokenImpl extends SleepToken {
20805        private final String mTag;
20806        private final long mAcquireTime;
20807
20808        public SleepTokenImpl(String tag) {
20809            mTag = tag;
20810            mAcquireTime = SystemClock.uptimeMillis();
20811        }
20812
20813        @Override
20814        public void release() {
20815            synchronized (ActivityManagerService.this) {
20816                if (mSleepTokens.remove(this)) {
20817                    updateSleepIfNeededLocked();
20818                }
20819            }
20820        }
20821
20822        @Override
20823        public String toString() {
20824            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20825        }
20826    }
20827
20828    /**
20829     * An implementation of IAppTask, that allows an app to manage its own tasks via
20830     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20831     * only the process that calls getAppTasks() can call the AppTask methods.
20832     */
20833    class AppTaskImpl extends IAppTask.Stub {
20834        private int mTaskId;
20835        private int mCallingUid;
20836
20837        public AppTaskImpl(int taskId, int callingUid) {
20838            mTaskId = taskId;
20839            mCallingUid = callingUid;
20840        }
20841
20842        private void checkCaller() {
20843            if (mCallingUid != Binder.getCallingUid()) {
20844                throw new SecurityException("Caller " + mCallingUid
20845                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20846            }
20847        }
20848
20849        @Override
20850        public void finishAndRemoveTask() {
20851            checkCaller();
20852
20853            synchronized (ActivityManagerService.this) {
20854                long origId = Binder.clearCallingIdentity();
20855                try {
20856                    // We remove the task from recents to preserve backwards
20857                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20858                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20859                    }
20860                } finally {
20861                    Binder.restoreCallingIdentity(origId);
20862                }
20863            }
20864        }
20865
20866        @Override
20867        public ActivityManager.RecentTaskInfo getTaskInfo() {
20868            checkCaller();
20869
20870            synchronized (ActivityManagerService.this) {
20871                long origId = Binder.clearCallingIdentity();
20872                try {
20873                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20874                    if (tr == null) {
20875                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20876                    }
20877                    return createRecentTaskInfoFromTaskRecord(tr);
20878                } finally {
20879                    Binder.restoreCallingIdentity(origId);
20880                }
20881            }
20882        }
20883
20884        @Override
20885        public void moveToFront() {
20886            checkCaller();
20887            // Will bring task to front if it already has a root activity.
20888            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20889        }
20890
20891        @Override
20892        public int startActivity(IBinder whoThread, String callingPackage,
20893                Intent intent, String resolvedType, Bundle bOptions) {
20894            checkCaller();
20895
20896            int callingUser = UserHandle.getCallingUserId();
20897            TaskRecord tr;
20898            IApplicationThread appThread;
20899            synchronized (ActivityManagerService.this) {
20900                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20901                if (tr == null) {
20902                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20903                }
20904                appThread = ApplicationThreadNative.asInterface(whoThread);
20905                if (appThread == null) {
20906                    throw new IllegalArgumentException("Bad app thread " + appThread);
20907                }
20908            }
20909            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20910                    resolvedType, null, null, null, null, 0, 0, null, null,
20911                    null, bOptions, false, callingUser, null, tr);
20912        }
20913
20914        @Override
20915        public void setExcludeFromRecents(boolean exclude) {
20916            checkCaller();
20917
20918            synchronized (ActivityManagerService.this) {
20919                long origId = Binder.clearCallingIdentity();
20920                try {
20921                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20922                    if (tr == null) {
20923                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20924                    }
20925                    Intent intent = tr.getBaseIntent();
20926                    if (exclude) {
20927                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20928                    } else {
20929                        intent.setFlags(intent.getFlags()
20930                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20931                    }
20932                } finally {
20933                    Binder.restoreCallingIdentity(origId);
20934                }
20935            }
20936        }
20937    }
20938
20939    /**
20940     * Kill processes for the user with id userId and that depend on the package named packageName
20941     */
20942    @Override
20943    public void killPackageDependents(String packageName, int userId) {
20944        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20945        if (packageName == null) {
20946            throw new NullPointerException("Cannot kill the dependents of a package without its name.");
20947        }
20948
20949        long callingId = Binder.clearCallingIdentity();
20950        IPackageManager pm = AppGlobals.getPackageManager();
20951        int pkgUid = -1;
20952        try {
20953            pkgUid = pm.getPackageUid(packageName, userId);
20954        } catch (RemoteException e) {
20955        }
20956        if (pkgUid == -1) {
20957            throw new IllegalArgumentException("Cannot kill dependents of non-existing package " + packageName);
20958        }
20959        try {
20960            synchronized(this) {
20961                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20962                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, false,
20963                        "dep: " + packageName);
20964            }
20965        } finally {
20966            Binder.restoreCallingIdentity(callingId);
20967        }
20968    }
20969}
20970