ActivityManagerService.java revision 935dafbf0d69e183cfdbd5f24e53ee925bd072f5
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;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
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.database.ContentObserver;
145import android.graphics.Bitmap;
146import android.graphics.Point;
147import android.graphics.Rect;
148import android.location.LocationManager;
149import android.net.Proxy;
150import android.net.ProxyInfo;
151import android.net.Uri;
152import android.os.BatteryStats;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IProcessInfoService;
166import android.os.Looper;
167import android.os.Message;
168import android.os.Parcel;
169import android.os.ParcelFileDescriptor;
170import android.os.PersistableBundle;
171import android.os.PowerManager;
172import android.os.PowerManagerInternal;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.ResultReceiver;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.Trace;
182import android.os.TransactionTooLargeException;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.os.WorkSource;
187import android.os.storage.IMountService;
188import android.os.storage.MountServiceInternal;
189import android.os.storage.StorageManager;
190import android.provider.Settings;
191import android.service.voice.IVoiceInteractionSession;
192import android.service.voice.VoiceInteractionManagerInternal;
193import android.service.voice.VoiceInteractionSession;
194import android.text.format.DateUtils;
195import android.text.format.Time;
196import android.util.ArrayMap;
197import android.util.ArraySet;
198import android.util.AtomicFile;
199import android.util.DebugUtils;
200import android.util.EventLog;
201import android.util.LocaleList;
202import android.util.Log;
203import android.util.Pair;
204import android.util.PrintWriterPrinter;
205import android.util.Slog;
206import android.util.SparseArray;
207import android.util.TimeUtils;
208import android.util.Xml;
209import android.view.Display;
210import android.view.Gravity;
211import android.view.LayoutInflater;
212import android.view.View;
213import android.view.WindowManager;
214
215import java.io.BufferedInputStream;
216import java.io.BufferedOutputStream;
217import java.io.DataInputStream;
218import java.io.DataOutputStream;
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
277import static android.provider.Settings.System.FONT_SCALE;
278import static com.android.internal.util.XmlUtils.readBooleanAttribute;
279import static com.android.internal.util.XmlUtils.readIntAttribute;
280import static com.android.internal.util.XmlUtils.readLongAttribute;
281import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
282import static com.android.internal.util.XmlUtils.writeIntAttribute;
283import static com.android.internal.util.XmlUtils.writeLongAttribute;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
339import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
340import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
341import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
342import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
343import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
344import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
345import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
346import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
347import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
348import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
350import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
351import static org.xmlpull.v1.XmlPullParser.START_TAG;
352
353public final class ActivityManagerService extends ActivityManagerNative
354        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
355
356    // File that stores last updated system version and called preboot receivers
357    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
358
359    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
360    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
361    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
362    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
363    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
364    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
365    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
366    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
367    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
368    private static final String TAG_LRU = TAG + POSTFIX_LRU;
369    private static final String TAG_MU = TAG + POSTFIX_MU;
370    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
371    private static final String TAG_POWER = TAG + POSTFIX_POWER;
372    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
373    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
374    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
375    private static final String TAG_PSS = TAG + POSTFIX_PSS;
376    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
377    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
378    private static final String TAG_STACK = TAG + POSTFIX_STACK;
379    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
380    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
381    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
382    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
383    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
384
385    /** Control over CPU and battery monitoring */
386    // write battery stats every 30 minutes.
387    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
388    static final boolean MONITOR_CPU_USAGE = true;
389    // don't sample cpu less than every 5 seconds.
390    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
391    // wait possibly forever for next cpu sample.
392    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
393    static final boolean MONITOR_THREAD_CPU_USAGE = false;
394
395    // The flags that are set for all calls we make to the package manager.
396    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
397
398    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
399
400    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
401
402    // Amount of time after a call to stopAppSwitches() during which we will
403    // prevent further untrusted switches from happening.
404    static final long APP_SWITCH_DELAY_TIME = 5*1000;
405
406    // How long we wait for a launched process to attach to the activity manager
407    // before we decide it's never going to come up for real.
408    static final int PROC_START_TIMEOUT = 10*1000;
409    // How long we wait for an attached process to publish its content providers
410    // before we decide it must be hung.
411    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
412
413    // How long we will retain processes hosting content providers in the "last activity"
414    // state before allowing them to drop down to the regular cached LRU list.  This is
415    // to avoid thrashing of provider processes under low memory situations.
416    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
417
418    // How long we wait for a launched process to attach to the activity manager
419    // before we decide it's never going to come up for real, when the process was
420    // started with a wrapper for instrumentation (such as Valgrind) because it
421    // could take much longer than usual.
422    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
423
424    // How long to wait after going idle before forcing apps to GC.
425    static final int GC_TIMEOUT = 5*1000;
426
427    // The minimum amount of time between successive GC requests for a process.
428    static final int GC_MIN_INTERVAL = 60*1000;
429
430    // The minimum amount of time between successive PSS requests for a process.
431    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
432
433    // The minimum amount of time between successive PSS requests for a process
434    // when the request is due to the memory state being lowered.
435    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
436
437    // The rate at which we check for apps using excessive power -- 15 mins.
438    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
439
440    // The minimum sample duration we will allow before deciding we have
441    // enough data on wake locks to start killing things.
442    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
443
444    // The minimum sample duration we will allow before deciding we have
445    // enough data on CPU usage to start killing things.
446    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
447
448    // How long we allow a receiver to run before giving up on it.
449    static final int BROADCAST_FG_TIMEOUT = 10*1000;
450    static final int BROADCAST_BG_TIMEOUT = 60*1000;
451
452    // How long we wait until we timeout on key dispatching.
453    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
454
455    // How long we wait until we timeout on key dispatching during instrumentation.
456    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
457
458    // This is the amount of time an app needs to be running a foreground service before
459    // we will consider it to be doing interaction for usage stats.
460    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
461
462    // Maximum amount of time we will allow to elapse before re-reporting usage stats
463    // interaction with foreground processes.
464    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
465
466    // This is the amount of time we allow an app to settle after it goes into the background,
467    // before we start restricting what it can do.
468    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
469
470    // How long to wait in getAssistContextExtras for the activity and foreground services
471    // to respond with the result.
472    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
473
474    // How long top wait when going through the modern assist (which doesn't need to block
475    // on getting this result before starting to launch its UI).
476    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
477
478    // Maximum number of persisted Uri grants a package is allowed
479    static final int MAX_PERSISTED_URI_GRANTS = 128;
480
481    static final int MY_PID = Process.myPid();
482
483    static final String[] EMPTY_STRING_ARRAY = new String[0];
484
485    // How many bytes to write into the dropbox log before truncating
486    static final int DROPBOX_MAX_SIZE = 256 * 1024;
487
488    // Access modes for handleIncomingUser.
489    static final int ALLOW_NON_FULL = 0;
490    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
491    static final int ALLOW_FULL_ONLY = 2;
492
493    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
494
495    // Delay in notifying task stack change listeners (in millis)
496    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
497
498    // Necessary ApplicationInfo flags to mark an app as persistent
499    private static final int PERSISTENT_MASK =
500            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
501
502    // Intent sent when remote bugreport collection has been completed
503    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
504            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
505
506    // Delay to disable app launch boost
507    static final int APP_BOOST_MESSAGE_DELAY = 3000;
508    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
509    static final int APP_BOOST_TIMEOUT = 2500;
510
511    // Used to indicate that a task is removed it should also be removed from recents.
512    private static final boolean REMOVE_FROM_RECENTS = true;
513    // Used to indicate that an app transition should be animated.
514    static final boolean ANIMATE = true;
515
516    // Determines whether to take full screen screenshots
517    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
518
519    private static native int nativeMigrateToBoost();
520    private static native int nativeMigrateFromBoost();
521    private boolean mIsBoosted = false;
522    private long mBoostStartTime = 0;
523
524    /** All system services */
525    SystemServiceManager mSystemServiceManager;
526
527    private Installer mInstaller;
528
529    /** Run all ActivityStacks through this */
530    final ActivityStackSupervisor mStackSupervisor;
531
532    final ActivityStarter mActivityStarter;
533
534    /** Task stack change listeners. */
535    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
536            new RemoteCallbackList<ITaskStackListener>();
537
538    public IntentFirewall mIntentFirewall;
539
540    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
541    // default actuion automatically.  Important for devices without direct input
542    // devices.
543    private boolean mShowDialogs = true;
544    private boolean mInVrMode = false;
545
546    BroadcastQueue mFgBroadcastQueue;
547    BroadcastQueue mBgBroadcastQueue;
548    // Convenient for easy iteration over the queues. Foreground is first
549    // so that dispatch of foreground broadcasts gets precedence.
550    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
551
552    BroadcastQueue broadcastQueueForIntent(Intent intent) {
553        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
554        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
555                "Broadcast intent " + intent + " on "
556                + (isFg ? "foreground" : "background") + " queue");
557        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
558    }
559
560    /**
561     * Activity we have told the window manager to have key focus.
562     */
563    ActivityRecord mFocusedActivity = null;
564
565    /**
566     * User id of the last activity mFocusedActivity was set to.
567     */
568    private int mLastFocusedUserId;
569
570    /**
571     * If non-null, we are tracking the time the user spends in the currently focused app.
572     */
573    private AppTimeTracker mCurAppTimeTracker;
574
575    /**
576     * List of intents that were used to start the most recent tasks.
577     */
578    final RecentTasks mRecentTasks;
579
580    /**
581     * For addAppTask: cached of the last activity component that was added.
582     */
583    ComponentName mLastAddedTaskComponent;
584
585    /**
586     * For addAppTask: cached of the last activity uid that was added.
587     */
588    int mLastAddedTaskUid;
589
590    /**
591     * For addAppTask: cached of the last ActivityInfo that was added.
592     */
593    ActivityInfo mLastAddedTaskActivity;
594
595    /**
596     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
597     */
598    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
599
600    /**
601     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
602     */
603    String mDeviceOwnerName;
604
605    final UserController mUserController;
606
607    final AppErrors mAppErrors;
608
609    boolean mDoingSetFocusedActivity;
610
611    public boolean canShowErrorDialogs() {
612        return mShowDialogs && !mSleeping && !mShuttingDown;
613    }
614
615    public class PendingAssistExtras extends Binder implements Runnable {
616        public final ActivityRecord activity;
617        public final Bundle extras;
618        public final Intent intent;
619        public final String hint;
620        public final IResultReceiver receiver;
621        public final int userHandle;
622        public boolean haveResult = false;
623        public Bundle result = null;
624        public AssistStructure structure = null;
625        public AssistContent content = null;
626        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
627                String _hint, IResultReceiver _receiver, int _userHandle) {
628            activity = _activity;
629            extras = _extras;
630            intent = _intent;
631            hint = _hint;
632            receiver = _receiver;
633            userHandle = _userHandle;
634        }
635        @Override
636        public void run() {
637            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
638            synchronized (this) {
639                haveResult = true;
640                notifyAll();
641            }
642            pendingAssistExtrasTimedOut(this);
643        }
644    }
645
646    final ArrayList<PendingAssistExtras> mPendingAssistExtras
647            = new ArrayList<PendingAssistExtras>();
648
649    /**
650     * Process management.
651     */
652    final ProcessList mProcessList = new ProcessList();
653
654    /**
655     * All of the applications we currently have running organized by name.
656     * The keys are strings of the application package name (as
657     * returned by the package manager), and the keys are ApplicationRecord
658     * objects.
659     */
660    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
661
662    /**
663     * Tracking long-term execution of processes to look for abuse and other
664     * bad app behavior.
665     */
666    final ProcessStatsService mProcessStats;
667
668    /**
669     * The currently running isolated processes.
670     */
671    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
672
673    /**
674     * Counter for assigning isolated process uids, to avoid frequently reusing the
675     * same ones.
676     */
677    int mNextIsolatedProcessUid = 0;
678
679    /**
680     * The currently running heavy-weight process, if any.
681     */
682    ProcessRecord mHeavyWeightProcess = null;
683
684    /**
685     * All of the processes we currently have running organized by pid.
686     * The keys are the pid running the application.
687     *
688     * <p>NOTE: This object is protected by its own lock, NOT the global
689     * activity manager lock!
690     */
691    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
692
693    /**
694     * All of the processes that have been forced to be foreground.  The key
695     * is the pid of the caller who requested it (we hold a death
696     * link on it).
697     */
698    abstract class ForegroundToken implements IBinder.DeathRecipient {
699        int pid;
700        IBinder token;
701    }
702    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
703
704    /**
705     * List of records for processes that someone had tried to start before the
706     * system was ready.  We don't start them at that point, but ensure they
707     * are started by the time booting is complete.
708     */
709    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
710
711    /**
712     * List of persistent applications that are in the process
713     * of being started.
714     */
715    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
716
717    /**
718     * Processes that are being forcibly torn down.
719     */
720    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
721
722    /**
723     * List of running applications, sorted by recent usage.
724     * The first entry in the list is the least recently used.
725     */
726    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * Where in mLruProcesses that the processes hosting activities start.
730     */
731    int mLruProcessActivityStart = 0;
732
733    /**
734     * Where in mLruProcesses that the processes hosting services start.
735     * This is after (lower index) than mLruProcessesActivityStart.
736     */
737    int mLruProcessServiceStart = 0;
738
739    /**
740     * List of processes that should gc as soon as things are idle.
741     */
742    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
743
744    /**
745     * Processes we want to collect PSS data from.
746     */
747    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
748
749    private boolean mBinderTransactionTrackingEnabled = false;
750
751    /**
752     * Last time we requested PSS data of all processes.
753     */
754    long mLastFullPssTime = SystemClock.uptimeMillis();
755
756    /**
757     * If set, the next time we collect PSS data we should do a full collection
758     * with data from native processes and the kernel.
759     */
760    boolean mFullPssPending = false;
761
762    /**
763     * This is the process holding what we currently consider to be
764     * the "home" activity.
765     */
766    ProcessRecord mHomeProcess;
767
768    /**
769     * This is the process holding the activity the user last visited that
770     * is in a different process from the one they are currently in.
771     */
772    ProcessRecord mPreviousProcess;
773
774    /**
775     * The time at which the previous process was last visible.
776     */
777    long mPreviousProcessVisibleTime;
778
779    /**
780     * Track all uids that have actively running processes.
781     */
782    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
783
784    /**
785     * This is for verifying the UID report flow.
786     */
787    static final boolean VALIDATE_UID_STATES = true;
788    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
789
790    /**
791     * Packages that the user has asked to have run in screen size
792     * compatibility mode instead of filling the screen.
793     */
794    final CompatModePackages mCompatModePackages;
795
796    /**
797     * Set of IntentSenderRecord objects that are currently active.
798     */
799    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
800            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
801
802    /**
803     * Fingerprints (hashCode()) of stack traces that we've
804     * already logged DropBox entries for.  Guarded by itself.  If
805     * something (rogue user app) forces this over
806     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
807     */
808    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
809    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
810
811    /**
812     * Strict Mode background batched logging state.
813     *
814     * The string buffer is guarded by itself, and its lock is also
815     * used to determine if another batched write is already
816     * in-flight.
817     */
818    private final StringBuilder mStrictModeBuffer = new StringBuilder();
819
820    /**
821     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
822     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
823     */
824    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
825
826    /**
827     * Resolver for broadcast intents to registered receivers.
828     * Holds BroadcastFilter (subclass of IntentFilter).
829     */
830    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
831            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
832        @Override
833        protected boolean allowFilterResult(
834                BroadcastFilter filter, List<BroadcastFilter> dest) {
835            IBinder target = filter.receiverList.receiver.asBinder();
836            for (int i = dest.size() - 1; i >= 0; i--) {
837                if (dest.get(i).receiverList.receiver.asBinder() == target) {
838                    return false;
839                }
840            }
841            return true;
842        }
843
844        @Override
845        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
846            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
847                    || userId == filter.owningUserId) {
848                return super.newResult(filter, match, userId);
849            }
850            return null;
851        }
852
853        @Override
854        protected BroadcastFilter[] newArray(int size) {
855            return new BroadcastFilter[size];
856        }
857
858        @Override
859        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
860            return packageName.equals(filter.packageName);
861        }
862    };
863
864    /**
865     * State of all active sticky broadcasts per user.  Keys are the action of the
866     * sticky Intent, values are an ArrayList of all broadcasted intents with
867     * that action (which should usually be one).  The SparseArray is keyed
868     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
869     * for stickies that are sent to all users.
870     */
871    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
872            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
873
874    final ActiveServices mServices;
875
876    final static class Association {
877        final int mSourceUid;
878        final String mSourceProcess;
879        final int mTargetUid;
880        final ComponentName mTargetComponent;
881        final String mTargetProcess;
882
883        int mCount;
884        long mTime;
885
886        int mNesting;
887        long mStartTime;
888
889        Association(int sourceUid, String sourceProcess, int targetUid,
890                ComponentName targetComponent, String targetProcess) {
891            mSourceUid = sourceUid;
892            mSourceProcess = sourceProcess;
893            mTargetUid = targetUid;
894            mTargetComponent = targetComponent;
895            mTargetProcess = targetProcess;
896        }
897    }
898
899    /**
900     * When service association tracking is enabled, this is all of the associations we
901     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
902     * -> association data.
903     */
904    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
905            mAssociations = new SparseArray<>();
906    boolean mTrackingAssociations;
907
908    /**
909     * Backup/restore process management
910     */
911    String mBackupAppName = null;
912    BackupRecord mBackupTarget = null;
913
914    final ProviderMap mProviderMap;
915
916    /**
917     * List of content providers who have clients waiting for them.  The
918     * application is currently being launched and the provider will be
919     * removed from this list once it is published.
920     */
921    final ArrayList<ContentProviderRecord> mLaunchingProviders
922            = new ArrayList<ContentProviderRecord>();
923
924    /**
925     * File storing persisted {@link #mGrantedUriPermissions}.
926     */
927    private final AtomicFile mGrantFile;
928
929    /** XML constants used in {@link #mGrantFile} */
930    private static final String TAG_URI_GRANTS = "uri-grants";
931    private static final String TAG_URI_GRANT = "uri-grant";
932    private static final String ATTR_USER_HANDLE = "userHandle";
933    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
934    private static final String ATTR_TARGET_USER_ID = "targetUserId";
935    private static final String ATTR_SOURCE_PKG = "sourcePkg";
936    private static final String ATTR_TARGET_PKG = "targetPkg";
937    private static final String ATTR_URI = "uri";
938    private static final String ATTR_MODE_FLAGS = "modeFlags";
939    private static final String ATTR_CREATED_TIME = "createdTime";
940    private static final String ATTR_PREFIX = "prefix";
941
942    /**
943     * Global set of specific {@link Uri} permissions that have been granted.
944     * This optimized lookup structure maps from {@link UriPermission#targetUid}
945     * to {@link UriPermission#uri} to {@link UriPermission}.
946     */
947    @GuardedBy("this")
948    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
949            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
950
951    public static class GrantUri {
952        public final int sourceUserId;
953        public final Uri uri;
954        public boolean prefix;
955
956        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
957            this.sourceUserId = sourceUserId;
958            this.uri = uri;
959            this.prefix = prefix;
960        }
961
962        @Override
963        public int hashCode() {
964            int hashCode = 1;
965            hashCode = 31 * hashCode + sourceUserId;
966            hashCode = 31 * hashCode + uri.hashCode();
967            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
968            return hashCode;
969        }
970
971        @Override
972        public boolean equals(Object o) {
973            if (o instanceof GrantUri) {
974                GrantUri other = (GrantUri) o;
975                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
976                        && prefix == other.prefix;
977            }
978            return false;
979        }
980
981        @Override
982        public String toString() {
983            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
984            if (prefix) result += " [prefix]";
985            return result;
986        }
987
988        public String toSafeString() {
989            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
990            if (prefix) result += " [prefix]";
991            return result;
992        }
993
994        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
995            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
996                    ContentProvider.getUriWithoutUserId(uri), false);
997        }
998    }
999
1000    CoreSettingsObserver mCoreSettingsObserver;
1001
1002    FontScaleSettingObserver mFontScaleSettingObserver;
1003
1004    private final class FontScaleSettingObserver extends ContentObserver {
1005        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1006
1007        public FontScaleSettingObserver() {
1008            super(mHandler);
1009            ContentResolver resolver = mContext.getContentResolver();
1010            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1011        }
1012
1013        @Override
1014        public void onChange(boolean selfChange, Uri uri) {
1015            if (mFontScaleUri.equals(uri)) {
1016                updateFontScaleIfNeeded();
1017            }
1018        }
1019    }
1020
1021    /**
1022     * Thread-local storage used to carry caller permissions over through
1023     * indirect content-provider access.
1024     */
1025    private class Identity {
1026        public final IBinder token;
1027        public final int pid;
1028        public final int uid;
1029
1030        Identity(IBinder _token, int _pid, int _uid) {
1031            token = _token;
1032            pid = _pid;
1033            uid = _uid;
1034        }
1035    }
1036
1037    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1038
1039    /**
1040     * All information we have collected about the runtime performance of
1041     * any user id that can impact battery performance.
1042     */
1043    final BatteryStatsService mBatteryStatsService;
1044
1045    /**
1046     * Information about component usage
1047     */
1048    UsageStatsManagerInternal mUsageStatsService;
1049
1050    /**
1051     * Access to DeviceIdleController service.
1052     */
1053    DeviceIdleController.LocalService mLocalDeviceIdleController;
1054
1055    /**
1056     * Information about and control over application operations
1057     */
1058    final AppOpsService mAppOpsService;
1059
1060    /**
1061     * Current configuration information.  HistoryRecord objects are given
1062     * a reference to this object to indicate which configuration they are
1063     * currently running in, so this object must be kept immutable.
1064     */
1065    Configuration mConfiguration = new Configuration();
1066
1067    /**
1068     * Current sequencing integer of the configuration, for skipping old
1069     * configurations.
1070     */
1071    int mConfigurationSeq = 0;
1072
1073    boolean mSuppressResizeConfigChanges = false;
1074
1075    /**
1076     * Hardware-reported OpenGLES version.
1077     */
1078    final int GL_ES_VERSION;
1079
1080    /**
1081     * List of initialization arguments to pass to all processes when binding applications to them.
1082     * For example, references to the commonly used services.
1083     */
1084    HashMap<String, IBinder> mAppBindArgs;
1085
1086    /**
1087     * Temporary to avoid allocations.  Protected by main lock.
1088     */
1089    final StringBuilder mStringBuilder = new StringBuilder(256);
1090
1091    /**
1092     * Used to control how we initialize the service.
1093     */
1094    ComponentName mTopComponent;
1095    String mTopAction = Intent.ACTION_MAIN;
1096    String mTopData;
1097    boolean mProcessesReady = false;
1098    boolean mSystemReady = false;
1099    boolean mBooting = false;
1100    boolean mCallFinishBooting = false;
1101    boolean mBootAnimationComplete = false;
1102    boolean mWaitingUpdate = false;
1103    boolean mDidUpdate = false;
1104    boolean mOnBattery = false;
1105    boolean mLaunchWarningShown = false;
1106
1107    Context mContext;
1108
1109    int mFactoryTest;
1110
1111    boolean mCheckedForSetup;
1112
1113    /**
1114     * The time at which we will allow normal application switches again,
1115     * after a call to {@link #stopAppSwitches()}.
1116     */
1117    long mAppSwitchesAllowedTime;
1118
1119    /**
1120     * This is set to true after the first switch after mAppSwitchesAllowedTime
1121     * is set; any switches after that will clear the time.
1122     */
1123    boolean mDidAppSwitch;
1124
1125    /**
1126     * Last time (in realtime) at which we checked for power usage.
1127     */
1128    long mLastPowerCheckRealtime;
1129
1130    /**
1131     * Last time (in uptime) at which we checked for power usage.
1132     */
1133    long mLastPowerCheckUptime;
1134
1135    /**
1136     * Set while we are wanting to sleep, to prevent any
1137     * activities from being started/resumed.
1138     */
1139    private boolean mSleeping = false;
1140
1141    /**
1142     * The process state used for processes that are running the top activities.
1143     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1144     */
1145    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1146
1147    /**
1148     * Set while we are running a voice interaction.  This overrides
1149     * sleeping while it is active.
1150     */
1151    private IVoiceInteractionSession mRunningVoice;
1152
1153    /**
1154     * For some direct access we need to power manager.
1155     */
1156    PowerManagerInternal mLocalPowerManager;
1157
1158    /**
1159     * We want to hold a wake lock while running a voice interaction session, since
1160     * this may happen with the screen off and we need to keep the CPU running to
1161     * be able to continue to interact with the user.
1162     */
1163    PowerManager.WakeLock mVoiceWakeLock;
1164
1165    /**
1166     * State of external calls telling us if the device is awake or asleep.
1167     */
1168    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1169
1170    /**
1171     * A list of tokens that cause the top activity to be put to sleep.
1172     * They are used by components that may hide and block interaction with underlying
1173     * activities.
1174     */
1175    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1176
1177    static final int LOCK_SCREEN_HIDDEN = 0;
1178    static final int LOCK_SCREEN_LEAVING = 1;
1179    static final int LOCK_SCREEN_SHOWN = 2;
1180    /**
1181     * State of external call telling us if the lock screen is shown.
1182     */
1183    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1184
1185    /**
1186     * Set if we are shutting down the system, similar to sleeping.
1187     */
1188    boolean mShuttingDown = false;
1189
1190    /**
1191     * Current sequence id for oom_adj computation traversal.
1192     */
1193    int mAdjSeq = 0;
1194
1195    /**
1196     * Current sequence id for process LRU updating.
1197     */
1198    int mLruSeq = 0;
1199
1200    /**
1201     * Keep track of the non-cached/empty process we last found, to help
1202     * determine how to distribute cached/empty processes next time.
1203     */
1204    int mNumNonCachedProcs = 0;
1205
1206    /**
1207     * Keep track of the number of cached hidden procs, to balance oom adj
1208     * distribution between those and empty procs.
1209     */
1210    int mNumCachedHiddenProcs = 0;
1211
1212    /**
1213     * Keep track of the number of service processes we last found, to
1214     * determine on the next iteration which should be B services.
1215     */
1216    int mNumServiceProcs = 0;
1217    int mNewNumAServiceProcs = 0;
1218    int mNewNumServiceProcs = 0;
1219
1220    /**
1221     * Allow the current computed overall memory level of the system to go down?
1222     * This is set to false when we are killing processes for reasons other than
1223     * memory management, so that the now smaller process list will not be taken as
1224     * an indication that memory is tighter.
1225     */
1226    boolean mAllowLowerMemLevel = false;
1227
1228    /**
1229     * The last computed memory level, for holding when we are in a state that
1230     * processes are going away for other reasons.
1231     */
1232    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1233
1234    /**
1235     * The last total number of process we have, to determine if changes actually look
1236     * like a shrinking number of process due to lower RAM.
1237     */
1238    int mLastNumProcesses;
1239
1240    /**
1241     * The uptime of the last time we performed idle maintenance.
1242     */
1243    long mLastIdleTime = SystemClock.uptimeMillis();
1244
1245    /**
1246     * Total time spent with RAM that has been added in the past since the last idle time.
1247     */
1248    long mLowRamTimeSinceLastIdle = 0;
1249
1250    /**
1251     * If RAM is currently low, when that horrible situation started.
1252     */
1253    long mLowRamStartTime = 0;
1254
1255    /**
1256     * For reporting to battery stats the current top application.
1257     */
1258    private String mCurResumedPackage = null;
1259    private int mCurResumedUid = -1;
1260
1261    /**
1262     * For reporting to battery stats the apps currently running foreground
1263     * service.  The ProcessMap is package/uid tuples; each of these contain
1264     * an array of the currently foreground processes.
1265     */
1266    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1267            = new ProcessMap<ArrayList<ProcessRecord>>();
1268
1269    /**
1270     * This is set if we had to do a delayed dexopt of an app before launching
1271     * it, to increase the ANR timeouts in that case.
1272     */
1273    boolean mDidDexOpt;
1274
1275    /**
1276     * Set if the systemServer made a call to enterSafeMode.
1277     */
1278    boolean mSafeMode;
1279
1280    /**
1281     * If true, we are running under a test environment so will sample PSS from processes
1282     * much more rapidly to try to collect better data when the tests are rapidly
1283     * running through apps.
1284     */
1285    boolean mTestPssMode = false;
1286
1287    String mDebugApp = null;
1288    boolean mWaitForDebugger = false;
1289    boolean mDebugTransient = false;
1290    String mOrigDebugApp = null;
1291    boolean mOrigWaitForDebugger = false;
1292    boolean mAlwaysFinishActivities = false;
1293    boolean mForceResizableActivities;
1294    boolean mSupportsFreeformWindowManagement;
1295    boolean mSupportsPictureInPicture;
1296    Rect mDefaultPinnedStackBounds;
1297    IActivityController mController = null;
1298    String mProfileApp = null;
1299    ProcessRecord mProfileProc = null;
1300    String mProfileFile;
1301    ParcelFileDescriptor mProfileFd;
1302    int mSamplingInterval = 0;
1303    boolean mAutoStopProfiler = false;
1304    int mProfileType = 0;
1305    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1306    String mMemWatchDumpProcName;
1307    String mMemWatchDumpFile;
1308    int mMemWatchDumpPid;
1309    int mMemWatchDumpUid;
1310    String mTrackAllocationApp = null;
1311    String mNativeDebuggingApp = null;
1312
1313    final long[] mTmpLong = new long[2];
1314
1315    static final class ProcessChangeItem {
1316        static final int CHANGE_ACTIVITIES = 1<<0;
1317        static final int CHANGE_PROCESS_STATE = 1<<1;
1318        int changes;
1319        int uid;
1320        int pid;
1321        int processState;
1322        boolean foregroundActivities;
1323    }
1324
1325    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1326    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1327
1328    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1329    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1330
1331    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1332    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1333
1334    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1335    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1336
1337    /**
1338     * Runtime CPU use collection thread.  This object's lock is used to
1339     * perform synchronization with the thread (notifying it to run).
1340     */
1341    final Thread mProcessCpuThread;
1342
1343    /**
1344     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1345     * Must acquire this object's lock when accessing it.
1346     * NOTE: this lock will be held while doing long operations (trawling
1347     * through all processes in /proc), so it should never be acquired by
1348     * any critical paths such as when holding the main activity manager lock.
1349     */
1350    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1351            MONITOR_THREAD_CPU_USAGE);
1352    final AtomicLong mLastCpuTime = new AtomicLong(0);
1353    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1354
1355    long mLastWriteTime = 0;
1356
1357    /**
1358     * Used to retain an update lock when the foreground activity is in
1359     * immersive mode.
1360     */
1361    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1362
1363    /**
1364     * Set to true after the system has finished booting.
1365     */
1366    boolean mBooted = false;
1367
1368    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1369    int mProcessLimitOverride = -1;
1370
1371    WindowManagerService mWindowManager;
1372
1373    final ActivityThread mSystemThread;
1374
1375    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1376        final ProcessRecord mApp;
1377        final int mPid;
1378        final IApplicationThread mAppThread;
1379
1380        AppDeathRecipient(ProcessRecord app, int pid,
1381                IApplicationThread thread) {
1382            if (DEBUG_ALL) Slog.v(
1383                TAG, "New death recipient " + this
1384                + " for thread " + thread.asBinder());
1385            mApp = app;
1386            mPid = pid;
1387            mAppThread = thread;
1388        }
1389
1390        @Override
1391        public void binderDied() {
1392            if (DEBUG_ALL) Slog.v(
1393                TAG, "Death received in " + this
1394                + " for thread " + mAppThread.asBinder());
1395            synchronized(ActivityManagerService.this) {
1396                appDiedLocked(mApp, mPid, mAppThread, true);
1397            }
1398        }
1399    }
1400
1401    static final int SHOW_ERROR_UI_MSG = 1;
1402    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1403    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1404    static final int UPDATE_CONFIGURATION_MSG = 4;
1405    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1406    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1407    static final int SERVICE_TIMEOUT_MSG = 12;
1408    static final int UPDATE_TIME_ZONE = 13;
1409    static final int SHOW_UID_ERROR_UI_MSG = 14;
1410    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1411    static final int PROC_START_TIMEOUT_MSG = 20;
1412    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1413    static final int KILL_APPLICATION_MSG = 22;
1414    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1415    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1416    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1417    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1418    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1419    static final int CLEAR_DNS_CACHE_MSG = 28;
1420    static final int UPDATE_HTTP_PROXY_MSG = 29;
1421    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1422    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1423    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1424    static final int REPORT_MEM_USAGE_MSG = 33;
1425    static final int REPORT_USER_SWITCH_MSG = 34;
1426    static final int CONTINUE_USER_SWITCH_MSG = 35;
1427    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1428    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1429    static final int PERSIST_URI_GRANTS_MSG = 38;
1430    static final int REQUEST_ALL_PSS_MSG = 39;
1431    static final int START_PROFILES_MSG = 40;
1432    static final int UPDATE_TIME = 41;
1433    static final int SYSTEM_USER_START_MSG = 42;
1434    static final int SYSTEM_USER_CURRENT_MSG = 43;
1435    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1436    static final int FINISH_BOOTING_MSG = 45;
1437    static final int START_USER_SWITCH_UI_MSG = 46;
1438    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1439    static final int DISMISS_DIALOG_UI_MSG = 48;
1440    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1441    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1442    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1443    static final int DELETE_DUMPHEAP_MSG = 52;
1444    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1445    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1446    static final int REPORT_TIME_TRACKER_MSG = 55;
1447    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1448    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1449    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1450    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1451    static final int IDLE_UIDS_MSG = 60;
1452    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1453    static final int LOG_STACK_STATE = 62;
1454    static final int VR_MODE_CHANGE_MSG = 63;
1455    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1456    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1457    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1458
1459    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1460    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1461    static final int FIRST_COMPAT_MODE_MSG = 300;
1462    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1463
1464    CompatModeDialog mCompatModeDialog;
1465    long mLastMemUsageReportTime = 0;
1466
1467    /**
1468     * Flag whether the current user is a "monkey", i.e. whether
1469     * the UI is driven by a UI automation tool.
1470     */
1471    private boolean mUserIsMonkey;
1472
1473    /** Flag whether the device has a Recents UI */
1474    boolean mHasRecents;
1475
1476    /** The dimensions of the thumbnails in the Recents UI. */
1477    int mThumbnailWidth;
1478    int mThumbnailHeight;
1479
1480    final ServiceThread mHandlerThread;
1481    final MainHandler mHandler;
1482    final UiHandler mUiHandler;
1483    final ProcessStartLogger mProcessStartLogger;
1484
1485    PackageManagerInternal mPackageManagerInt;
1486
1487    final class UiHandler extends Handler {
1488        public UiHandler() {
1489            super(com.android.server.UiThread.get().getLooper(), null, true);
1490        }
1491
1492        @Override
1493        public void handleMessage(Message msg) {
1494            switch (msg.what) {
1495            case SHOW_ERROR_UI_MSG: {
1496                mAppErrors.handleShowAppErrorUi(msg);
1497                ensureBootCompleted();
1498            } break;
1499            case SHOW_NOT_RESPONDING_UI_MSG: {
1500                mAppErrors.handleShowAnrUi(msg);
1501                ensureBootCompleted();
1502            } break;
1503            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1504                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1505                synchronized (ActivityManagerService.this) {
1506                    ProcessRecord proc = (ProcessRecord) data.get("app");
1507                    if (proc == null) {
1508                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1509                        break;
1510                    }
1511                    if (proc.crashDialog != null) {
1512                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1513                        return;
1514                    }
1515                    AppErrorResult res = (AppErrorResult) data.get("result");
1516                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1517                        Dialog d = new StrictModeViolationDialog(mContext,
1518                                ActivityManagerService.this, res, proc);
1519                        d.show();
1520                        proc.crashDialog = d;
1521                    } else {
1522                        // The device is asleep, so just pretend that the user
1523                        // saw a crash dialog and hit "force quit".
1524                        res.set(0);
1525                    }
1526                }
1527                ensureBootCompleted();
1528            } break;
1529            case SHOW_FACTORY_ERROR_UI_MSG: {
1530                Dialog d = new FactoryErrorDialog(
1531                    mContext, msg.getData().getCharSequence("msg"));
1532                d.show();
1533                ensureBootCompleted();
1534            } break;
1535            case WAIT_FOR_DEBUGGER_UI_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    ProcessRecord app = (ProcessRecord)msg.obj;
1538                    if (msg.arg1 != 0) {
1539                        if (!app.waitedForDebugger) {
1540                            Dialog d = new AppWaitingForDebuggerDialog(
1541                                    ActivityManagerService.this,
1542                                    mContext, app);
1543                            app.waitDialog = d;
1544                            app.waitedForDebugger = true;
1545                            d.show();
1546                        }
1547                    } else {
1548                        if (app.waitDialog != null) {
1549                            app.waitDialog.dismiss();
1550                            app.waitDialog = null;
1551                        }
1552                    }
1553                }
1554            } break;
1555            case SHOW_UID_ERROR_UI_MSG: {
1556                if (mShowDialogs) {
1557                    AlertDialog d = new BaseErrorDialog(mContext);
1558                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1559                    d.setCancelable(false);
1560                    d.setTitle(mContext.getText(R.string.android_system_label));
1561                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1562                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1563                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1564                    d.show();
1565                }
1566            } break;
1567            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1568                if (mShowDialogs) {
1569                    AlertDialog d = new BaseErrorDialog(mContext);
1570                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1571                    d.setCancelable(false);
1572                    d.setTitle(mContext.getText(R.string.android_system_label));
1573                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1574                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1575                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1576                    d.show();
1577                }
1578            } break;
1579            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1580                synchronized (ActivityManagerService.this) {
1581                    ActivityRecord ar = (ActivityRecord) msg.obj;
1582                    if (mCompatModeDialog != null) {
1583                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1584                                ar.info.applicationInfo.packageName)) {
1585                            return;
1586                        }
1587                        mCompatModeDialog.dismiss();
1588                        mCompatModeDialog = null;
1589                    }
1590                    if (ar != null && false) {
1591                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1592                                ar.packageName)) {
1593                            int mode = mCompatModePackages.computeCompatModeLocked(
1594                                    ar.info.applicationInfo);
1595                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1596                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1597                                mCompatModeDialog = new CompatModeDialog(
1598                                        ActivityManagerService.this, mContext,
1599                                        ar.info.applicationInfo);
1600                                mCompatModeDialog.show();
1601                            }
1602                        }
1603                    }
1604                }
1605                break;
1606            }
1607            case START_USER_SWITCH_UI_MSG: {
1608                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1609                break;
1610            }
1611            case DISMISS_DIALOG_UI_MSG: {
1612                final Dialog d = (Dialog) msg.obj;
1613                d.dismiss();
1614                break;
1615            }
1616            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1617                dispatchProcessesChanged();
1618                break;
1619            }
1620            case DISPATCH_PROCESS_DIED_UI_MSG: {
1621                final int pid = msg.arg1;
1622                final int uid = msg.arg2;
1623                dispatchProcessDied(pid, uid);
1624                break;
1625            }
1626            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1627                dispatchUidsChanged();
1628            } break;
1629            }
1630        }
1631    }
1632
1633    final class MainHandler extends Handler {
1634        public MainHandler(Looper looper) {
1635            super(looper, null, true);
1636        }
1637
1638        @Override
1639        public void handleMessage(Message msg) {
1640            switch (msg.what) {
1641            case UPDATE_CONFIGURATION_MSG: {
1642                final ContentResolver resolver = mContext.getContentResolver();
1643                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1644                        msg.arg1);
1645            } break;
1646            case GC_BACKGROUND_PROCESSES_MSG: {
1647                synchronized (ActivityManagerService.this) {
1648                    performAppGcsIfAppropriateLocked();
1649                }
1650            } break;
1651            case SERVICE_TIMEOUT_MSG: {
1652                if (mDidDexOpt) {
1653                    mDidDexOpt = false;
1654                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1655                    nmsg.obj = msg.obj;
1656                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1657                    return;
1658                }
1659                mServices.serviceTimeout((ProcessRecord)msg.obj);
1660            } break;
1661            case UPDATE_TIME_ZONE: {
1662                synchronized (ActivityManagerService.this) {
1663                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1664                        ProcessRecord r = mLruProcesses.get(i);
1665                        if (r.thread != null) {
1666                            try {
1667                                r.thread.updateTimeZone();
1668                            } catch (RemoteException ex) {
1669                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1670                            }
1671                        }
1672                    }
1673                }
1674            } break;
1675            case CLEAR_DNS_CACHE_MSG: {
1676                synchronized (ActivityManagerService.this) {
1677                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1678                        ProcessRecord r = mLruProcesses.get(i);
1679                        if (r.thread != null) {
1680                            try {
1681                                r.thread.clearDnsCache();
1682                            } catch (RemoteException ex) {
1683                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1684                            }
1685                        }
1686                    }
1687                }
1688            } break;
1689            case UPDATE_HTTP_PROXY_MSG: {
1690                ProxyInfo proxy = (ProxyInfo)msg.obj;
1691                String host = "";
1692                String port = "";
1693                String exclList = "";
1694                Uri pacFileUrl = Uri.EMPTY;
1695                if (proxy != null) {
1696                    host = proxy.getHost();
1697                    port = Integer.toString(proxy.getPort());
1698                    exclList = proxy.getExclusionListAsString();
1699                    pacFileUrl = proxy.getPacFileUrl();
1700                }
1701                synchronized (ActivityManagerService.this) {
1702                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1703                        ProcessRecord r = mLruProcesses.get(i);
1704                        if (r.thread != null) {
1705                            try {
1706                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1707                            } catch (RemoteException ex) {
1708                                Slog.w(TAG, "Failed to update http proxy for: " +
1709                                        r.info.processName);
1710                            }
1711                        }
1712                    }
1713                }
1714            } break;
1715            case PROC_START_TIMEOUT_MSG: {
1716                if (mDidDexOpt) {
1717                    mDidDexOpt = false;
1718                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1719                    nmsg.obj = msg.obj;
1720                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1721                    return;
1722                }
1723                ProcessRecord app = (ProcessRecord)msg.obj;
1724                synchronized (ActivityManagerService.this) {
1725                    processStartTimedOutLocked(app);
1726                }
1727            } break;
1728            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1729                ProcessRecord app = (ProcessRecord)msg.obj;
1730                synchronized (ActivityManagerService.this) {
1731                    processContentProviderPublishTimedOutLocked(app);
1732                }
1733            } break;
1734            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1737                }
1738            } break;
1739            case KILL_APPLICATION_MSG: {
1740                synchronized (ActivityManagerService.this) {
1741                    int appid = msg.arg1;
1742                    boolean restart = (msg.arg2 == 1);
1743                    Bundle bundle = (Bundle)msg.obj;
1744                    String pkg = bundle.getString("pkg");
1745                    String reason = bundle.getString("reason");
1746                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1747                            false, UserHandle.USER_ALL, reason);
1748                }
1749            } break;
1750            case FINALIZE_PENDING_INTENT_MSG: {
1751                ((PendingIntentRecord)msg.obj).completeFinalize();
1752            } break;
1753            case POST_HEAVY_NOTIFICATION_MSG: {
1754                INotificationManager inm = NotificationManager.getService();
1755                if (inm == null) {
1756                    return;
1757                }
1758
1759                ActivityRecord root = (ActivityRecord)msg.obj;
1760                ProcessRecord process = root.app;
1761                if (process == null) {
1762                    return;
1763                }
1764
1765                try {
1766                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1767                    String text = mContext.getString(R.string.heavy_weight_notification,
1768                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1769                    Notification notification = new Notification.Builder(context)
1770                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1771                            .setWhen(0)
1772                            .setOngoing(true)
1773                            .setTicker(text)
1774                            .setColor(mContext.getColor(
1775                                    com.android.internal.R.color.system_notification_accent_color))
1776                            .setContentTitle(text)
1777                            .setContentText(
1778                                    mContext.getText(R.string.heavy_weight_notification_detail))
1779                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1780                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1781                                    new UserHandle(root.userId)))
1782                            .build();
1783                    try {
1784                        int[] outId = new int[1];
1785                        inm.enqueueNotificationWithTag("android", "android", null,
1786                                R.string.heavy_weight_notification,
1787                                notification, outId, root.userId);
1788                    } catch (RuntimeException e) {
1789                        Slog.w(ActivityManagerService.TAG,
1790                                "Error showing notification for heavy-weight app", e);
1791                    } catch (RemoteException e) {
1792                    }
1793                } catch (NameNotFoundException e) {
1794                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1795                }
1796            } break;
1797            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1798                INotificationManager inm = NotificationManager.getService();
1799                if (inm == null) {
1800                    return;
1801                }
1802                try {
1803                    inm.cancelNotificationWithTag("android", null,
1804                            R.string.heavy_weight_notification,  msg.arg1);
1805                } catch (RuntimeException e) {
1806                    Slog.w(ActivityManagerService.TAG,
1807                            "Error canceling notification for service", e);
1808                } catch (RemoteException e) {
1809                }
1810            } break;
1811            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1812                synchronized (ActivityManagerService.this) {
1813                    checkExcessivePowerUsageLocked(true);
1814                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1815                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1816                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1817                }
1818            } break;
1819            case REPORT_MEM_USAGE_MSG: {
1820                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1821                Thread thread = new Thread() {
1822                    @Override public void run() {
1823                        reportMemUsage(memInfos);
1824                    }
1825                };
1826                thread.start();
1827                break;
1828            }
1829            case REPORT_USER_SWITCH_MSG: {
1830                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1831                break;
1832            }
1833            case CONTINUE_USER_SWITCH_MSG: {
1834                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1835                break;
1836            }
1837            case USER_SWITCH_TIMEOUT_MSG: {
1838                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1839                break;
1840            }
1841            case IMMERSIVE_MODE_LOCK_MSG: {
1842                final boolean nextState = (msg.arg1 != 0);
1843                if (mUpdateLock.isHeld() != nextState) {
1844                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1845                            "Applying new update lock state '" + nextState
1846                            + "' for " + (ActivityRecord)msg.obj);
1847                    if (nextState) {
1848                        mUpdateLock.acquire();
1849                    } else {
1850                        mUpdateLock.release();
1851                    }
1852                }
1853                break;
1854            }
1855            case PERSIST_URI_GRANTS_MSG: {
1856                writeGrantedUriPermissions();
1857                break;
1858            }
1859            case REQUEST_ALL_PSS_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1862                }
1863                break;
1864            }
1865            case START_PROFILES_MSG: {
1866                synchronized (ActivityManagerService.this) {
1867                    mUserController.startProfilesLocked();
1868                }
1869                break;
1870            }
1871            case UPDATE_TIME: {
1872                synchronized (ActivityManagerService.this) {
1873                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1874                        ProcessRecord r = mLruProcesses.get(i);
1875                        if (r.thread != null) {
1876                            try {
1877                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1878                            } catch (RemoteException ex) {
1879                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1880                            }
1881                        }
1882                    }
1883                }
1884                break;
1885            }
1886            case SYSTEM_USER_START_MSG: {
1887                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1888                        Integer.toString(msg.arg1), msg.arg1);
1889                mSystemServiceManager.startUser(msg.arg1);
1890                break;
1891            }
1892            case SYSTEM_USER_UNLOCK_MSG: {
1893                final int userId = msg.arg1;
1894                mSystemServiceManager.unlockUser(userId);
1895                mRecentTasks.cleanupLocked(userId);
1896                installEncryptionUnawareProviders(userId);
1897                break;
1898            }
1899            case SYSTEM_USER_CURRENT_MSG: {
1900                mBatteryStatsService.noteEvent(
1901                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1902                        Integer.toString(msg.arg2), msg.arg2);
1903                mBatteryStatsService.noteEvent(
1904                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1905                        Integer.toString(msg.arg1), msg.arg1);
1906                mSystemServiceManager.switchUser(msg.arg1);
1907                break;
1908            }
1909            case ENTER_ANIMATION_COMPLETE_MSG: {
1910                synchronized (ActivityManagerService.this) {
1911                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1912                    if (r != null && r.app != null && r.app.thread != null) {
1913                        try {
1914                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1915                        } catch (RemoteException e) {
1916                        }
1917                    }
1918                }
1919                break;
1920            }
1921            case FINISH_BOOTING_MSG: {
1922                if (msg.arg1 != 0) {
1923                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1924                    finishBooting();
1925                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1926                }
1927                if (msg.arg2 != 0) {
1928                    enableScreenAfterBoot();
1929                }
1930                break;
1931            }
1932            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1933                try {
1934                    Locale l = (Locale) msg.obj;
1935                    IBinder service = ServiceManager.getService("mount");
1936                    IMountService mountService = IMountService.Stub.asInterface(service);
1937                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1938                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1939                } catch (RemoteException e) {
1940                    Log.e(TAG, "Error storing locale for decryption UI", e);
1941                }
1942                break;
1943            }
1944            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1947                        try {
1948                            // Make a one-way callback to the listener
1949                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1950                        } catch (RemoteException e){
1951                            // Handled by the RemoteCallbackList
1952                        }
1953                    }
1954                    mTaskStackListeners.finishBroadcast();
1955                }
1956                break;
1957            }
1958            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1959                synchronized (ActivityManagerService.this) {
1960                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1961                        try {
1962                            // Make a one-way callback to the listener
1963                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1964                        } catch (RemoteException e){
1965                            // Handled by the RemoteCallbackList
1966                        }
1967                    }
1968                    mTaskStackListeners.finishBroadcast();
1969                }
1970                break;
1971            }
1972            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1975                        try {
1976                            // Make a one-way callback to the listener
1977                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1978                        } catch (RemoteException e){
1979                            // Handled by the RemoteCallbackList
1980                        }
1981                    }
1982                    mTaskStackListeners.finishBroadcast();
1983                }
1984                break;
1985            }
1986            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
1987                synchronized (ActivityManagerService.this) {
1988                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1989                        try {
1990                            // Make a one-way callback to the listener
1991                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
1992                        } catch (RemoteException e){
1993                            // Handled by the RemoteCallbackList
1994                        }
1995                    }
1996                    mTaskStackListeners.finishBroadcast();
1997                }
1998                break;
1999            }
2000            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2001                final int uid = msg.arg1;
2002                final byte[] firstPacket = (byte[]) msg.obj;
2003
2004                synchronized (mPidsSelfLocked) {
2005                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2006                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2007                        if (p.uid == uid) {
2008                            try {
2009                                p.thread.notifyCleartextNetwork(firstPacket);
2010                            } catch (RemoteException ignored) {
2011                            }
2012                        }
2013                    }
2014                }
2015                break;
2016            }
2017            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2018                final String procName;
2019                final int uid;
2020                final long memLimit;
2021                final String reportPackage;
2022                synchronized (ActivityManagerService.this) {
2023                    procName = mMemWatchDumpProcName;
2024                    uid = mMemWatchDumpUid;
2025                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2026                    if (val == null) {
2027                        val = mMemWatchProcesses.get(procName, 0);
2028                    }
2029                    if (val != null) {
2030                        memLimit = val.first;
2031                        reportPackage = val.second;
2032                    } else {
2033                        memLimit = 0;
2034                        reportPackage = null;
2035                    }
2036                }
2037                if (procName == null) {
2038                    return;
2039                }
2040
2041                if (DEBUG_PSS) Slog.d(TAG_PSS,
2042                        "Showing dump heap notification from " + procName + "/" + uid);
2043
2044                INotificationManager inm = NotificationManager.getService();
2045                if (inm == null) {
2046                    return;
2047                }
2048
2049                String text = mContext.getString(R.string.dump_heap_notification, procName);
2050
2051
2052                Intent deleteIntent = new Intent();
2053                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2054                Intent intent = new Intent();
2055                intent.setClassName("android", DumpHeapActivity.class.getName());
2056                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2057                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2058                if (reportPackage != null) {
2059                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2060                }
2061                int userId = UserHandle.getUserId(uid);
2062                Notification notification = new Notification.Builder(mContext)
2063                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2064                        .setWhen(0)
2065                        .setOngoing(true)
2066                        .setAutoCancel(true)
2067                        .setTicker(text)
2068                        .setColor(mContext.getColor(
2069                                com.android.internal.R.color.system_notification_accent_color))
2070                        .setContentTitle(text)
2071                        .setContentText(
2072                                mContext.getText(R.string.dump_heap_notification_detail))
2073                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2074                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2075                                new UserHandle(userId)))
2076                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2077                                deleteIntent, 0, UserHandle.SYSTEM))
2078                        .build();
2079
2080                try {
2081                    int[] outId = new int[1];
2082                    inm.enqueueNotificationWithTag("android", "android", null,
2083                            R.string.dump_heap_notification,
2084                            notification, outId, userId);
2085                } catch (RuntimeException e) {
2086                    Slog.w(ActivityManagerService.TAG,
2087                            "Error showing notification for dump heap", e);
2088                } catch (RemoteException e) {
2089                }
2090            } break;
2091            case DELETE_DUMPHEAP_MSG: {
2092                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2093                        DumpHeapActivity.JAVA_URI,
2094                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2095                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2096                        UserHandle.myUserId());
2097                synchronized (ActivityManagerService.this) {
2098                    mMemWatchDumpFile = null;
2099                    mMemWatchDumpProcName = null;
2100                    mMemWatchDumpPid = -1;
2101                    mMemWatchDumpUid = -1;
2102                }
2103            } break;
2104            case FOREGROUND_PROFILE_CHANGED_MSG: {
2105                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2106            } break;
2107            case REPORT_TIME_TRACKER_MSG: {
2108                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2109                tracker.deliverResult(mContext);
2110            } break;
2111            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2112                mUserController.dispatchUserSwitchComplete(msg.arg1);
2113            } break;
2114            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2115                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2116                try {
2117                    connection.shutdown();
2118                } catch (RemoteException e) {
2119                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2120                }
2121                // Only a UiAutomation can set this flag and now that
2122                // it is finished we make sure it is reset to its default.
2123                mUserIsMonkey = false;
2124            } break;
2125            case APP_BOOST_DEACTIVATE_MSG: {
2126                synchronized(ActivityManagerService.this) {
2127                    if (mIsBoosted) {
2128                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2129                            nativeMigrateFromBoost();
2130                            mIsBoosted = false;
2131                            mBoostStartTime = 0;
2132                        } else {
2133                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2134                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2135                        }
2136                    }
2137                }
2138            } break;
2139            case IDLE_UIDS_MSG: {
2140                idleUids();
2141            } break;
2142            case LOG_STACK_STATE: {
2143                synchronized (ActivityManagerService.this) {
2144                    mStackSupervisor.logStackState();
2145                }
2146            } break;
2147            case VR_MODE_CHANGE_MSG: {
2148                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2149                final boolean vrMode = msg.arg1 != 0;
2150                vrService.setVrMode(vrMode);
2151
2152                if (mInVrMode != vrMode) {
2153                    synchronized (ActivityManagerService.this) {
2154                        mInVrMode = vrMode;
2155                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2156                    }
2157                }
2158            } break;
2159            }
2160        }
2161    };
2162
2163    static final int COLLECT_PSS_BG_MSG = 1;
2164
2165    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2166        @Override
2167        public void handleMessage(Message msg) {
2168            switch (msg.what) {
2169            case COLLECT_PSS_BG_MSG: {
2170                long start = SystemClock.uptimeMillis();
2171                MemInfoReader memInfo = null;
2172                synchronized (ActivityManagerService.this) {
2173                    if (mFullPssPending) {
2174                        mFullPssPending = false;
2175                        memInfo = new MemInfoReader();
2176                    }
2177                }
2178                if (memInfo != null) {
2179                    updateCpuStatsNow();
2180                    long nativeTotalPss = 0;
2181                    synchronized (mProcessCpuTracker) {
2182                        final int N = mProcessCpuTracker.countStats();
2183                        for (int j=0; j<N; j++) {
2184                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2185                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2186                                // This is definitely an application process; skip it.
2187                                continue;
2188                            }
2189                            synchronized (mPidsSelfLocked) {
2190                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2191                                    // This is one of our own processes; skip it.
2192                                    continue;
2193                                }
2194                            }
2195                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2196                        }
2197                    }
2198                    memInfo.readMemInfo();
2199                    synchronized (ActivityManagerService.this) {
2200                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2201                                + (SystemClock.uptimeMillis()-start) + "ms");
2202                        final long cachedKb = memInfo.getCachedSizeKb();
2203                        final long freeKb = memInfo.getFreeSizeKb();
2204                        final long zramKb = memInfo.getZramTotalSizeKb();
2205                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2206                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2207                                kernelKb*1024, nativeTotalPss*1024);
2208                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2209                                nativeTotalPss);
2210                    }
2211                }
2212
2213                int num = 0;
2214                long[] tmp = new long[2];
2215                do {
2216                    ProcessRecord proc;
2217                    int procState;
2218                    int pid;
2219                    long lastPssTime;
2220                    synchronized (ActivityManagerService.this) {
2221                        if (mPendingPssProcesses.size() <= 0) {
2222                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2223                                    "Collected PSS of " + num + " processes in "
2224                                    + (SystemClock.uptimeMillis() - start) + "ms");
2225                            mPendingPssProcesses.clear();
2226                            return;
2227                        }
2228                        proc = mPendingPssProcesses.remove(0);
2229                        procState = proc.pssProcState;
2230                        lastPssTime = proc.lastPssTime;
2231                        if (proc.thread != null && procState == proc.setProcState
2232                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2233                                        < SystemClock.uptimeMillis()) {
2234                            pid = proc.pid;
2235                        } else {
2236                            proc = null;
2237                            pid = 0;
2238                        }
2239                    }
2240                    if (proc != null) {
2241                        long pss = Debug.getPss(pid, tmp, null);
2242                        synchronized (ActivityManagerService.this) {
2243                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2244                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2245                                num++;
2246                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2247                                        SystemClock.uptimeMillis());
2248                            }
2249                        }
2250                    }
2251                } while (true);
2252            }
2253            }
2254        }
2255    };
2256
2257    public void setSystemProcess() {
2258        try {
2259            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2260            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2261            ServiceManager.addService("meminfo", new MemBinder(this));
2262            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2263            ServiceManager.addService("dbinfo", new DbBinder(this));
2264            if (MONITOR_CPU_USAGE) {
2265                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2266            }
2267            ServiceManager.addService("permission", new PermissionController(this));
2268            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2269
2270            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2271                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2272            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2273
2274            synchronized (this) {
2275                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2276                app.persistent = true;
2277                app.pid = MY_PID;
2278                app.maxAdj = ProcessList.SYSTEM_ADJ;
2279                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2280                synchronized (mPidsSelfLocked) {
2281                    mPidsSelfLocked.put(app.pid, app);
2282                }
2283                updateLruProcessLocked(app, false, null);
2284                updateOomAdjLocked();
2285            }
2286        } catch (PackageManager.NameNotFoundException e) {
2287            throw new RuntimeException(
2288                    "Unable to find android system package", e);
2289        }
2290    }
2291
2292    public void setWindowManager(WindowManagerService wm) {
2293        mWindowManager = wm;
2294        mStackSupervisor.setWindowManager(wm);
2295        mActivityStarter.setWindowManager(wm);
2296    }
2297
2298    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2299        mUsageStatsService = usageStatsManager;
2300    }
2301
2302    public void startObservingNativeCrashes() {
2303        final NativeCrashListener ncl = new NativeCrashListener(this);
2304        ncl.start();
2305    }
2306
2307    public IAppOpsService getAppOpsService() {
2308        return mAppOpsService;
2309    }
2310
2311    static class MemBinder extends Binder {
2312        ActivityManagerService mActivityManagerService;
2313        MemBinder(ActivityManagerService activityManagerService) {
2314            mActivityManagerService = activityManagerService;
2315        }
2316
2317        @Override
2318        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2319            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2320                    != PackageManager.PERMISSION_GRANTED) {
2321                pw.println("Permission Denial: can't dump meminfo from from pid="
2322                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2323                        + " without permission " + android.Manifest.permission.DUMP);
2324                return;
2325            }
2326
2327            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2328        }
2329    }
2330
2331    static class GraphicsBinder extends Binder {
2332        ActivityManagerService mActivityManagerService;
2333        GraphicsBinder(ActivityManagerService activityManagerService) {
2334            mActivityManagerService = activityManagerService;
2335        }
2336
2337        @Override
2338        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2339            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2340                    != PackageManager.PERMISSION_GRANTED) {
2341                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2342                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2343                        + " without permission " + android.Manifest.permission.DUMP);
2344                return;
2345            }
2346
2347            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2348        }
2349    }
2350
2351    static class DbBinder extends Binder {
2352        ActivityManagerService mActivityManagerService;
2353        DbBinder(ActivityManagerService activityManagerService) {
2354            mActivityManagerService = activityManagerService;
2355        }
2356
2357        @Override
2358        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2359            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2360                    != PackageManager.PERMISSION_GRANTED) {
2361                pw.println("Permission Denial: can't dump dbinfo from from pid="
2362                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2363                        + " without permission " + android.Manifest.permission.DUMP);
2364                return;
2365            }
2366
2367            mActivityManagerService.dumpDbInfo(fd, pw, args);
2368        }
2369    }
2370
2371    static class CpuBinder extends Binder {
2372        ActivityManagerService mActivityManagerService;
2373        CpuBinder(ActivityManagerService activityManagerService) {
2374            mActivityManagerService = activityManagerService;
2375        }
2376
2377        @Override
2378        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2379            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2380                    != PackageManager.PERMISSION_GRANTED) {
2381                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2382                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2383                        + " without permission " + android.Manifest.permission.DUMP);
2384                return;
2385            }
2386
2387            synchronized (mActivityManagerService.mProcessCpuTracker) {
2388                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2389                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2390                        SystemClock.uptimeMillis()));
2391            }
2392        }
2393    }
2394
2395    public static final class Lifecycle extends SystemService {
2396        private final ActivityManagerService mService;
2397
2398        public Lifecycle(Context context) {
2399            super(context);
2400            mService = new ActivityManagerService(context);
2401        }
2402
2403        @Override
2404        public void onStart() {
2405            mService.start();
2406        }
2407
2408        public ActivityManagerService getService() {
2409            return mService;
2410        }
2411    }
2412
2413    // Note: This method is invoked on the main thread but may need to attach various
2414    // handlers to other threads.  So take care to be explicit about the looper.
2415    public ActivityManagerService(Context systemContext) {
2416        mContext = systemContext;
2417        mFactoryTest = FactoryTest.getMode();
2418        mSystemThread = ActivityThread.currentActivityThread();
2419
2420        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2421
2422        mHandlerThread = new ServiceThread(TAG,
2423                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2424        mHandlerThread.start();
2425        mHandler = new MainHandler(mHandlerThread.getLooper());
2426        mUiHandler = new UiHandler();
2427
2428        mProcessStartLogger = new ProcessStartLogger();
2429
2430        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2431                "foreground", BROADCAST_FG_TIMEOUT, false);
2432        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2433                "background", BROADCAST_BG_TIMEOUT, true);
2434        mBroadcastQueues[0] = mFgBroadcastQueue;
2435        mBroadcastQueues[1] = mBgBroadcastQueue;
2436
2437        mServices = new ActiveServices(this);
2438        mProviderMap = new ProviderMap(this);
2439        mAppErrors = new AppErrors(mContext, this);
2440
2441        // TODO: Move creation of battery stats service outside of activity manager service.
2442        File dataDir = Environment.getDataDirectory();
2443        File systemDir = new File(dataDir, "system");
2444        systemDir.mkdirs();
2445        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2446        mBatteryStatsService.getActiveStatistics().readLocked();
2447        mBatteryStatsService.scheduleWriteToDisk();
2448        mOnBattery = DEBUG_POWER ? true
2449                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2450        mBatteryStatsService.getActiveStatistics().setCallback(this);
2451
2452        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2453
2454        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2455        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2456                new IAppOpsCallback.Stub() {
2457                    @Override public void opChanged(int op, int uid, String packageName) {
2458                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2459                            if (mAppOpsService.checkOperation(op, uid, packageName)
2460                                    != AppOpsManager.MODE_ALLOWED) {
2461                                runInBackgroundDisabled(uid);
2462                            }
2463                        }
2464                    }
2465                });
2466
2467        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2468
2469        mUserController = new UserController(this);
2470
2471        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2472            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2473
2474        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2475
2476        mConfiguration.setToDefaults();
2477        mConfiguration.setLocales(LocaleList.getDefault());
2478
2479        mConfigurationSeq = mConfiguration.seq = 1;
2480        mProcessCpuTracker.init();
2481
2482        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2483        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2484        mStackSupervisor = new ActivityStackSupervisor(this);
2485        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2486        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2487
2488
2489        mProcessCpuThread = new Thread("CpuTracker") {
2490            @Override
2491            public void run() {
2492                while (true) {
2493                    try {
2494                        try {
2495                            synchronized(this) {
2496                                final long now = SystemClock.uptimeMillis();
2497                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2498                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2499                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2500                                //        + ", write delay=" + nextWriteDelay);
2501                                if (nextWriteDelay < nextCpuDelay) {
2502                                    nextCpuDelay = nextWriteDelay;
2503                                }
2504                                if (nextCpuDelay > 0) {
2505                                    mProcessCpuMutexFree.set(true);
2506                                    this.wait(nextCpuDelay);
2507                                }
2508                            }
2509                        } catch (InterruptedException e) {
2510                        }
2511                        updateCpuStatsNow();
2512                    } catch (Exception e) {
2513                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2514                    }
2515                }
2516            }
2517        };
2518
2519        Watchdog.getInstance().addMonitor(this);
2520        Watchdog.getInstance().addThread(mHandler);
2521    }
2522
2523    public void setSystemServiceManager(SystemServiceManager mgr) {
2524        mSystemServiceManager = mgr;
2525    }
2526
2527    public void setInstaller(Installer installer) {
2528        mInstaller = installer;
2529    }
2530
2531    private void start() {
2532        Process.removeAllProcessGroups();
2533        mProcessCpuThread.start();
2534
2535        mBatteryStatsService.publish(mContext);
2536        mAppOpsService.publish(mContext);
2537        Slog.d("AppOps", "AppOpsService published");
2538        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2539    }
2540
2541    void onUserStoppedLocked(int userId) {
2542        mRecentTasks.unloadUserRecentsLocked(userId);
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    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2747        if (r == null || mFocusedActivity == r) {
2748            return false;
2749        }
2750
2751        if (!r.isFocusable()) {
2752            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2753            return false;
2754        }
2755
2756        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2757
2758        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2759        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2760                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2761        mDoingSetFocusedActivity = true;
2762
2763        final ActivityRecord last = mFocusedActivity;
2764        mFocusedActivity = r;
2765        if (r.task.isApplicationTask()) {
2766            if (mCurAppTimeTracker != r.appTimeTracker) {
2767                // We are switching app tracking.  Complete the current one.
2768                if (mCurAppTimeTracker != null) {
2769                    mCurAppTimeTracker.stop();
2770                    mHandler.obtainMessage(
2771                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2772                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2773                    mCurAppTimeTracker = null;
2774                }
2775                if (r.appTimeTracker != null) {
2776                    mCurAppTimeTracker = r.appTimeTracker;
2777                    startTimeTrackingFocusedActivityLocked();
2778                }
2779            } else {
2780                startTimeTrackingFocusedActivityLocked();
2781            }
2782        } else {
2783            r.appTimeTracker = null;
2784        }
2785        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2786        // TODO: Probably not, because we don't want to resume voice on switching
2787        // back to this activity
2788        if (r.task.voiceInteractor != null) {
2789            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2790        } else {
2791            finishRunningVoiceLocked();
2792            IVoiceInteractionSession session;
2793            if (last != null && ((session = last.task.voiceSession) != null
2794                    || (session = last.voiceSession) != null)) {
2795                // We had been in a voice interaction session, but now focused has
2796                // move to something different.  Just finish the session, we can't
2797                // return to it and retain the proper state and synchronization with
2798                // the voice interaction service.
2799                finishVoiceTask(session);
2800            }
2801        }
2802        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2803            mWindowManager.setFocusedApp(r.appToken, true);
2804        }
2805        applyUpdateLockStateLocked(r);
2806        applyUpdateVrModeLocked(r);
2807        if (mFocusedActivity.userId != mLastFocusedUserId) {
2808            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2809            mHandler.obtainMessage(
2810                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2811            mLastFocusedUserId = mFocusedActivity.userId;
2812        }
2813
2814        // Log a warning if the focused app is changed during the process. This could
2815        // indicate a problem of the focus setting logic!
2816        if (mFocusedActivity != r) Slog.w(TAG,
2817                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2818        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2819
2820        EventLogTags.writeAmFocusedActivity(
2821                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2822                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2823                reason);
2824        return true;
2825    }
2826
2827    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2828        if (mFocusedActivity != goingAway) {
2829            return;
2830        }
2831
2832        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2833        if (focusedStack != null) {
2834            final ActivityRecord top = focusedStack.topActivity();
2835            if (top != null && top.userId != mLastFocusedUserId) {
2836                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2837                mHandler.sendMessage(
2838                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2839                mLastFocusedUserId = top.userId;
2840            }
2841        }
2842
2843        // Try to move focus to another activity if possible.
2844        if (setFocusedActivityLocked(
2845                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2846            return;
2847        }
2848
2849        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2850                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2851        mFocusedActivity = null;
2852        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2853    }
2854
2855    @Override
2856    public void setFocusedStack(int stackId) {
2857        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2858        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2859        final long callingId = Binder.clearCallingIdentity();
2860        try {
2861            synchronized (this) {
2862                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2863                if (stack == null) {
2864                    return;
2865                }
2866                final ActivityRecord r = stack.topRunningActivityLocked();
2867                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2868                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2869                }
2870            }
2871        } finally {
2872            Binder.restoreCallingIdentity(callingId);
2873        }
2874    }
2875
2876    @Override
2877    public void setFocusedTask(int taskId) {
2878        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2879        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2880        final long callingId = Binder.clearCallingIdentity();
2881        try {
2882            synchronized (this) {
2883                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2884                if (task == null) {
2885                    return;
2886                }
2887                final ActivityRecord r = task.topRunningActivityLocked();
2888                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2889                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2890                }
2891            }
2892        } finally {
2893            Binder.restoreCallingIdentity(callingId);
2894        }
2895    }
2896
2897    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2898    @Override
2899    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2901        synchronized (this) {
2902            if (listener != null) {
2903                mTaskStackListeners.register(listener);
2904            }
2905        }
2906    }
2907
2908    @Override
2909    public void notifyActivityDrawn(IBinder token) {
2910        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2911        synchronized (this) {
2912            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2913            if (r != null) {
2914                r.task.stack.notifyActivityDrawnLocked(r);
2915            }
2916        }
2917    }
2918
2919    final void applyUpdateLockStateLocked(ActivityRecord r) {
2920        // Modifications to the UpdateLock state are done on our handler, outside
2921        // the activity manager's locks.  The new state is determined based on the
2922        // state *now* of the relevant activity record.  The object is passed to
2923        // the handler solely for logging detail, not to be consulted/modified.
2924        final boolean nextState = r != null && r.immersive;
2925        mHandler.sendMessage(
2926                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2927    }
2928
2929    final void applyUpdateVrModeLocked(ActivityRecord r) {
2930        mHandler.sendMessage(
2931                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2932    }
2933
2934    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2935        Message msg = Message.obtain();
2936        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2937        msg.obj = r.task.askedCompatMode ? null : r;
2938        mUiHandler.sendMessage(msg);
2939    }
2940
2941    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2942            String what, Object obj, ProcessRecord srcApp) {
2943        app.lastActivityTime = now;
2944
2945        if (app.activities.size() > 0) {
2946            // Don't want to touch dependent processes that are hosting activities.
2947            return index;
2948        }
2949
2950        int lrui = mLruProcesses.lastIndexOf(app);
2951        if (lrui < 0) {
2952            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2953                    + what + " " + obj + " from " + srcApp);
2954            return index;
2955        }
2956
2957        if (lrui >= index) {
2958            // Don't want to cause this to move dependent processes *back* in the
2959            // list as if they were less frequently used.
2960            return index;
2961        }
2962
2963        if (lrui >= mLruProcessActivityStart) {
2964            // Don't want to touch dependent processes that are hosting activities.
2965            return index;
2966        }
2967
2968        mLruProcesses.remove(lrui);
2969        if (index > 0) {
2970            index--;
2971        }
2972        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2973                + " in LRU list: " + app);
2974        mLruProcesses.add(index, app);
2975        return index;
2976    }
2977
2978    static void killProcessGroup(int uid, int pid) {
2979        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2980        Process.killProcessGroup(uid, pid);
2981        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2982    }
2983
2984    final void removeLruProcessLocked(ProcessRecord app) {
2985        int lrui = mLruProcesses.lastIndexOf(app);
2986        if (lrui >= 0) {
2987            if (!app.killed) {
2988                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2989                Process.killProcessQuiet(app.pid);
2990                killProcessGroup(app.info.uid, app.pid);
2991            }
2992            if (lrui <= mLruProcessActivityStart) {
2993                mLruProcessActivityStart--;
2994            }
2995            if (lrui <= mLruProcessServiceStart) {
2996                mLruProcessServiceStart--;
2997            }
2998            mLruProcesses.remove(lrui);
2999        }
3000    }
3001
3002    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3003            ProcessRecord client) {
3004        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3005                || app.treatLikeActivity;
3006        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3007        if (!activityChange && hasActivity) {
3008            // The process has activities, so we are only allowing activity-based adjustments
3009            // to move it.  It should be kept in the front of the list with other
3010            // processes that have activities, and we don't want those to change their
3011            // order except due to activity operations.
3012            return;
3013        }
3014
3015        mLruSeq++;
3016        final long now = SystemClock.uptimeMillis();
3017        app.lastActivityTime = now;
3018
3019        // First a quick reject: if the app is already at the position we will
3020        // put it, then there is nothing to do.
3021        if (hasActivity) {
3022            final int N = mLruProcesses.size();
3023            if (N > 0 && mLruProcesses.get(N-1) == app) {
3024                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3025                return;
3026            }
3027        } else {
3028            if (mLruProcessServiceStart > 0
3029                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3030                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3031                return;
3032            }
3033        }
3034
3035        int lrui = mLruProcesses.lastIndexOf(app);
3036
3037        if (app.persistent && lrui >= 0) {
3038            // We don't care about the position of persistent processes, as long as
3039            // they are in the list.
3040            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3041            return;
3042        }
3043
3044        /* In progress: compute new position first, so we can avoid doing work
3045           if the process is not actually going to move.  Not yet working.
3046        int addIndex;
3047        int nextIndex;
3048        boolean inActivity = false, inService = false;
3049        if (hasActivity) {
3050            // Process has activities, put it at the very tipsy-top.
3051            addIndex = mLruProcesses.size();
3052            nextIndex = mLruProcessServiceStart;
3053            inActivity = true;
3054        } else if (hasService) {
3055            // Process has services, put it at the top of the service list.
3056            addIndex = mLruProcessActivityStart;
3057            nextIndex = mLruProcessServiceStart;
3058            inActivity = true;
3059            inService = true;
3060        } else  {
3061            // Process not otherwise of interest, it goes to the top of the non-service area.
3062            addIndex = mLruProcessServiceStart;
3063            if (client != null) {
3064                int clientIndex = mLruProcesses.lastIndexOf(client);
3065                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3066                        + app);
3067                if (clientIndex >= 0 && addIndex > clientIndex) {
3068                    addIndex = clientIndex;
3069                }
3070            }
3071            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3072        }
3073
3074        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3075                + mLruProcessActivityStart + "): " + app);
3076        */
3077
3078        if (lrui >= 0) {
3079            if (lrui < mLruProcessActivityStart) {
3080                mLruProcessActivityStart--;
3081            }
3082            if (lrui < mLruProcessServiceStart) {
3083                mLruProcessServiceStart--;
3084            }
3085            /*
3086            if (addIndex > lrui) {
3087                addIndex--;
3088            }
3089            if (nextIndex > lrui) {
3090                nextIndex--;
3091            }
3092            */
3093            mLruProcesses.remove(lrui);
3094        }
3095
3096        /*
3097        mLruProcesses.add(addIndex, app);
3098        if (inActivity) {
3099            mLruProcessActivityStart++;
3100        }
3101        if (inService) {
3102            mLruProcessActivityStart++;
3103        }
3104        */
3105
3106        int nextIndex;
3107        if (hasActivity) {
3108            final int N = mLruProcesses.size();
3109            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3110                // Process doesn't have activities, but has clients with
3111                // activities...  move it up, but one below the top (the top
3112                // should always have a real activity).
3113                if (DEBUG_LRU) Slog.d(TAG_LRU,
3114                        "Adding to second-top of LRU activity list: " + app);
3115                mLruProcesses.add(N - 1, app);
3116                // To keep it from spamming the LRU list (by making a bunch of clients),
3117                // we will push down any other entries owned by the app.
3118                final int uid = app.info.uid;
3119                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3120                    ProcessRecord subProc = mLruProcesses.get(i);
3121                    if (subProc.info.uid == uid) {
3122                        // We want to push this one down the list.  If the process after
3123                        // it is for the same uid, however, don't do so, because we don't
3124                        // want them internally to be re-ordered.
3125                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3126                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3127                                    "Pushing uid " + uid + " swapping at " + i + ": "
3128                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3129                            ProcessRecord tmp = mLruProcesses.get(i);
3130                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3131                            mLruProcesses.set(i - 1, tmp);
3132                            i--;
3133                        }
3134                    } else {
3135                        // A gap, we can stop here.
3136                        break;
3137                    }
3138                }
3139            } else {
3140                // Process has activities, put it at the very tipsy-top.
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3142                mLruProcesses.add(app);
3143            }
3144            nextIndex = mLruProcessServiceStart;
3145        } else if (hasService) {
3146            // Process has services, put it at the top of the service list.
3147            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3148            mLruProcesses.add(mLruProcessActivityStart, app);
3149            nextIndex = mLruProcessServiceStart;
3150            mLruProcessActivityStart++;
3151        } else  {
3152            // Process not otherwise of interest, it goes to the top of the non-service area.
3153            int index = mLruProcessServiceStart;
3154            if (client != null) {
3155                // If there is a client, don't allow the process to be moved up higher
3156                // in the list than that client.
3157                int clientIndex = mLruProcesses.lastIndexOf(client);
3158                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3159                        + " when updating " + app);
3160                if (clientIndex <= lrui) {
3161                    // Don't allow the client index restriction to push it down farther in the
3162                    // list than it already is.
3163                    clientIndex = lrui;
3164                }
3165                if (clientIndex >= 0 && index > clientIndex) {
3166                    index = clientIndex;
3167                }
3168            }
3169            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3170            mLruProcesses.add(index, app);
3171            nextIndex = index-1;
3172            mLruProcessActivityStart++;
3173            mLruProcessServiceStart++;
3174        }
3175
3176        // If the app is currently using a content provider or service,
3177        // bump those processes as well.
3178        for (int j=app.connections.size()-1; j>=0; j--) {
3179            ConnectionRecord cr = app.connections.valueAt(j);
3180            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3181                    && cr.binding.service.app != null
3182                    && cr.binding.service.app.lruSeq != mLruSeq
3183                    && !cr.binding.service.app.persistent) {
3184                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3185                        "service connection", cr, app);
3186            }
3187        }
3188        for (int j=app.conProviders.size()-1; j>=0; j--) {
3189            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3190            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3191                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3192                        "provider reference", cpr, app);
3193            }
3194        }
3195    }
3196
3197    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3198        if (uid == Process.SYSTEM_UID) {
3199            // The system gets to run in any process.  If there are multiple
3200            // processes with the same uid, just pick the first (this
3201            // should never happen).
3202            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3203            if (procs == null) return null;
3204            final int procCount = procs.size();
3205            for (int i = 0; i < procCount; i++) {
3206                final int procUid = procs.keyAt(i);
3207                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3208                    // Don't use an app process or different user process for system component.
3209                    continue;
3210                }
3211                return procs.valueAt(i);
3212            }
3213        }
3214        ProcessRecord proc = mProcessNames.get(processName, uid);
3215        if (false && proc != null && !keepIfLarge
3216                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3217                && proc.lastCachedPss >= 4000) {
3218            // Turn this condition on to cause killing to happen regularly, for testing.
3219            if (proc.baseProcessTracker != null) {
3220                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3221            }
3222            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3223        } else if (proc != null && !keepIfLarge
3224                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3225                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3226            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3227            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3228                if (proc.baseProcessTracker != null) {
3229                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3230                }
3231                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3232            }
3233        }
3234        return proc;
3235    }
3236
3237    void notifyPackageUse(String packageName) {
3238        IPackageManager pm = AppGlobals.getPackageManager();
3239        try {
3240            pm.notifyPackageUse(packageName);
3241        } catch (RemoteException e) {
3242        }
3243    }
3244
3245    boolean isNextTransitionForward() {
3246        int transit = mWindowManager.getPendingAppTransition();
3247        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3248                || transit == AppTransition.TRANSIT_TASK_OPEN
3249                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3250    }
3251
3252    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3253            String processName, String abiOverride, int uid, Runnable crashHandler) {
3254        synchronized(this) {
3255            ApplicationInfo info = new ApplicationInfo();
3256            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3257            // For isolated processes, the former contains the parent's uid and the latter the
3258            // actual uid of the isolated process.
3259            // In the special case introduced by this method (which is, starting an isolated
3260            // process directly from the SystemServer without an actual parent app process) the
3261            // closest thing to a parent's uid is SYSTEM_UID.
3262            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3263            // the |isolated| logic in the ProcessRecord constructor.
3264            info.uid = Process.SYSTEM_UID;
3265            info.processName = processName;
3266            info.className = entryPoint;
3267            info.packageName = "android";
3268            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3269                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3270                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3271                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3272                    crashHandler);
3273            return proc != null ? proc.pid : 0;
3274        }
3275    }
3276
3277    final ProcessRecord startProcessLocked(String processName,
3278            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3279            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3280            boolean isolated, boolean keepIfLarge) {
3281        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3282                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3283                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3284                null /* crashHandler */);
3285    }
3286
3287    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3288            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3289            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3290            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3291        long startTime = SystemClock.elapsedRealtime();
3292        ProcessRecord app;
3293        if (!isolated) {
3294            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3295            checkTime(startTime, "startProcess: after getProcessRecord");
3296
3297            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3298                // If we are in the background, then check to see if this process
3299                // is bad.  If so, we will just silently fail.
3300                if (mAppErrors.isBadProcessLocked(info)) {
3301                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3302                            + "/" + info.processName);
3303                    return null;
3304                }
3305            } else {
3306                // When the user is explicitly starting a process, then clear its
3307                // crash count so that we won't make it bad until they see at
3308                // least one crash dialog again, and make the process good again
3309                // if it had been bad.
3310                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3311                        + "/" + info.processName);
3312                mAppErrors.resetProcessCrashTimeLocked(info);
3313                if (mAppErrors.isBadProcessLocked(info)) {
3314                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3315                            UserHandle.getUserId(info.uid), info.uid,
3316                            info.processName);
3317                    mAppErrors.clearBadProcessLocked(info);
3318                    if (app != null) {
3319                        app.bad = false;
3320                    }
3321                }
3322            }
3323        } else {
3324            // If this is an isolated process, it can't re-use an existing process.
3325            app = null;
3326        }
3327
3328        // app launch boost for big.little configurations
3329        // use cpusets to migrate freshly launched tasks to big cores
3330        synchronized(ActivityManagerService.this) {
3331            nativeMigrateToBoost();
3332            mIsBoosted = true;
3333            mBoostStartTime = SystemClock.uptimeMillis();
3334            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3335            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3336        }
3337
3338        // We don't have to do anything more if:
3339        // (1) There is an existing application record; and
3340        // (2) The caller doesn't think it is dead, OR there is no thread
3341        //     object attached to it so we know it couldn't have crashed; and
3342        // (3) There is a pid assigned to it, so it is either starting or
3343        //     already running.
3344        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3345                + " app=" + app + " knownToBeDead=" + knownToBeDead
3346                + " thread=" + (app != null ? app.thread : null)
3347                + " pid=" + (app != null ? app.pid : -1));
3348        if (app != null && app.pid > 0) {
3349            if (!knownToBeDead || app.thread == null) {
3350                // We already have the app running, or are waiting for it to
3351                // come up (we have a pid but not yet its thread), so keep it.
3352                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3353                // If this is a new package in the process, add the package to the list
3354                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3355                checkTime(startTime, "startProcess: done, added package to proc");
3356                return app;
3357            }
3358
3359            // An application record is attached to a previous process,
3360            // clean it up now.
3361            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3362            checkTime(startTime, "startProcess: bad proc running, killing");
3363            killProcessGroup(app.info.uid, app.pid);
3364            handleAppDiedLocked(app, true, true);
3365            checkTime(startTime, "startProcess: done killing old proc");
3366        }
3367
3368        String hostingNameStr = hostingName != null
3369                ? hostingName.flattenToShortString() : null;
3370
3371        if (app == null) {
3372            checkTime(startTime, "startProcess: creating new process record");
3373            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3374            if (app == null) {
3375                Slog.w(TAG, "Failed making new process record for "
3376                        + processName + "/" + info.uid + " isolated=" + isolated);
3377                return null;
3378            }
3379            app.crashHandler = crashHandler;
3380            checkTime(startTime, "startProcess: done creating new process record");
3381        } else {
3382            // If this is a new package in the process, add the package to the list
3383            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3384            checkTime(startTime, "startProcess: added package to existing proc");
3385        }
3386
3387        // If the system is not ready yet, then hold off on starting this
3388        // process until it is.
3389        if (!mProcessesReady
3390                && !isAllowedWhileBooting(info)
3391                && !allowWhileBooting) {
3392            if (!mProcessesOnHold.contains(app)) {
3393                mProcessesOnHold.add(app);
3394            }
3395            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3396                    "System not ready, putting on hold: " + app);
3397            checkTime(startTime, "startProcess: returning with proc on hold");
3398            return app;
3399        }
3400
3401        checkTime(startTime, "startProcess: stepping in to startProcess");
3402        startProcessLocked(
3403                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3404        checkTime(startTime, "startProcess: done starting proc!");
3405        return (app.pid != 0) ? app : null;
3406    }
3407
3408    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3409        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3410    }
3411
3412    private final void startProcessLocked(ProcessRecord app,
3413            String hostingType, String hostingNameStr) {
3414        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3415                null /* entryPoint */, null /* entryPointArgs */);
3416    }
3417
3418    private final void startProcessLocked(ProcessRecord app, String hostingType,
3419            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3420        long startTime = SystemClock.elapsedRealtime();
3421        if (app.pid > 0 && app.pid != MY_PID) {
3422            checkTime(startTime, "startProcess: removing from pids map");
3423            synchronized (mPidsSelfLocked) {
3424                mPidsSelfLocked.remove(app.pid);
3425                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3426            }
3427            checkTime(startTime, "startProcess: done removing from pids map");
3428            app.setPid(0);
3429        }
3430
3431        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3432                "startProcessLocked removing on hold: " + app);
3433        mProcessesOnHold.remove(app);
3434
3435        checkTime(startTime, "startProcess: starting to update cpu stats");
3436        updateCpuStats();
3437        checkTime(startTime, "startProcess: done updating cpu stats");
3438
3439        try {
3440            try {
3441                final int userId = UserHandle.getUserId(app.uid);
3442                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3443            } catch (RemoteException e) {
3444                throw e.rethrowAsRuntimeException();
3445            }
3446
3447            int uid = app.uid;
3448            int[] gids = null;
3449            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3450            if (!app.isolated) {
3451                int[] permGids = null;
3452                try {
3453                    checkTime(startTime, "startProcess: getting gids from package manager");
3454                    final IPackageManager pm = AppGlobals.getPackageManager();
3455                    permGids = pm.getPackageGids(app.info.packageName,
3456                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3457                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3458                            MountServiceInternal.class);
3459                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3460                            app.info.packageName);
3461                } catch (RemoteException e) {
3462                    throw e.rethrowAsRuntimeException();
3463                }
3464
3465                /*
3466                 * Add shared application and profile GIDs so applications can share some
3467                 * resources like shared libraries and access user-wide resources
3468                 */
3469                if (ArrayUtils.isEmpty(permGids)) {
3470                    gids = new int[2];
3471                } else {
3472                    gids = new int[permGids.length + 2];
3473                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3474                }
3475                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3476                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3477            }
3478            checkTime(startTime, "startProcess: building args");
3479            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3480                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3481                        && mTopComponent != null
3482                        && app.processName.equals(mTopComponent.getPackageName())) {
3483                    uid = 0;
3484                }
3485                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3486                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3487                    uid = 0;
3488                }
3489            }
3490            int debugFlags = 0;
3491            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3492                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3493                // Also turn on CheckJNI for debuggable apps. It's quite
3494                // awkward to turn on otherwise.
3495                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3496            }
3497            // Run the app in safe mode if its manifest requests so or the
3498            // system is booted in safe mode.
3499            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3500                mSafeMode == true) {
3501                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3502            }
3503            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3504                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3505            }
3506            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3507            if ("true".equals(genDebugInfoProperty)) {
3508                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3509            }
3510            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3511                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3512            }
3513            if ("1".equals(SystemProperties.get("debug.assert"))) {
3514                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3515            }
3516            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3517                // Enable all debug flags required by the native debugger.
3518                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3519                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3520                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3521                mNativeDebuggingApp = null;
3522            }
3523
3524            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3525            if (requiredAbi == null) {
3526                requiredAbi = Build.SUPPORTED_ABIS[0];
3527            }
3528
3529            String instructionSet = null;
3530            if (app.info.primaryCpuAbi != null) {
3531                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3532            }
3533
3534            app.gids = gids;
3535            app.requiredAbi = requiredAbi;
3536            app.instructionSet = instructionSet;
3537
3538            // Start the process.  It will either succeed and return a result containing
3539            // the PID of the new process, or else throw a RuntimeException.
3540            boolean isActivityProcess = (entryPoint == null);
3541            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3542            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3543                    app.processName);
3544            checkTime(startTime, "startProcess: asking zygote to start proc");
3545            Process.ProcessStartResult startResult = Process.start(entryPoint,
3546                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3547                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3548                    app.info.dataDir, entryPointArgs);
3549            checkTime(startTime, "startProcess: returned from zygote!");
3550            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3551
3552            if (app.isolated) {
3553                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3554            }
3555            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3556            checkTime(startTime, "startProcess: done updating battery stats");
3557
3558            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3559                    UserHandle.getUserId(uid), startResult.pid, uid,
3560                    app.processName, hostingType,
3561                    hostingNameStr != null ? hostingNameStr : "");
3562
3563            mProcessStartLogger.logIfNeededLocked(app, startResult);
3564
3565            if (app.persistent) {
3566                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3567            }
3568
3569            if (DEBUG_PROCESSES) {
3570                checkTime(startTime, "startProcess: building log message");
3571                StringBuilder buf = mStringBuilder;
3572                buf.setLength(0);
3573                buf.append("Start proc ");
3574                buf.append(startResult.pid);
3575                buf.append(':');
3576                buf.append(app.processName);
3577                buf.append('/');
3578                UserHandle.formatUid(buf, uid);
3579                if (!isActivityProcess) {
3580                    buf.append(" [");
3581                    buf.append(entryPoint);
3582                    buf.append("]");
3583                }
3584                buf.append(" for ");
3585                buf.append(hostingType);
3586                if (hostingNameStr != null) {
3587                    buf.append(" ");
3588                    buf.append(hostingNameStr);
3589                }
3590                Slog.i(TAG, buf.toString());
3591            }
3592            app.setPid(startResult.pid);
3593            app.usingWrapper = startResult.usingWrapper;
3594            app.removed = false;
3595            app.killed = false;
3596            app.killedByAm = false;
3597            checkTime(startTime, "startProcess: starting to update pids map");
3598            synchronized (mPidsSelfLocked) {
3599                this.mPidsSelfLocked.put(startResult.pid, app);
3600                if (isActivityProcess) {
3601                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3602                    msg.obj = app;
3603                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3604                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3605                }
3606            }
3607            checkTime(startTime, "startProcess: done updating pids map");
3608        } catch (RuntimeException e) {
3609            // XXX do better error recovery.
3610            app.setPid(0);
3611            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3612            if (app.isolated) {
3613                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3614            }
3615            Slog.e(TAG, "Failure starting process " + app.processName, e);
3616        }
3617    }
3618
3619    void updateUsageStats(ActivityRecord component, boolean resumed) {
3620        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3621                "updateUsageStats: comp=" + component + "res=" + resumed);
3622        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3623        if (resumed) {
3624            if (mUsageStatsService != null) {
3625                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3626                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3627            }
3628            synchronized (stats) {
3629                stats.noteActivityResumedLocked(component.app.uid);
3630            }
3631        } else {
3632            if (mUsageStatsService != null) {
3633                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3634                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3635            }
3636            synchronized (stats) {
3637                stats.noteActivityPausedLocked(component.app.uid);
3638            }
3639        }
3640    }
3641
3642    Intent getHomeIntent() {
3643        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3644        intent.setComponent(mTopComponent);
3645        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3646        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3647            intent.addCategory(Intent.CATEGORY_HOME);
3648        }
3649        return intent;
3650    }
3651
3652    boolean startHomeActivityLocked(int userId, String reason) {
3653        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3654                && mTopAction == null) {
3655            // We are running in factory test mode, but unable to find
3656            // the factory test app, so just sit around displaying the
3657            // error message and don't try to start anything.
3658            return false;
3659        }
3660        Intent intent = getHomeIntent();
3661        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3662        if (aInfo != null) {
3663            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3664            // Don't do this if the home app is currently being
3665            // instrumented.
3666            aInfo = new ActivityInfo(aInfo);
3667            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3668            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3669                    aInfo.applicationInfo.uid, true);
3670            if (app == null || app.instrumentationClass == null) {
3671                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3672                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3673            }
3674        }
3675
3676        return true;
3677    }
3678
3679    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3680        ActivityInfo ai = null;
3681        ComponentName comp = intent.getComponent();
3682        try {
3683            if (comp != null) {
3684                // Factory test.
3685                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3686            } else {
3687                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3688                        intent,
3689                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3690                        flags, userId);
3691
3692                if (info != null) {
3693                    ai = info.activityInfo;
3694                }
3695            }
3696        } catch (RemoteException e) {
3697            // ignore
3698        }
3699
3700        return ai;
3701    }
3702
3703    /**
3704     * Starts the "new version setup screen" if appropriate.
3705     */
3706    void startSetupActivityLocked() {
3707        // Only do this once per boot.
3708        if (mCheckedForSetup) {
3709            return;
3710        }
3711
3712        // We will show this screen if the current one is a different
3713        // version than the last one shown, and we are not running in
3714        // low-level factory test mode.
3715        final ContentResolver resolver = mContext.getContentResolver();
3716        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3717                Settings.Global.getInt(resolver,
3718                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3719            mCheckedForSetup = true;
3720
3721            // See if we should be showing the platform update setup UI.
3722            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3723            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3724                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3725            if (!ris.isEmpty()) {
3726                final ResolveInfo ri = ris.get(0);
3727                String vers = ri.activityInfo.metaData != null
3728                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3729                        : null;
3730                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3731                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3732                            Intent.METADATA_SETUP_VERSION);
3733                }
3734                String lastVers = Settings.Secure.getString(
3735                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3736                if (vers != null && !vers.equals(lastVers)) {
3737                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3738                    intent.setComponent(new ComponentName(
3739                            ri.activityInfo.packageName, ri.activityInfo.name));
3740                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3741                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3742                            null, 0, 0, 0, null, false, false, null, null, null);
3743                }
3744            }
3745        }
3746    }
3747
3748    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3749        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3750    }
3751
3752    void enforceNotIsolatedCaller(String caller) {
3753        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3754            throw new SecurityException("Isolated process not allowed to call " + caller);
3755        }
3756    }
3757
3758    void enforceShellRestriction(String restriction, int userHandle) {
3759        if (Binder.getCallingUid() == Process.SHELL_UID) {
3760            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3761                throw new SecurityException("Shell does not have permission to access user "
3762                        + userHandle);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public int getFrontActivityScreenCompatMode() {
3769        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3770        synchronized (this) {
3771            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3772        }
3773    }
3774
3775    @Override
3776    public void setFrontActivityScreenCompatMode(int mode) {
3777        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3778                "setFrontActivityScreenCompatMode");
3779        synchronized (this) {
3780            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3781        }
3782    }
3783
3784    @Override
3785    public int getPackageScreenCompatMode(String packageName) {
3786        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3787        synchronized (this) {
3788            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3789        }
3790    }
3791
3792    @Override
3793    public void setPackageScreenCompatMode(String packageName, int mode) {
3794        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3795                "setPackageScreenCompatMode");
3796        synchronized (this) {
3797            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3798        }
3799    }
3800
3801    @Override
3802    public boolean getPackageAskScreenCompat(String packageName) {
3803        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3804        synchronized (this) {
3805            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3806        }
3807    }
3808
3809    @Override
3810    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3811        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3812                "setPackageAskScreenCompat");
3813        synchronized (this) {
3814            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3815        }
3816    }
3817
3818    private boolean hasUsageStatsPermission(String callingPackage) {
3819        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3820                Binder.getCallingUid(), callingPackage);
3821        if (mode == AppOpsManager.MODE_DEFAULT) {
3822            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3823                    == PackageManager.PERMISSION_GRANTED;
3824        }
3825        return mode == AppOpsManager.MODE_ALLOWED;
3826    }
3827
3828    @Override
3829    public int getPackageProcessState(String packageName, String callingPackage) {
3830        if (!hasUsageStatsPermission(callingPackage)) {
3831            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3832                    "getPackageProcessState");
3833        }
3834
3835        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3836        synchronized (this) {
3837            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3838                final ProcessRecord proc = mLruProcesses.get(i);
3839                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3840                        || procState > proc.setProcState) {
3841                    boolean found = false;
3842                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3843                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3844                            procState = proc.setProcState;
3845                            found = true;
3846                        }
3847                    }
3848                    if (proc.pkgDeps != null && !found) {
3849                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3850                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3851                                procState = proc.setProcState;
3852                                break;
3853                            }
3854                        }
3855                    }
3856                }
3857            }
3858        }
3859        return procState;
3860    }
3861
3862    @Override
3863    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3864        synchronized (this) {
3865            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3866            if (app == null) {
3867                return false;
3868            }
3869            if (app.trimMemoryLevel < level && app.thread != null &&
3870                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3871                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3872                try {
3873                    app.thread.scheduleTrimMemory(level);
3874                    app.trimMemoryLevel = level;
3875                    return true;
3876                } catch (RemoteException e) {
3877                    // Fallthrough to failure case.
3878                }
3879            }
3880        }
3881        return false;
3882    }
3883
3884    private void dispatchProcessesChanged() {
3885        int N;
3886        synchronized (this) {
3887            N = mPendingProcessChanges.size();
3888            if (mActiveProcessChanges.length < N) {
3889                mActiveProcessChanges = new ProcessChangeItem[N];
3890            }
3891            mPendingProcessChanges.toArray(mActiveProcessChanges);
3892            mPendingProcessChanges.clear();
3893            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3894                    "*** Delivering " + N + " process changes");
3895        }
3896
3897        int i = mProcessObservers.beginBroadcast();
3898        while (i > 0) {
3899            i--;
3900            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3901            if (observer != null) {
3902                try {
3903                    for (int j=0; j<N; j++) {
3904                        ProcessChangeItem item = mActiveProcessChanges[j];
3905                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3906                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3907                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3908                                    + item.uid + ": " + item.foregroundActivities);
3909                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3910                                    item.foregroundActivities);
3911                        }
3912                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3913                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3914                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3915                                    + ": " + item.processState);
3916                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3917                        }
3918                    }
3919                } catch (RemoteException e) {
3920                }
3921            }
3922        }
3923        mProcessObservers.finishBroadcast();
3924
3925        synchronized (this) {
3926            for (int j=0; j<N; j++) {
3927                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3928            }
3929        }
3930    }
3931
3932    private void dispatchProcessDied(int pid, int uid) {
3933        int i = mProcessObservers.beginBroadcast();
3934        while (i > 0) {
3935            i--;
3936            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3937            if (observer != null) {
3938                try {
3939                    observer.onProcessDied(pid, uid);
3940                } catch (RemoteException e) {
3941                }
3942            }
3943        }
3944        mProcessObservers.finishBroadcast();
3945    }
3946
3947    private void dispatchUidsChanged() {
3948        int N;
3949        synchronized (this) {
3950            N = mPendingUidChanges.size();
3951            if (mActiveUidChanges.length < N) {
3952                mActiveUidChanges = new UidRecord.ChangeItem[N];
3953            }
3954            for (int i=0; i<N; i++) {
3955                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3956                mActiveUidChanges[i] = change;
3957                if (change.uidRecord != null) {
3958                    change.uidRecord.pendingChange = null;
3959                    change.uidRecord = null;
3960                }
3961            }
3962            mPendingUidChanges.clear();
3963            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3964                    "*** Delivering " + N + " uid changes");
3965        }
3966
3967        if (mLocalPowerManager != null) {
3968            for (int j=0; j<N; j++) {
3969                UidRecord.ChangeItem item = mActiveUidChanges[j];
3970                if (item.change == UidRecord.CHANGE_GONE
3971                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3972                    mLocalPowerManager.uidGone(item.uid);
3973                } else {
3974                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3975                }
3976            }
3977        }
3978
3979        int i = mUidObservers.beginBroadcast();
3980        while (i > 0) {
3981            i--;
3982            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3983            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3984            if (observer != null) {
3985                try {
3986                    for (int j=0; j<N; j++) {
3987                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3988                        final int change = item.change;
3989                        UidRecord validateUid = null;
3990                        if (VALIDATE_UID_STATES && i == 0) {
3991                            validateUid = mValidateUids.get(item.uid);
3992                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3993                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3994                                validateUid = new UidRecord(item.uid);
3995                                mValidateUids.put(item.uid, validateUid);
3996                            }
3997                        }
3998                        if (change == UidRecord.CHANGE_IDLE
3999                                || change == UidRecord.CHANGE_GONE_IDLE) {
4000                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4001                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4002                                        "UID idle uid=" + item.uid);
4003                                observer.onUidIdle(item.uid);
4004                            }
4005                            if (VALIDATE_UID_STATES && i == 0) {
4006                                if (validateUid != null) {
4007                                    validateUid.idle = true;
4008                                }
4009                            }
4010                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4011                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4012                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4013                                        "UID active uid=" + item.uid);
4014                                observer.onUidActive(item.uid);
4015                            }
4016                            if (VALIDATE_UID_STATES && i == 0) {
4017                                validateUid.idle = false;
4018                            }
4019                        }
4020                        if (change == UidRecord.CHANGE_GONE
4021                                || change == UidRecord.CHANGE_GONE_IDLE) {
4022                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4023                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4024                                        "UID gone uid=" + item.uid);
4025                                observer.onUidGone(item.uid);
4026                            }
4027                            if (VALIDATE_UID_STATES && i == 0) {
4028                                if (validateUid != null) {
4029                                    mValidateUids.remove(item.uid);
4030                                }
4031                            }
4032                        } else {
4033                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4034                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4035                                        "UID CHANGED uid=" + item.uid
4036                                                + ": " + item.processState);
4037                                observer.onUidStateChanged(item.uid, item.processState);
4038                            }
4039                            if (VALIDATE_UID_STATES && i == 0) {
4040                                validateUid.curProcState = validateUid.setProcState
4041                                        = item.processState;
4042                            }
4043                        }
4044                    }
4045                } catch (RemoteException e) {
4046                }
4047            }
4048        }
4049        mUidObservers.finishBroadcast();
4050
4051        synchronized (this) {
4052            for (int j=0; j<N; j++) {
4053                mAvailUidChanges.add(mActiveUidChanges[j]);
4054            }
4055        }
4056    }
4057
4058    @Override
4059    public final int startActivity(IApplicationThread caller, String callingPackage,
4060            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4061            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4062        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4063                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4064                UserHandle.getCallingUserId());
4065    }
4066
4067    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4068        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4069        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4070                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4071                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4072
4073        // TODO: Switch to user app stacks here.
4074        String mimeType = intent.getType();
4075        final Uri data = intent.getData();
4076        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4077            mimeType = getProviderMimeType(data, userId);
4078        }
4079        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4080
4081        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4082        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4083                null, 0, 0, null, null, null, null, false, userId, container, null);
4084    }
4085
4086    @Override
4087    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4088            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4089            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4090        enforceNotIsolatedCaller("startActivity");
4091        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4092                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4093        // TODO: Switch to user app stacks here.
4094        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4095                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4096                profilerInfo, null, null, bOptions, false, userId, null, null);
4097    }
4098
4099    @Override
4100    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4101            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4102            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4103            int userId) {
4104
4105        // This is very dangerous -- it allows you to perform a start activity (including
4106        // permission grants) as any app that may launch one of your own activities.  So
4107        // we will only allow this to be done from activities that are part of the core framework,
4108        // and then only when they are running as the system.
4109        final ActivityRecord sourceRecord;
4110        final int targetUid;
4111        final String targetPackage;
4112        synchronized (this) {
4113            if (resultTo == null) {
4114                throw new SecurityException("Must be called from an activity");
4115            }
4116            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4117            if (sourceRecord == null) {
4118                throw new SecurityException("Called with bad activity token: " + resultTo);
4119            }
4120            if (!sourceRecord.info.packageName.equals("android")) {
4121                throw new SecurityException(
4122                        "Must be called from an activity that is declared in the android package");
4123            }
4124            if (sourceRecord.app == null) {
4125                throw new SecurityException("Called without a process attached to activity");
4126            }
4127            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4128                // This is still okay, as long as this activity is running under the
4129                // uid of the original calling activity.
4130                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4131                    throw new SecurityException(
4132                            "Calling activity in uid " + sourceRecord.app.uid
4133                                    + " must be system uid or original calling uid "
4134                                    + sourceRecord.launchedFromUid);
4135                }
4136            }
4137            if (ignoreTargetSecurity) {
4138                if (intent.getComponent() == null) {
4139                    throw new SecurityException(
4140                            "Component must be specified with ignoreTargetSecurity");
4141                }
4142                if (intent.getSelector() != null) {
4143                    throw new SecurityException(
4144                            "Selector not allowed with ignoreTargetSecurity");
4145                }
4146            }
4147            targetUid = sourceRecord.launchedFromUid;
4148            targetPackage = sourceRecord.launchedFromPackage;
4149        }
4150
4151        if (userId == UserHandle.USER_NULL) {
4152            userId = UserHandle.getUserId(sourceRecord.app.uid);
4153        }
4154
4155        // TODO: Switch to user app stacks here.
4156        try {
4157            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4158                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4159                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4160            return ret;
4161        } catch (SecurityException e) {
4162            // XXX need to figure out how to propagate to original app.
4163            // A SecurityException here is generally actually a fault of the original
4164            // calling activity (such as a fairly granting permissions), so propagate it
4165            // back to them.
4166            /*
4167            StringBuilder msg = new StringBuilder();
4168            msg.append("While launching");
4169            msg.append(intent.toString());
4170            msg.append(": ");
4171            msg.append(e.getMessage());
4172            */
4173            throw e;
4174        }
4175    }
4176
4177    @Override
4178    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4179            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4180            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4181        enforceNotIsolatedCaller("startActivityAndWait");
4182        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4183                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4184        WaitResult res = new WaitResult();
4185        // TODO: Switch to user app stacks here.
4186        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4187                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4188                bOptions, false, userId, null, null);
4189        return res;
4190    }
4191
4192    @Override
4193    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, Configuration config, Bundle bOptions, int userId) {
4196        enforceNotIsolatedCaller("startActivityWithConfig");
4197        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4198                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4199        // TODO: Switch to user app stacks here.
4200        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4201                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4202                null, null, config, bOptions, false, userId, null, null);
4203        return ret;
4204    }
4205
4206    @Override
4207    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4208            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4209            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4210            throws TransactionTooLargeException {
4211        enforceNotIsolatedCaller("startActivityIntentSender");
4212        // Refuse possible leaked file descriptors
4213        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4214            throw new IllegalArgumentException("File descriptors passed in Intent");
4215        }
4216
4217        IIntentSender sender = intent.getTarget();
4218        if (!(sender instanceof PendingIntentRecord)) {
4219            throw new IllegalArgumentException("Bad PendingIntent object");
4220        }
4221
4222        PendingIntentRecord pir = (PendingIntentRecord)sender;
4223
4224        synchronized (this) {
4225            // If this is coming from the currently resumed activity, it is
4226            // effectively saying that app switches are allowed at this point.
4227            final ActivityStack stack = getFocusedStack();
4228            if (stack.mResumedActivity != null &&
4229                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4230                mAppSwitchesAllowedTime = 0;
4231            }
4232        }
4233        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4234                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4235        return ret;
4236    }
4237
4238    @Override
4239    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4240            Intent intent, String resolvedType, IVoiceInteractionSession session,
4241            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4242            Bundle bOptions, int userId) {
4243        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4244                != PackageManager.PERMISSION_GRANTED) {
4245            String msg = "Permission Denial: startVoiceActivity() from pid="
4246                    + Binder.getCallingPid()
4247                    + ", uid=" + Binder.getCallingUid()
4248                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4249            Slog.w(TAG, msg);
4250            throw new SecurityException(msg);
4251        }
4252        if (session == null || interactor == null) {
4253            throw new NullPointerException("null session or interactor");
4254        }
4255        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4256                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4257        // TODO: Switch to user app stacks here.
4258        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4259                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4260                null, bOptions, false, userId, null, null);
4261    }
4262
4263    @Override
4264    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4265            throws RemoteException {
4266        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4267        synchronized (this) {
4268            ActivityRecord activity = getFocusedStack().topActivity();
4269            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4270                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4271            }
4272            if (mRunningVoice != null || activity.task.voiceSession != null
4273                    || activity.voiceSession != null) {
4274                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4275                return;
4276            }
4277            if (activity.pendingVoiceInteractionStart) {
4278                Slog.w(TAG, "Pending start of voice interaction already.");
4279                return;
4280            }
4281            activity.pendingVoiceInteractionStart = true;
4282        }
4283        LocalServices.getService(VoiceInteractionManagerInternal.class)
4284                .startLocalVoiceInteraction(callingActivity, options);
4285    }
4286
4287    @Override
4288    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4289        LocalServices.getService(VoiceInteractionManagerInternal.class)
4290                .stopLocalVoiceInteraction(callingActivity);
4291    }
4292
4293    @Override
4294    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4295        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4296                .supportsLocalVoiceInteraction();
4297    }
4298
4299    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4300            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4301        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4302        if (activityToCallback == null) return;
4303        activityToCallback.setVoiceSessionLocked(voiceSession);
4304
4305        // Inform the activity
4306        try {
4307            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4308                    voiceInteractor);
4309            long token = Binder.clearCallingIdentity();
4310            try {
4311                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4312            } finally {
4313                Binder.restoreCallingIdentity(token);
4314            }
4315            // TODO: VI Should we cache the activity so that it's easier to find later
4316            // rather than scan through all the stacks and activities?
4317        } catch (RemoteException re) {
4318            activityToCallback.clearVoiceSessionLocked();
4319            // TODO: VI Should this terminate the voice session?
4320        }
4321    }
4322
4323    @Override
4324    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4325        synchronized (this) {
4326            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4327                if (keepAwake) {
4328                    mVoiceWakeLock.acquire();
4329                } else {
4330                    mVoiceWakeLock.release();
4331                }
4332            }
4333        }
4334    }
4335
4336    @Override
4337    public boolean startNextMatchingActivity(IBinder callingActivity,
4338            Intent intent, Bundle bOptions) {
4339        // Refuse possible leaked file descriptors
4340        if (intent != null && intent.hasFileDescriptors() == true) {
4341            throw new IllegalArgumentException("File descriptors passed in Intent");
4342        }
4343        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4344
4345        synchronized (this) {
4346            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4347            if (r == null) {
4348                ActivityOptions.abort(options);
4349                return false;
4350            }
4351            if (r.app == null || r.app.thread == null) {
4352                // The caller is not running...  d'oh!
4353                ActivityOptions.abort(options);
4354                return false;
4355            }
4356            intent = new Intent(intent);
4357            // The caller is not allowed to change the data.
4358            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4359            // And we are resetting to find the next component...
4360            intent.setComponent(null);
4361
4362            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4363
4364            ActivityInfo aInfo = null;
4365            try {
4366                List<ResolveInfo> resolves =
4367                    AppGlobals.getPackageManager().queryIntentActivities(
4368                            intent, r.resolvedType,
4369                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4370                            UserHandle.getCallingUserId());
4371
4372                // Look for the original activity in the list...
4373                final int N = resolves != null ? resolves.size() : 0;
4374                for (int i=0; i<N; i++) {
4375                    ResolveInfo rInfo = resolves.get(i);
4376                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4377                            && rInfo.activityInfo.name.equals(r.info.name)) {
4378                        // We found the current one...  the next matching is
4379                        // after it.
4380                        i++;
4381                        if (i<N) {
4382                            aInfo = resolves.get(i).activityInfo;
4383                        }
4384                        if (debug) {
4385                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4386                                    + "/" + r.info.name);
4387                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4388                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4389                        }
4390                        break;
4391                    }
4392                }
4393            } catch (RemoteException e) {
4394            }
4395
4396            if (aInfo == null) {
4397                // Nobody who is next!
4398                ActivityOptions.abort(options);
4399                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4400                return false;
4401            }
4402
4403            intent.setComponent(new ComponentName(
4404                    aInfo.applicationInfo.packageName, aInfo.name));
4405            intent.setFlags(intent.getFlags()&~(
4406                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4407                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4408                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4409                    Intent.FLAG_ACTIVITY_NEW_TASK));
4410
4411            // Okay now we need to start the new activity, replacing the
4412            // currently running activity.  This is a little tricky because
4413            // we want to start the new one as if the current one is finished,
4414            // but not finish the current one first so that there is no flicker.
4415            // And thus...
4416            final boolean wasFinishing = r.finishing;
4417            r.finishing = true;
4418
4419            // Propagate reply information over to the new activity.
4420            final ActivityRecord resultTo = r.resultTo;
4421            final String resultWho = r.resultWho;
4422            final int requestCode = r.requestCode;
4423            r.resultTo = null;
4424            if (resultTo != null) {
4425                resultTo.removeResultsLocked(r, resultWho, requestCode);
4426            }
4427
4428            final long origId = Binder.clearCallingIdentity();
4429            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4430                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4431                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4432                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4433                    false, false, null, null, null);
4434            Binder.restoreCallingIdentity(origId);
4435
4436            r.finishing = wasFinishing;
4437            if (res != ActivityManager.START_SUCCESS) {
4438                return false;
4439            }
4440            return true;
4441        }
4442    }
4443
4444    @Override
4445    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4446        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4447            String msg = "Permission Denial: startActivityFromRecents called without " +
4448                    START_TASKS_FROM_RECENTS;
4449            Slog.w(TAG, msg);
4450            throw new SecurityException(msg);
4451        }
4452        final long origId = Binder.clearCallingIdentity();
4453        try {
4454            return startActivityFromRecentsInner(taskId, bOptions);
4455        } finally {
4456            Binder.restoreCallingIdentity(origId);
4457        }
4458    }
4459
4460    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4461        final TaskRecord task;
4462        final int callingUid;
4463        final String callingPackage;
4464        final Intent intent;
4465        final int userId;
4466        synchronized (this) {
4467            final ActivityOptions activityOptions = (bOptions != null)
4468                    ? new ActivityOptions(bOptions) : null;
4469            final int launchStackId = (activityOptions != null)
4470                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4471
4472            if (launchStackId == HOME_STACK_ID) {
4473                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4474                        + taskId + " can't be launch in the home stack.");
4475            }
4476            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4477            if (task == null) {
4478                throw new IllegalArgumentException(
4479                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4480            }
4481
4482            if (launchStackId != INVALID_STACK_ID) {
4483                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4484                    mWindowManager.setDockedStackCreateState(
4485                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4486                }
4487                if (task.stack.mStackId != launchStackId) {
4488                    mStackSupervisor.moveTaskToStackLocked(
4489                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4490                            ANIMATE);
4491                }
4492            }
4493
4494            // If the user must confirm credentials (e.g. when first launching a work app and the
4495            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4496            if (!mUserController.shouldConfirmCredentials(task.userId)
4497                    && task.getRootActivity() != null) {
4498                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4499                return ActivityManager.START_TASK_TO_FRONT;
4500            }
4501            callingUid = task.mCallingUid;
4502            callingPackage = task.mCallingPackage;
4503            intent = task.intent;
4504            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4505            userId = task.userId;
4506        }
4507        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4508                bOptions, userId, null, task);
4509    }
4510
4511    final int startActivityInPackage(int uid, String callingPackage,
4512            Intent intent, String resolvedType, IBinder resultTo,
4513            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4514            IActivityContainer container, TaskRecord inTask) {
4515
4516        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4517                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4518
4519        // TODO: Switch to user app stacks here.
4520        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4521                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4522                null, null, null, bOptions, false, userId, container, inTask);
4523        return ret;
4524    }
4525
4526    @Override
4527    public final int startActivities(IApplicationThread caller, String callingPackage,
4528            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4529            int userId) {
4530        enforceNotIsolatedCaller("startActivities");
4531        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4532                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4533        // TODO: Switch to user app stacks here.
4534        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4535                resolvedTypes, resultTo, bOptions, userId);
4536        return ret;
4537    }
4538
4539    final int startActivitiesInPackage(int uid, String callingPackage,
4540            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4541            Bundle bOptions, int userId) {
4542
4543        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4544                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4545        // TODO: Switch to user app stacks here.
4546        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4547                resultTo, bOptions, userId);
4548        return ret;
4549    }
4550
4551    @Override
4552    public void reportActivityFullyDrawn(IBinder token) {
4553        synchronized (this) {
4554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4555            if (r == null) {
4556                return;
4557            }
4558            r.reportFullyDrawnLocked();
4559        }
4560    }
4561
4562    @Override
4563    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4564        synchronized (this) {
4565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4566            if (r == null) {
4567                return;
4568            }
4569            TaskRecord task = r.task;
4570            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4571                // Fixed screen orientation isn't supported when activities aren't in full screen
4572                // mode.
4573                return;
4574            }
4575            final long origId = Binder.clearCallingIdentity();
4576            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4577            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4578                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4579            if (config != null) {
4580                r.frozenBeforeDestroy = true;
4581                if (!updateConfigurationLocked(config, r, false)) {
4582                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4583                }
4584            }
4585            Binder.restoreCallingIdentity(origId);
4586        }
4587    }
4588
4589    @Override
4590    public int getRequestedOrientation(IBinder token) {
4591        synchronized (this) {
4592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4593            if (r == null) {
4594                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4595            }
4596            return mWindowManager.getAppOrientation(r.appToken);
4597        }
4598    }
4599
4600    /**
4601     * This is the internal entry point for handling Activity.finish().
4602     *
4603     * @param token The Binder token referencing the Activity we want to finish.
4604     * @param resultCode Result code, if any, from this Activity.
4605     * @param resultData Result data (Intent), if any, from this Activity.
4606     * @param finishTask Whether to finish the task associated with this Activity.
4607     *
4608     * @return Returns true if the activity successfully finished, or false if it is still running.
4609     */
4610    @Override
4611    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4612            int finishTask) {
4613        // Refuse possible leaked file descriptors
4614        if (resultData != null && resultData.hasFileDescriptors() == true) {
4615            throw new IllegalArgumentException("File descriptors passed in Intent");
4616        }
4617
4618        synchronized(this) {
4619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4620            if (r == null) {
4621                return true;
4622            }
4623            // Keep track of the root activity of the task before we finish it
4624            TaskRecord tr = r.task;
4625            ActivityRecord rootR = tr.getRootActivity();
4626            if (rootR == null) {
4627                Slog.w(TAG, "Finishing task with all activities already finished");
4628            }
4629            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4630            // finish.
4631            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4632                    mStackSupervisor.isLastLockedTask(tr)) {
4633                Slog.i(TAG, "Not finishing task in lock task mode");
4634                mStackSupervisor.showLockTaskToast();
4635                return false;
4636            }
4637            if (mController != null) {
4638                // Find the first activity that is not finishing.
4639                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4640                if (next != null) {
4641                    // ask watcher if this is allowed
4642                    boolean resumeOK = true;
4643                    try {
4644                        resumeOK = mController.activityResuming(next.packageName);
4645                    } catch (RemoteException e) {
4646                        mController = null;
4647                        Watchdog.getInstance().setActivityController(null);
4648                    }
4649
4650                    if (!resumeOK) {
4651                        Slog.i(TAG, "Not finishing activity because controller resumed");
4652                        return false;
4653                    }
4654                }
4655            }
4656            final long origId = Binder.clearCallingIdentity();
4657            try {
4658                boolean res;
4659                final boolean finishWithRootActivity =
4660                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4661                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4662                        || (finishWithRootActivity && r == rootR)) {
4663                    // If requested, remove the task that is associated to this activity only if it
4664                    // was the root activity in the task. The result code and data is ignored
4665                    // because we don't support returning them across task boundaries. Also, to
4666                    // keep backwards compatibility we remove the task from recents when finishing
4667                    // task with root activity.
4668                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4669                    if (!res) {
4670                        Slog.i(TAG, "Removing task failed to finish activity");
4671                    }
4672                } else {
4673                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4674                            resultData, "app-request", true);
4675                    if (!res) {
4676                        Slog.i(TAG, "Failed to finish by app-request");
4677                    }
4678                }
4679                return res;
4680            } finally {
4681                Binder.restoreCallingIdentity(origId);
4682            }
4683        }
4684    }
4685
4686    @Override
4687    public final void finishHeavyWeightApp() {
4688        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4689                != PackageManager.PERMISSION_GRANTED) {
4690            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4691                    + Binder.getCallingPid()
4692                    + ", uid=" + Binder.getCallingUid()
4693                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4694            Slog.w(TAG, msg);
4695            throw new SecurityException(msg);
4696        }
4697
4698        synchronized(this) {
4699            if (mHeavyWeightProcess == null) {
4700                return;
4701            }
4702
4703            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4704            for (int i = 0; i < activities.size(); i++) {
4705                ActivityRecord r = activities.get(i);
4706                if (!r.finishing && r.isInStackLocked()) {
4707                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4708                            null, "finish-heavy", true);
4709                }
4710            }
4711
4712            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4713                    mHeavyWeightProcess.userId, 0));
4714            mHeavyWeightProcess = null;
4715        }
4716    }
4717
4718    @Override
4719    public void crashApplication(int uid, int initialPid, String packageName,
4720            String message) {
4721        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4722                != PackageManager.PERMISSION_GRANTED) {
4723            String msg = "Permission Denial: crashApplication() from pid="
4724                    + Binder.getCallingPid()
4725                    + ", uid=" + Binder.getCallingUid()
4726                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4727            Slog.w(TAG, msg);
4728            throw new SecurityException(msg);
4729        }
4730
4731        synchronized(this) {
4732            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4733        }
4734    }
4735
4736    @Override
4737    public final void finishSubActivity(IBinder token, String resultWho,
4738            int requestCode) {
4739        synchronized(this) {
4740            final long origId = Binder.clearCallingIdentity();
4741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4742            if (r != null) {
4743                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4744            }
4745            Binder.restoreCallingIdentity(origId);
4746        }
4747    }
4748
4749    @Override
4750    public boolean finishActivityAffinity(IBinder token) {
4751        synchronized(this) {
4752            final long origId = Binder.clearCallingIdentity();
4753            try {
4754                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4755                if (r == null) {
4756                    return false;
4757                }
4758
4759                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4760                // can finish.
4761                final TaskRecord task = r.task;
4762                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4763                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4764                    mStackSupervisor.showLockTaskToast();
4765                    return false;
4766                }
4767                return task.stack.finishActivityAffinityLocked(r);
4768            } finally {
4769                Binder.restoreCallingIdentity(origId);
4770            }
4771        }
4772    }
4773
4774    @Override
4775    public void finishVoiceTask(IVoiceInteractionSession session) {
4776        synchronized (this) {
4777            final long origId = Binder.clearCallingIdentity();
4778            try {
4779                // TODO: VI Consider treating local voice interactions and voice tasks
4780                // differently here
4781                mStackSupervisor.finishVoiceTask(session);
4782            } finally {
4783                Binder.restoreCallingIdentity(origId);
4784            }
4785        }
4786
4787    }
4788
4789    @Override
4790    public boolean releaseActivityInstance(IBinder token) {
4791        synchronized(this) {
4792            final long origId = Binder.clearCallingIdentity();
4793            try {
4794                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4795                if (r == null) {
4796                    return false;
4797                }
4798                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4799            } finally {
4800                Binder.restoreCallingIdentity(origId);
4801            }
4802        }
4803    }
4804
4805    @Override
4806    public void releaseSomeActivities(IApplicationThread appInt) {
4807        synchronized(this) {
4808            final long origId = Binder.clearCallingIdentity();
4809            try {
4810                ProcessRecord app = getRecordForAppLocked(appInt);
4811                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4812            } finally {
4813                Binder.restoreCallingIdentity(origId);
4814            }
4815        }
4816    }
4817
4818    @Override
4819    public boolean willActivityBeVisible(IBinder token) {
4820        synchronized(this) {
4821            ActivityStack stack = ActivityRecord.getStackLocked(token);
4822            if (stack != null) {
4823                return stack.willActivityBeVisibleLocked(token);
4824            }
4825            return false;
4826        }
4827    }
4828
4829    @Override
4830    public void overridePendingTransition(IBinder token, String packageName,
4831            int enterAnim, int exitAnim) {
4832        synchronized(this) {
4833            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4834            if (self == null) {
4835                return;
4836            }
4837
4838            final long origId = Binder.clearCallingIdentity();
4839
4840            if (self.state == ActivityState.RESUMED
4841                    || self.state == ActivityState.PAUSING) {
4842                mWindowManager.overridePendingAppTransition(packageName,
4843                        enterAnim, exitAnim, null);
4844            }
4845
4846            Binder.restoreCallingIdentity(origId);
4847        }
4848    }
4849
4850    /**
4851     * Main function for removing an existing process from the activity manager
4852     * as a result of that process going away.  Clears out all connections
4853     * to the process.
4854     */
4855    private final void handleAppDiedLocked(ProcessRecord app,
4856            boolean restarting, boolean allowRestart) {
4857        int pid = app.pid;
4858        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4859        if (!kept && !restarting) {
4860            removeLruProcessLocked(app);
4861            if (pid > 0) {
4862                ProcessList.remove(pid);
4863            }
4864        }
4865
4866        if (mProfileProc == app) {
4867            clearProfilerLocked();
4868        }
4869
4870        // Remove this application's activities from active lists.
4871        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4872
4873        app.activities.clear();
4874
4875        if (app.instrumentationClass != null) {
4876            Slog.w(TAG, "Crash of app " + app.processName
4877                  + " running instrumentation " + app.instrumentationClass);
4878            Bundle info = new Bundle();
4879            info.putString("shortMsg", "Process crashed.");
4880            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4881        }
4882
4883        if (!restarting && hasVisibleActivities
4884                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4885            // If there was nothing to resume, and we are not already restarting this process, but
4886            // there is a visible activity that is hosted by the process...  then make sure all
4887            // visible activities are running, taking care of restarting this process.
4888            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4889        }
4890    }
4891
4892    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4893        IBinder threadBinder = thread.asBinder();
4894        // Find the application record.
4895        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4896            ProcessRecord rec = mLruProcesses.get(i);
4897            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4898                return i;
4899            }
4900        }
4901        return -1;
4902    }
4903
4904    final ProcessRecord getRecordForAppLocked(
4905            IApplicationThread thread) {
4906        if (thread == null) {
4907            return null;
4908        }
4909
4910        int appIndex = getLRURecordIndexForAppLocked(thread);
4911        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4912    }
4913
4914    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4915        // If there are no longer any background processes running,
4916        // and the app that died was not running instrumentation,
4917        // then tell everyone we are now low on memory.
4918        boolean haveBg = false;
4919        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4920            ProcessRecord rec = mLruProcesses.get(i);
4921            if (rec.thread != null
4922                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4923                haveBg = true;
4924                break;
4925            }
4926        }
4927
4928        if (!haveBg) {
4929            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4930            if (doReport) {
4931                long now = SystemClock.uptimeMillis();
4932                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4933                    doReport = false;
4934                } else {
4935                    mLastMemUsageReportTime = now;
4936                }
4937            }
4938            final ArrayList<ProcessMemInfo> memInfos
4939                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4940            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4941            long now = SystemClock.uptimeMillis();
4942            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4943                ProcessRecord rec = mLruProcesses.get(i);
4944                if (rec == dyingProc || rec.thread == null) {
4945                    continue;
4946                }
4947                if (doReport) {
4948                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4949                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4950                }
4951                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4952                    // The low memory report is overriding any current
4953                    // state for a GC request.  Make sure to do
4954                    // heavy/important/visible/foreground processes first.
4955                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4956                        rec.lastRequestedGc = 0;
4957                    } else {
4958                        rec.lastRequestedGc = rec.lastLowMemory;
4959                    }
4960                    rec.reportLowMemory = true;
4961                    rec.lastLowMemory = now;
4962                    mProcessesToGc.remove(rec);
4963                    addProcessToGcListLocked(rec);
4964                }
4965            }
4966            if (doReport) {
4967                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4968                mHandler.sendMessage(msg);
4969            }
4970            scheduleAppGcsLocked();
4971        }
4972    }
4973
4974    final void appDiedLocked(ProcessRecord app) {
4975       appDiedLocked(app, app.pid, app.thread, false);
4976    }
4977
4978    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4979            boolean fromBinderDied) {
4980        // First check if this ProcessRecord is actually active for the pid.
4981        synchronized (mPidsSelfLocked) {
4982            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4983            if (curProc != app) {
4984                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4985                return;
4986            }
4987        }
4988
4989        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4990        synchronized (stats) {
4991            stats.noteProcessDiedLocked(app.info.uid, pid);
4992        }
4993
4994        if (!app.killed) {
4995            if (!fromBinderDied) {
4996                Process.killProcessQuiet(pid);
4997            }
4998            killProcessGroup(app.info.uid, pid);
4999            app.killed = true;
5000        }
5001
5002        // Clean up already done if the process has been re-started.
5003        if (app.pid == pid && app.thread != null &&
5004                app.thread.asBinder() == thread.asBinder()) {
5005            boolean doLowMem = app.instrumentationClass == null;
5006            boolean doOomAdj = doLowMem;
5007            if (!app.killedByAm) {
5008                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5009                        + ") has died");
5010                mAllowLowerMemLevel = true;
5011            } else {
5012                // Note that we always want to do oom adj to update our state with the
5013                // new number of procs.
5014                mAllowLowerMemLevel = false;
5015                doLowMem = false;
5016            }
5017            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5018            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5019                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5020            handleAppDiedLocked(app, false, true);
5021
5022            if (doOomAdj) {
5023                updateOomAdjLocked();
5024            }
5025            if (doLowMem) {
5026                doLowMemReportIfNeededLocked(app);
5027            }
5028        } else if (app.pid != pid) {
5029            // A new process has already been started.
5030            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5031                    + ") has died and restarted (pid " + app.pid + ").");
5032            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5033        } else if (DEBUG_PROCESSES) {
5034            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5035                    + thread.asBinder());
5036        }
5037    }
5038
5039    /**
5040     * If a stack trace dump file is configured, dump process stack traces.
5041     * @param clearTraces causes the dump file to be erased prior to the new
5042     *    traces being written, if true; when false, the new traces will be
5043     *    appended to any existing file content.
5044     * @param firstPids of dalvik VM processes to dump stack traces for first
5045     * @param lastPids of dalvik VM processes to dump stack traces for last
5046     * @param nativeProcs optional list of native process names to dump stack crawls
5047     * @return file containing stack traces, or null if no dump file is configured
5048     */
5049    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5050            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5051        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5052        if (tracesPath == null || tracesPath.length() == 0) {
5053            return null;
5054        }
5055
5056        File tracesFile = new File(tracesPath);
5057        try {
5058            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5059            tracesFile.createNewFile();
5060            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5061        } catch (IOException e) {
5062            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5063            return null;
5064        }
5065
5066        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5067        return tracesFile;
5068    }
5069
5070    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5071            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5072        // Use a FileObserver to detect when traces finish writing.
5073        // The order of traces is considered important to maintain for legibility.
5074        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5075            @Override
5076            public synchronized void onEvent(int event, String path) { notify(); }
5077        };
5078
5079        try {
5080            observer.startWatching();
5081
5082            // First collect all of the stacks of the most important pids.
5083            if (firstPids != null) {
5084                try {
5085                    int num = firstPids.size();
5086                    for (int i = 0; i < num; i++) {
5087                        synchronized (observer) {
5088                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5089                            observer.wait(200);  // Wait for write-close, give up after 200msec
5090                        }
5091                    }
5092                } catch (InterruptedException e) {
5093                    Slog.wtf(TAG, e);
5094                }
5095            }
5096
5097            // Next collect the stacks of the native pids
5098            if (nativeProcs != null) {
5099                int[] pids = Process.getPidsForCommands(nativeProcs);
5100                if (pids != null) {
5101                    for (int pid : pids) {
5102                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5103                    }
5104                }
5105            }
5106
5107            // Lastly, measure CPU usage.
5108            if (processCpuTracker != null) {
5109                processCpuTracker.init();
5110                System.gc();
5111                processCpuTracker.update();
5112                try {
5113                    synchronized (processCpuTracker) {
5114                        processCpuTracker.wait(500); // measure over 1/2 second.
5115                    }
5116                } catch (InterruptedException e) {
5117                }
5118                processCpuTracker.update();
5119
5120                // We'll take the stack crawls of just the top apps using CPU.
5121                final int N = processCpuTracker.countWorkingStats();
5122                int numProcs = 0;
5123                for (int i=0; i<N && numProcs<5; i++) {
5124                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5125                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5126                        numProcs++;
5127                        try {
5128                            synchronized (observer) {
5129                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5130                                observer.wait(200);  // Wait for write-close, give up after 200msec
5131                            }
5132                        } catch (InterruptedException e) {
5133                            Slog.wtf(TAG, e);
5134                        }
5135
5136                    }
5137                }
5138            }
5139        } finally {
5140            observer.stopWatching();
5141        }
5142    }
5143
5144    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5145        if (true || IS_USER_BUILD) {
5146            return;
5147        }
5148        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5149        if (tracesPath == null || tracesPath.length() == 0) {
5150            return;
5151        }
5152
5153        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5154        StrictMode.allowThreadDiskWrites();
5155        try {
5156            final File tracesFile = new File(tracesPath);
5157            final File tracesDir = tracesFile.getParentFile();
5158            final File tracesTmp = new File(tracesDir, "__tmp__");
5159            try {
5160                if (tracesFile.exists()) {
5161                    tracesTmp.delete();
5162                    tracesFile.renameTo(tracesTmp);
5163                }
5164                StringBuilder sb = new StringBuilder();
5165                Time tobj = new Time();
5166                tobj.set(System.currentTimeMillis());
5167                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5168                sb.append(": ");
5169                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5170                sb.append(" since ");
5171                sb.append(msg);
5172                FileOutputStream fos = new FileOutputStream(tracesFile);
5173                fos.write(sb.toString().getBytes());
5174                if (app == null) {
5175                    fos.write("\n*** No application process!".getBytes());
5176                }
5177                fos.close();
5178                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5179            } catch (IOException e) {
5180                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5181                return;
5182            }
5183
5184            if (app != null) {
5185                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5186                firstPids.add(app.pid);
5187                dumpStackTraces(tracesPath, firstPids, null, null, null);
5188            }
5189
5190            File lastTracesFile = null;
5191            File curTracesFile = null;
5192            for (int i=9; i>=0; i--) {
5193                String name = String.format(Locale.US, "slow%02d.txt", i);
5194                curTracesFile = new File(tracesDir, name);
5195                if (curTracesFile.exists()) {
5196                    if (lastTracesFile != null) {
5197                        curTracesFile.renameTo(lastTracesFile);
5198                    } else {
5199                        curTracesFile.delete();
5200                    }
5201                }
5202                lastTracesFile = curTracesFile;
5203            }
5204            tracesFile.renameTo(curTracesFile);
5205            if (tracesTmp.exists()) {
5206                tracesTmp.renameTo(tracesFile);
5207            }
5208        } finally {
5209            StrictMode.setThreadPolicy(oldPolicy);
5210        }
5211    }
5212
5213    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5214        if (!mLaunchWarningShown) {
5215            mLaunchWarningShown = true;
5216            mUiHandler.post(new Runnable() {
5217                @Override
5218                public void run() {
5219                    synchronized (ActivityManagerService.this) {
5220                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5221                        d.show();
5222                        mUiHandler.postDelayed(new Runnable() {
5223                            @Override
5224                            public void run() {
5225                                synchronized (ActivityManagerService.this) {
5226                                    d.dismiss();
5227                                    mLaunchWarningShown = false;
5228                                }
5229                            }
5230                        }, 4000);
5231                    }
5232                }
5233            });
5234        }
5235    }
5236
5237    @Override
5238    public boolean clearApplicationUserData(final String packageName,
5239            final IPackageDataObserver observer, int userId) {
5240        enforceNotIsolatedCaller("clearApplicationUserData");
5241        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5242            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5243        }
5244        int uid = Binder.getCallingUid();
5245        int pid = Binder.getCallingPid();
5246        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5247                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5248        long callingId = Binder.clearCallingIdentity();
5249        try {
5250            IPackageManager pm = AppGlobals.getPackageManager();
5251            int pkgUid = -1;
5252            synchronized(this) {
5253                try {
5254                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5255                } catch (RemoteException e) {
5256                }
5257                if (pkgUid == -1) {
5258                    Slog.w(TAG, "Invalid packageName: " + packageName);
5259                    if (observer != null) {
5260                        try {
5261                            observer.onRemoveCompleted(packageName, false);
5262                        } catch (RemoteException e) {
5263                            Slog.i(TAG, "Observer no longer exists.");
5264                        }
5265                    }
5266                    return false;
5267                }
5268                if (uid == pkgUid || checkComponentPermission(
5269                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5270                        pid, uid, -1, true)
5271                        == PackageManager.PERMISSION_GRANTED) {
5272                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5273                } else {
5274                    throw new SecurityException("PID " + pid + " does not have permission "
5275                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5276                                    + " of package " + packageName);
5277                }
5278
5279                // Remove all tasks match the cleared application package and user
5280                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5281                    final TaskRecord tr = mRecentTasks.get(i);
5282                    final String taskPackageName =
5283                            tr.getBaseIntent().getComponent().getPackageName();
5284                    if (tr.userId != userId) continue;
5285                    if (!taskPackageName.equals(packageName)) continue;
5286                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5287                }
5288            }
5289
5290            try {
5291                // Clear application user data
5292                pm.clearApplicationUserData(packageName, observer, userId);
5293
5294                synchronized(this) {
5295                    // Remove all permissions granted from/to this package
5296                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5297                }
5298
5299                // Remove all zen rules created by this package; revoke it's zen access.
5300                INotificationManager inm = NotificationManager.getService();
5301                inm.removeAutomaticZenRules(packageName);
5302                inm.setNotificationPolicyAccessGranted(packageName, false);
5303
5304                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5305                        Uri.fromParts("package", packageName, null));
5306                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5307                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5308                        null, null, 0, null, null, null, null, false, false, userId);
5309            } catch (RemoteException e) {
5310            }
5311        } finally {
5312            Binder.restoreCallingIdentity(callingId);
5313        }
5314        return true;
5315    }
5316
5317    @Override
5318    public void killBackgroundProcesses(final String packageName, int userId) {
5319        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5320                != PackageManager.PERMISSION_GRANTED &&
5321                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5322                        != PackageManager.PERMISSION_GRANTED) {
5323            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5324                    + Binder.getCallingPid()
5325                    + ", uid=" + Binder.getCallingUid()
5326                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5327            Slog.w(TAG, msg);
5328            throw new SecurityException(msg);
5329        }
5330
5331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5332                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5333        long callingId = Binder.clearCallingIdentity();
5334        try {
5335            IPackageManager pm = AppGlobals.getPackageManager();
5336            synchronized(this) {
5337                int appId = -1;
5338                try {
5339                    appId = UserHandle.getAppId(
5340                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5341                } catch (RemoteException e) {
5342                }
5343                if (appId == -1) {
5344                    Slog.w(TAG, "Invalid packageName: " + packageName);
5345                    return;
5346                }
5347                killPackageProcessesLocked(packageName, appId, userId,
5348                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5349            }
5350        } finally {
5351            Binder.restoreCallingIdentity(callingId);
5352        }
5353    }
5354
5355    @Override
5356    public void killAllBackgroundProcesses() {
5357        killAllBackgroundProcesses(-1);
5358    }
5359
5360    /**
5361     * Kills all background processes with targetSdkVersion below the specified
5362     * target SDK version.
5363     *
5364     * @param targetSdkVersion the target SDK version below which to kill
5365     *                         processes, or {@code -1} to kill all processes
5366     */
5367    private void killAllBackgroundProcesses(int targetSdkVersion) {
5368        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5369                != PackageManager.PERMISSION_GRANTED) {
5370            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5371                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5372                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5373            Slog.w(TAG, msg);
5374            throw new SecurityException(msg);
5375        }
5376
5377        final long callingId = Binder.clearCallingIdentity();
5378        try {
5379            synchronized (this) {
5380                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5381                final int NP = mProcessNames.getMap().size();
5382                for (int ip = 0; ip < NP; ip++) {
5383                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5384                    final int NA = apps.size();
5385                    for (int ia = 0; ia < NA; ia++) {
5386                        final ProcessRecord app = apps.valueAt(ia);
5387                        if (app.persistent) {
5388                            // We don't kill persistent processes.
5389                            continue;
5390                        }
5391                        if (targetSdkVersion > 0
5392                                && app.info.targetSdkVersion >= targetSdkVersion) {
5393                            continue;
5394                        }
5395                        if (app.removed) {
5396                            procs.add(app);
5397                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5398                            app.removed = true;
5399                            procs.add(app);
5400                        }
5401                    }
5402                }
5403
5404                final int N = procs.size();
5405                for (int i = 0; i < N; i++) {
5406                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5407                }
5408
5409                mAllowLowerMemLevel = true;
5410
5411                updateOomAdjLocked();
5412                doLowMemReportIfNeededLocked(null);
5413            }
5414        } finally {
5415            Binder.restoreCallingIdentity(callingId);
5416        }
5417    }
5418
5419    @Override
5420    public void forceStopPackage(final String packageName, int userId) {
5421        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5422                != PackageManager.PERMISSION_GRANTED) {
5423            String msg = "Permission Denial: forceStopPackage() from pid="
5424                    + Binder.getCallingPid()
5425                    + ", uid=" + Binder.getCallingUid()
5426                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5427            Slog.w(TAG, msg);
5428            throw new SecurityException(msg);
5429        }
5430        final int callingPid = Binder.getCallingPid();
5431        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5432                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5433        long callingId = Binder.clearCallingIdentity();
5434        try {
5435            IPackageManager pm = AppGlobals.getPackageManager();
5436            synchronized(this) {
5437                int[] users = userId == UserHandle.USER_ALL
5438                        ? mUserController.getUsers() : new int[] { userId };
5439                for (int user : users) {
5440                    int pkgUid = -1;
5441                    try {
5442                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5443                                user);
5444                    } catch (RemoteException e) {
5445                    }
5446                    if (pkgUid == -1) {
5447                        Slog.w(TAG, "Invalid packageName: " + packageName);
5448                        continue;
5449                    }
5450                    try {
5451                        pm.setPackageStoppedState(packageName, true, user);
5452                    } catch (RemoteException e) {
5453                    } catch (IllegalArgumentException e) {
5454                        Slog.w(TAG, "Failed trying to unstop package "
5455                                + packageName + ": " + e);
5456                    }
5457                    if (mUserController.isUserRunningLocked(user, 0)) {
5458                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5459                    }
5460                }
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(callingId);
5464        }
5465    }
5466
5467    @Override
5468    public void addPackageDependency(String packageName) {
5469        synchronized (this) {
5470            int callingPid = Binder.getCallingPid();
5471            if (callingPid == Process.myPid()) {
5472                //  Yeah, um, no.
5473                return;
5474            }
5475            ProcessRecord proc;
5476            synchronized (mPidsSelfLocked) {
5477                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5478            }
5479            if (proc != null) {
5480                if (proc.pkgDeps == null) {
5481                    proc.pkgDeps = new ArraySet<String>(1);
5482                }
5483                proc.pkgDeps.add(packageName);
5484            }
5485        }
5486    }
5487
5488    /*
5489     * The pkg name and app id have to be specified.
5490     */
5491    @Override
5492    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5493        if (pkg == null) {
5494            return;
5495        }
5496        // Make sure the uid is valid.
5497        if (appid < 0) {
5498            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5499            return;
5500        }
5501        int callerUid = Binder.getCallingUid();
5502        // Only the system server can kill an application
5503        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5504            // Post an aysnc message to kill the application
5505            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5506            msg.arg1 = appid;
5507            msg.arg2 = 0;
5508            Bundle bundle = new Bundle();
5509            bundle.putString("pkg", pkg);
5510            bundle.putString("reason", reason);
5511            msg.obj = bundle;
5512            mHandler.sendMessage(msg);
5513        } else {
5514            throw new SecurityException(callerUid + " cannot kill pkg: " +
5515                    pkg);
5516        }
5517    }
5518
5519    @Override
5520    public void closeSystemDialogs(String reason) {
5521        enforceNotIsolatedCaller("closeSystemDialogs");
5522
5523        final int pid = Binder.getCallingPid();
5524        final int uid = Binder.getCallingUid();
5525        final long origId = Binder.clearCallingIdentity();
5526        try {
5527            synchronized (this) {
5528                // Only allow this from foreground processes, so that background
5529                // applications can't abuse it to prevent system UI from being shown.
5530                if (uid >= Process.FIRST_APPLICATION_UID) {
5531                    ProcessRecord proc;
5532                    synchronized (mPidsSelfLocked) {
5533                        proc = mPidsSelfLocked.get(pid);
5534                    }
5535                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5536                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5537                                + " from background process " + proc);
5538                        return;
5539                    }
5540                }
5541                closeSystemDialogsLocked(reason);
5542            }
5543        } finally {
5544            Binder.restoreCallingIdentity(origId);
5545        }
5546    }
5547
5548    void closeSystemDialogsLocked(String reason) {
5549        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5550        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5551                | Intent.FLAG_RECEIVER_FOREGROUND);
5552        if (reason != null) {
5553            intent.putExtra("reason", reason);
5554        }
5555        mWindowManager.closeSystemDialogs(reason);
5556
5557        mStackSupervisor.closeSystemDialogsLocked();
5558
5559        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5560                AppOpsManager.OP_NONE, null, false, false,
5561                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5562    }
5563
5564    @Override
5565    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5566        enforceNotIsolatedCaller("getProcessMemoryInfo");
5567        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5568        for (int i=pids.length-1; i>=0; i--) {
5569            ProcessRecord proc;
5570            int oomAdj;
5571            synchronized (this) {
5572                synchronized (mPidsSelfLocked) {
5573                    proc = mPidsSelfLocked.get(pids[i]);
5574                    oomAdj = proc != null ? proc.setAdj : 0;
5575                }
5576            }
5577            infos[i] = new Debug.MemoryInfo();
5578            Debug.getMemoryInfo(pids[i], infos[i]);
5579            if (proc != null) {
5580                synchronized (this) {
5581                    if (proc.thread != null && proc.setAdj == oomAdj) {
5582                        // Record this for posterity if the process has been stable.
5583                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5584                                infos[i].getTotalUss(), false, proc.pkgList);
5585                    }
5586                }
5587            }
5588        }
5589        return infos;
5590    }
5591
5592    @Override
5593    public long[] getProcessPss(int[] pids) {
5594        enforceNotIsolatedCaller("getProcessPss");
5595        long[] pss = new long[pids.length];
5596        for (int i=pids.length-1; i>=0; i--) {
5597            ProcessRecord proc;
5598            int oomAdj;
5599            synchronized (this) {
5600                synchronized (mPidsSelfLocked) {
5601                    proc = mPidsSelfLocked.get(pids[i]);
5602                    oomAdj = proc != null ? proc.setAdj : 0;
5603                }
5604            }
5605            long[] tmpUss = new long[1];
5606            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5607            if (proc != null) {
5608                synchronized (this) {
5609                    if (proc.thread != null && proc.setAdj == oomAdj) {
5610                        // Record this for posterity if the process has been stable.
5611                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5612                    }
5613                }
5614            }
5615        }
5616        return pss;
5617    }
5618
5619    @Override
5620    public void killApplicationProcess(String processName, int uid) {
5621        if (processName == null) {
5622            return;
5623        }
5624
5625        int callerUid = Binder.getCallingUid();
5626        // Only the system server can kill an application
5627        if (callerUid == Process.SYSTEM_UID) {
5628            synchronized (this) {
5629                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5630                if (app != null && app.thread != null) {
5631                    try {
5632                        app.thread.scheduleSuicide();
5633                    } catch (RemoteException e) {
5634                        // If the other end already died, then our work here is done.
5635                    }
5636                } else {
5637                    Slog.w(TAG, "Process/uid not found attempting kill of "
5638                            + processName + " / " + uid);
5639                }
5640            }
5641        } else {
5642            throw new SecurityException(callerUid + " cannot kill app process: " +
5643                    processName);
5644        }
5645    }
5646
5647    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5648        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5649                false, true, false, false, UserHandle.getUserId(uid), reason);
5650        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5651                Uri.fromParts("package", packageName, null));
5652        if (!mProcessesReady) {
5653            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5654                    | Intent.FLAG_RECEIVER_FOREGROUND);
5655        }
5656        intent.putExtra(Intent.EXTRA_UID, uid);
5657        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5658        broadcastIntentLocked(null, null, intent,
5659                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5660                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5661    }
5662
5663
5664    private final boolean killPackageProcessesLocked(String packageName, int appId,
5665            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5666            boolean doit, boolean evenPersistent, String reason) {
5667        ArrayList<ProcessRecord> procs = new ArrayList<>();
5668
5669        // Remove all processes this package may have touched: all with the
5670        // same UID (except for the system or root user), and all whose name
5671        // matches the package name.
5672        final int NP = mProcessNames.getMap().size();
5673        for (int ip=0; ip<NP; ip++) {
5674            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5675            final int NA = apps.size();
5676            for (int ia=0; ia<NA; ia++) {
5677                ProcessRecord app = apps.valueAt(ia);
5678                if (app.persistent && !evenPersistent) {
5679                    // we don't kill persistent processes
5680                    continue;
5681                }
5682                if (app.removed) {
5683                    if (doit) {
5684                        procs.add(app);
5685                    }
5686                    continue;
5687                }
5688
5689                // Skip process if it doesn't meet our oom adj requirement.
5690                if (app.setAdj < minOomAdj) {
5691                    continue;
5692                }
5693
5694                // If no package is specified, we call all processes under the
5695                // give user id.
5696                if (packageName == null) {
5697                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5698                        continue;
5699                    }
5700                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5701                        continue;
5702                    }
5703                // Package has been specified, we want to hit all processes
5704                // that match it.  We need to qualify this by the processes
5705                // that are running under the specified app and user ID.
5706                } else {
5707                    final boolean isDep = app.pkgDeps != null
5708                            && app.pkgDeps.contains(packageName);
5709                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5710                        continue;
5711                    }
5712                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5713                        continue;
5714                    }
5715                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5716                        continue;
5717                    }
5718                }
5719
5720                // Process has passed all conditions, kill it!
5721                if (!doit) {
5722                    return true;
5723                }
5724                app.removed = true;
5725                procs.add(app);
5726            }
5727        }
5728
5729        int N = procs.size();
5730        for (int i=0; i<N; i++) {
5731            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5732        }
5733        updateOomAdjLocked();
5734        return N > 0;
5735    }
5736
5737    private void cleanupDisabledPackageComponentsLocked(
5738            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5739
5740        Set<String> disabledClasses = null;
5741        boolean packageDisabled = false;
5742        IPackageManager pm = AppGlobals.getPackageManager();
5743
5744        if (changedClasses == null) {
5745            // Nothing changed...
5746            return;
5747        }
5748
5749        // Determine enable/disable state of the package and its components.
5750        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5751        for (int i = changedClasses.length - 1; i >= 0; i--) {
5752            final String changedClass = changedClasses[i];
5753
5754            if (changedClass.equals(packageName)) {
5755                try {
5756                    // Entire package setting changed
5757                    enabled = pm.getApplicationEnabledSetting(packageName,
5758                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5759                } catch (Exception e) {
5760                    // No such package/component; probably racing with uninstall.  In any
5761                    // event it means we have nothing further to do here.
5762                    return;
5763                }
5764                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5765                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5766                if (packageDisabled) {
5767                    // Entire package is disabled.
5768                    // No need to continue to check component states.
5769                    disabledClasses = null;
5770                    break;
5771                }
5772            } else {
5773                try {
5774                    enabled = pm.getComponentEnabledSetting(
5775                            new ComponentName(packageName, changedClass),
5776                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5777                } catch (Exception e) {
5778                    // As above, probably racing with uninstall.
5779                    return;
5780                }
5781                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5782                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5783                    if (disabledClasses == null) {
5784                        disabledClasses = new ArraySet<>(changedClasses.length);
5785                    }
5786                    disabledClasses.add(changedClass);
5787                }
5788            }
5789        }
5790
5791        if (!packageDisabled && disabledClasses == null) {
5792            // Nothing to do here...
5793            return;
5794        }
5795
5796        // Clean-up disabled activities.
5797        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5798                packageName, disabledClasses, true, false, userId) && mBooted) {
5799            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5800            mStackSupervisor.scheduleIdleLocked();
5801        }
5802
5803        // Clean-up disabled tasks
5804        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5805
5806        // Clean-up disabled services.
5807        mServices.bringDownDisabledPackageServicesLocked(
5808                packageName, disabledClasses, userId, false, killProcess, true);
5809
5810        // Clean-up disabled providers.
5811        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5812        mProviderMap.collectPackageProvidersLocked(
5813                packageName, disabledClasses, true, false, userId, providers);
5814        for (int i = providers.size() - 1; i >= 0; i--) {
5815            removeDyingProviderLocked(null, providers.get(i), true);
5816        }
5817
5818        // Clean-up disabled broadcast receivers.
5819        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5820            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5821                    packageName, disabledClasses, userId, true);
5822        }
5823
5824    }
5825
5826    final boolean forceStopPackageLocked(String packageName, int appId,
5827            boolean callerWillRestart, boolean purgeCache, boolean doit,
5828            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5829        int i;
5830
5831        if (userId == UserHandle.USER_ALL && packageName == null) {
5832            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5833        }
5834
5835        if (appId < 0 && packageName != null) {
5836            try {
5837                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5838                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5839            } catch (RemoteException e) {
5840            }
5841        }
5842
5843        if (doit) {
5844            if (packageName != null) {
5845                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5846                        + " user=" + userId + ": " + reason);
5847            } else {
5848                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5849            }
5850
5851            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5852        }
5853
5854        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5855                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5856                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5857
5858        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5859                packageName, null, doit, evenPersistent, userId)) {
5860            if (!doit) {
5861                return true;
5862            }
5863            didSomething = true;
5864        }
5865
5866        if (mServices.bringDownDisabledPackageServicesLocked(
5867                packageName, null, userId, evenPersistent, true, doit)) {
5868            if (!doit) {
5869                return true;
5870            }
5871            didSomething = true;
5872        }
5873
5874        if (packageName == null) {
5875            // Remove all sticky broadcasts from this user.
5876            mStickyBroadcasts.remove(userId);
5877        }
5878
5879        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5880        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5881                userId, providers)) {
5882            if (!doit) {
5883                return true;
5884            }
5885            didSomething = true;
5886        }
5887        for (i = providers.size() - 1; i >= 0; i--) {
5888            removeDyingProviderLocked(null, providers.get(i), true);
5889        }
5890
5891        // Remove transient permissions granted from/to this package/user
5892        removeUriPermissionsForPackageLocked(packageName, userId, false);
5893
5894        if (doit) {
5895            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5896                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5897                        packageName, null, userId, doit);
5898            }
5899        }
5900
5901        if (packageName == null || uninstalling) {
5902            // Remove pending intents.  For now we only do this when force
5903            // stopping users, because we have some problems when doing this
5904            // for packages -- app widgets are not currently cleaned up for
5905            // such packages, so they can be left with bad pending intents.
5906            if (mIntentSenderRecords.size() > 0) {
5907                Iterator<WeakReference<PendingIntentRecord>> it
5908                        = mIntentSenderRecords.values().iterator();
5909                while (it.hasNext()) {
5910                    WeakReference<PendingIntentRecord> wpir = it.next();
5911                    if (wpir == null) {
5912                        it.remove();
5913                        continue;
5914                    }
5915                    PendingIntentRecord pir = wpir.get();
5916                    if (pir == null) {
5917                        it.remove();
5918                        continue;
5919                    }
5920                    if (packageName == null) {
5921                        // Stopping user, remove all objects for the user.
5922                        if (pir.key.userId != userId) {
5923                            // Not the same user, skip it.
5924                            continue;
5925                        }
5926                    } else {
5927                        if (UserHandle.getAppId(pir.uid) != appId) {
5928                            // Different app id, skip it.
5929                            continue;
5930                        }
5931                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5932                            // Different user, skip it.
5933                            continue;
5934                        }
5935                        if (!pir.key.packageName.equals(packageName)) {
5936                            // Different package, skip it.
5937                            continue;
5938                        }
5939                    }
5940                    if (!doit) {
5941                        return true;
5942                    }
5943                    didSomething = true;
5944                    it.remove();
5945                    pir.canceled = true;
5946                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5947                        pir.key.activity.pendingResults.remove(pir.ref);
5948                    }
5949                }
5950            }
5951        }
5952
5953        if (doit) {
5954            if (purgeCache && packageName != null) {
5955                AttributeCache ac = AttributeCache.instance();
5956                if (ac != null) {
5957                    ac.removePackage(packageName);
5958                }
5959            }
5960            if (mBooted) {
5961                mStackSupervisor.resumeFocusedStackTopActivityLocked();
5962                mStackSupervisor.scheduleIdleLocked();
5963            }
5964        }
5965
5966        return didSomething;
5967    }
5968
5969    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5970        ProcessRecord old = mProcessNames.remove(name, uid);
5971        if (old != null) {
5972            old.uidRecord.numProcs--;
5973            if (old.uidRecord.numProcs == 0) {
5974                // No more processes using this uid, tell clients it is gone.
5975                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5976                        "No more processes in " + old.uidRecord);
5977                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
5978                mActiveUids.remove(uid);
5979                mBatteryStatsService.noteUidProcessState(uid,
5980                        ActivityManager.PROCESS_STATE_NONEXISTENT);
5981            }
5982            old.uidRecord = null;
5983        }
5984        mIsolatedProcesses.remove(uid);
5985        return old;
5986    }
5987
5988    private final void addProcessNameLocked(ProcessRecord proc) {
5989        // We shouldn't already have a process under this name, but just in case we
5990        // need to clean up whatever may be there now.
5991        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5992        if (old == proc && proc.persistent) {
5993            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5994            Slog.w(TAG, "Re-adding persistent process " + proc);
5995        } else if (old != null) {
5996            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5997        }
5998        UidRecord uidRec = mActiveUids.get(proc.uid);
5999        if (uidRec == null) {
6000            uidRec = new UidRecord(proc.uid);
6001            // This is the first appearance of the uid, report it now!
6002            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6003                    "Creating new process uid: " + uidRec);
6004            mActiveUids.put(proc.uid, uidRec);
6005            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6006            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6007        }
6008        proc.uidRecord = uidRec;
6009        uidRec.numProcs++;
6010        mProcessNames.put(proc.processName, proc.uid, proc);
6011        if (proc.isolated) {
6012            mIsolatedProcesses.put(proc.uid, proc);
6013        }
6014    }
6015
6016    boolean removeProcessLocked(ProcessRecord app,
6017            boolean callerWillRestart, boolean allowRestart, String reason) {
6018        final String name = app.processName;
6019        final int uid = app.uid;
6020        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6021            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6022
6023        removeProcessNameLocked(name, uid);
6024        if (mHeavyWeightProcess == app) {
6025            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6026                    mHeavyWeightProcess.userId, 0));
6027            mHeavyWeightProcess = null;
6028        }
6029        boolean needRestart = false;
6030        if (app.pid > 0 && app.pid != MY_PID) {
6031            int pid = app.pid;
6032            synchronized (mPidsSelfLocked) {
6033                mPidsSelfLocked.remove(pid);
6034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6035            }
6036            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6037            if (app.isolated) {
6038                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6039            }
6040            boolean willRestart = false;
6041            if (app.persistent && !app.isolated) {
6042                if (!callerWillRestart) {
6043                    willRestart = true;
6044                } else {
6045                    needRestart = true;
6046                }
6047            }
6048            app.kill(reason, true);
6049            handleAppDiedLocked(app, willRestart, allowRestart);
6050            if (willRestart) {
6051                removeLruProcessLocked(app);
6052                addAppLocked(app.info, false, null /* ABI override */);
6053            }
6054        } else {
6055            mRemovedProcesses.add(app);
6056        }
6057
6058        return needRestart;
6059    }
6060
6061    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6062        cleanupAppInLaunchingProvidersLocked(app, true);
6063        removeProcessLocked(app, false, true, "timeout publishing content providers");
6064    }
6065
6066    private final void processStartTimedOutLocked(ProcessRecord app) {
6067        final int pid = app.pid;
6068        boolean gone = false;
6069        synchronized (mPidsSelfLocked) {
6070            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6071            if (knownApp != null && knownApp.thread == null) {
6072                mPidsSelfLocked.remove(pid);
6073                gone = true;
6074            }
6075        }
6076
6077        if (gone) {
6078            Slog.w(TAG, "Process " + app + " failed to attach");
6079            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6080                    pid, app.uid, app.processName);
6081            removeProcessNameLocked(app.processName, app.uid);
6082            if (mHeavyWeightProcess == app) {
6083                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6084                        mHeavyWeightProcess.userId, 0));
6085                mHeavyWeightProcess = null;
6086            }
6087            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6088            if (app.isolated) {
6089                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6090            }
6091            // Take care of any launching providers waiting for this process.
6092            cleanupAppInLaunchingProvidersLocked(app, true);
6093            // Take care of any services that are waiting for the process.
6094            mServices.processStartTimedOutLocked(app);
6095            app.kill("start timeout", true);
6096            removeLruProcessLocked(app);
6097            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6098                Slog.w(TAG, "Unattached app died before backup, skipping");
6099                try {
6100                    IBackupManager bm = IBackupManager.Stub.asInterface(
6101                            ServiceManager.getService(Context.BACKUP_SERVICE));
6102                    bm.agentDisconnected(app.info.packageName);
6103                } catch (RemoteException e) {
6104                    // Can't happen; the backup manager is local
6105                }
6106            }
6107            if (isPendingBroadcastProcessLocked(pid)) {
6108                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6109                skipPendingBroadcastLocked(pid);
6110            }
6111        } else {
6112            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6113        }
6114    }
6115
6116    private final boolean attachApplicationLocked(IApplicationThread thread,
6117            int pid) {
6118
6119        // Find the application record that is being attached...  either via
6120        // the pid if we are running in multiple processes, or just pull the
6121        // next app record if we are emulating process with anonymous threads.
6122        ProcessRecord app;
6123        if (pid != MY_PID && pid >= 0) {
6124            synchronized (mPidsSelfLocked) {
6125                app = mPidsSelfLocked.get(pid);
6126            }
6127        } else {
6128            app = null;
6129        }
6130
6131        if (app == null) {
6132            Slog.w(TAG, "No pending application record for pid " + pid
6133                    + " (IApplicationThread " + thread + "); dropping process");
6134            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6135            if (pid > 0 && pid != MY_PID) {
6136                Process.killProcessQuiet(pid);
6137                //TODO: killProcessGroup(app.info.uid, pid);
6138            } else {
6139                try {
6140                    thread.scheduleExit();
6141                } catch (Exception e) {
6142                    // Ignore exceptions.
6143                }
6144            }
6145            return false;
6146        }
6147
6148        // If this application record is still attached to a previous
6149        // process, clean it up now.
6150        if (app.thread != null) {
6151            handleAppDiedLocked(app, true, true);
6152        }
6153
6154        // Tell the process all about itself.
6155
6156        if (DEBUG_ALL) Slog.v(
6157                TAG, "Binding process pid " + pid + " to record " + app);
6158
6159        final String processName = app.processName;
6160        try {
6161            AppDeathRecipient adr = new AppDeathRecipient(
6162                    app, pid, thread);
6163            thread.asBinder().linkToDeath(adr, 0);
6164            app.deathRecipient = adr;
6165        } catch (RemoteException e) {
6166            app.resetPackageList(mProcessStats);
6167            startProcessLocked(app, "link fail", processName);
6168            return false;
6169        }
6170
6171        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6172
6173        app.makeActive(thread, mProcessStats);
6174        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6175        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6176        app.forcingToForeground = null;
6177        updateProcessForegroundLocked(app, false, false);
6178        app.hasShownUi = false;
6179        app.debugging = false;
6180        app.cached = false;
6181        app.killedByAm = false;
6182
6183        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6184
6185        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6186        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6187
6188        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6189            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6190            msg.obj = app;
6191            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6192        }
6193
6194        if (!normalMode) {
6195            Slog.i(TAG, "Launching preboot mode app: " + app);
6196        }
6197
6198        if (DEBUG_ALL) Slog.v(
6199            TAG, "New app record " + app
6200            + " thread=" + thread.asBinder() + " pid=" + pid);
6201        try {
6202            int testMode = IApplicationThread.DEBUG_OFF;
6203            if (mDebugApp != null && mDebugApp.equals(processName)) {
6204                testMode = mWaitForDebugger
6205                    ? IApplicationThread.DEBUG_WAIT
6206                    : IApplicationThread.DEBUG_ON;
6207                app.debugging = true;
6208                if (mDebugTransient) {
6209                    mDebugApp = mOrigDebugApp;
6210                    mWaitForDebugger = mOrigWaitForDebugger;
6211                }
6212            }
6213            String profileFile = app.instrumentationProfileFile;
6214            ParcelFileDescriptor profileFd = null;
6215            int samplingInterval = 0;
6216            boolean profileAutoStop = false;
6217            if (mProfileApp != null && mProfileApp.equals(processName)) {
6218                mProfileProc = app;
6219                profileFile = mProfileFile;
6220                profileFd = mProfileFd;
6221                samplingInterval = mSamplingInterval;
6222                profileAutoStop = mAutoStopProfiler;
6223            }
6224            boolean enableTrackAllocation = false;
6225            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6226                enableTrackAllocation = true;
6227                mTrackAllocationApp = null;
6228            }
6229
6230            // If the app is being launched for restore or full backup, set it up specially
6231            boolean isRestrictedBackupMode = false;
6232            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6233                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6234                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6235                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6236            }
6237
6238            notifyPackageUse(app.instrumentationInfo != null
6239                    ? app.instrumentationInfo.packageName
6240                    : app.info.packageName);
6241            if (app.instrumentationClass != null) {
6242                notifyPackageUse(app.instrumentationClass.getPackageName());
6243            }
6244            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6245                    + processName + " with config " + mConfiguration);
6246            ApplicationInfo appInfo = app.instrumentationInfo != null
6247                    ? app.instrumentationInfo : app.info;
6248            app.compat = compatibilityInfoForPackageLocked(appInfo);
6249            if (profileFd != null) {
6250                profileFd = profileFd.dup();
6251            }
6252            ProfilerInfo profilerInfo = profileFile == null ? null
6253                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6254            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6255                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6256                    app.instrumentationUiAutomationConnection, testMode,
6257                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6258                    isRestrictedBackupMode || !normalMode, app.persistent,
6259                    new Configuration(mConfiguration), app.compat,
6260                    getCommonServicesLocked(app.isolated),
6261                    mCoreSettingsObserver.getCoreSettingsLocked());
6262            updateLruProcessLocked(app, false, null);
6263            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6264        } catch (Exception e) {
6265            // todo: Yikes!  What should we do?  For now we will try to
6266            // start another process, but that could easily get us in
6267            // an infinite loop of restarting processes...
6268            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6269
6270            app.resetPackageList(mProcessStats);
6271            app.unlinkDeathRecipient();
6272            startProcessLocked(app, "bind fail", processName);
6273            return false;
6274        }
6275
6276        // Remove this record from the list of starting applications.
6277        mPersistentStartingProcesses.remove(app);
6278        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6279                "Attach application locked removing on hold: " + app);
6280        mProcessesOnHold.remove(app);
6281
6282        boolean badApp = false;
6283        boolean didSomething = false;
6284
6285        // See if the top visible activity is waiting to run in this process...
6286        if (normalMode) {
6287            try {
6288                if (mStackSupervisor.attachApplicationLocked(app)) {
6289                    didSomething = true;
6290                }
6291            } catch (Exception e) {
6292                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6293                badApp = true;
6294            }
6295        }
6296
6297        // Find any services that should be running in this process...
6298        if (!badApp) {
6299            try {
6300                didSomething |= mServices.attachApplicationLocked(app, processName);
6301            } catch (Exception e) {
6302                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6303                badApp = true;
6304            }
6305        }
6306
6307        // Check if a next-broadcast receiver is in this process...
6308        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6309            try {
6310                didSomething |= sendPendingBroadcastsLocked(app);
6311            } catch (Exception e) {
6312                // If the app died trying to launch the receiver we declare it 'bad'
6313                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6314                badApp = true;
6315            }
6316        }
6317
6318        // Check whether the next backup agent is in this process...
6319        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6320            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6321                    "New app is backup target, launching agent for " + app);
6322            notifyPackageUse(mBackupTarget.appInfo.packageName);
6323            try {
6324                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6325                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6326                        mBackupTarget.backupMode);
6327            } catch (Exception e) {
6328                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6329                badApp = true;
6330            }
6331        }
6332
6333        if (badApp) {
6334            app.kill("error during init", true);
6335            handleAppDiedLocked(app, false, true);
6336            return false;
6337        }
6338
6339        if (!didSomething) {
6340            updateOomAdjLocked();
6341        }
6342
6343        return true;
6344    }
6345
6346    @Override
6347    public final void attachApplication(IApplicationThread thread) {
6348        synchronized (this) {
6349            int callingPid = Binder.getCallingPid();
6350            final long origId = Binder.clearCallingIdentity();
6351            attachApplicationLocked(thread, callingPid);
6352            Binder.restoreCallingIdentity(origId);
6353        }
6354    }
6355
6356    @Override
6357    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6358        final long origId = Binder.clearCallingIdentity();
6359        synchronized (this) {
6360            ActivityStack stack = ActivityRecord.getStackLocked(token);
6361            if (stack != null) {
6362                ActivityRecord r =
6363                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6364                if (stopProfiling) {
6365                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6366                        try {
6367                            mProfileFd.close();
6368                        } catch (IOException e) {
6369                        }
6370                        clearProfilerLocked();
6371                    }
6372                }
6373            }
6374        }
6375        Binder.restoreCallingIdentity(origId);
6376    }
6377
6378    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6379        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6380                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6381    }
6382
6383    void enableScreenAfterBoot() {
6384        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6385                SystemClock.uptimeMillis());
6386        mWindowManager.enableScreenAfterBoot();
6387
6388        synchronized (this) {
6389            updateEventDispatchingLocked();
6390        }
6391    }
6392
6393    @Override
6394    public void showBootMessage(final CharSequence msg, final boolean always) {
6395        if (Binder.getCallingUid() != Process.myUid()) {
6396            // These days only the core system can call this, so apps can't get in
6397            // the way of what we show about running them.
6398        }
6399        mWindowManager.showBootMessage(msg, always);
6400    }
6401
6402    @Override
6403    public void keyguardWaitingForActivityDrawn() {
6404        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6405        final long token = Binder.clearCallingIdentity();
6406        try {
6407            synchronized (this) {
6408                if (DEBUG_LOCKSCREEN) logLockScreen("");
6409                mWindowManager.keyguardWaitingForActivityDrawn();
6410                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6411                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6412                    updateSleepIfNeededLocked();
6413                }
6414            }
6415        } finally {
6416            Binder.restoreCallingIdentity(token);
6417        }
6418    }
6419
6420    @Override
6421    public void keyguardGoingAway(boolean disableWindowAnimations,
6422            boolean keyguardGoingToNotificationShade) {
6423        enforceNotIsolatedCaller("keyguardGoingAway");
6424        final long token = Binder.clearCallingIdentity();
6425        try {
6426            synchronized (this) {
6427                if (DEBUG_LOCKSCREEN) logLockScreen("");
6428                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6429                        keyguardGoingToNotificationShade);
6430                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6431                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6432                    updateSleepIfNeededLocked();
6433
6434                    // Some stack visibility might change (e.g. docked stack)
6435                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6436                }
6437            }
6438        } finally {
6439            Binder.restoreCallingIdentity(token);
6440        }
6441    }
6442
6443    final void finishBooting() {
6444        synchronized (this) {
6445            if (!mBootAnimationComplete) {
6446                mCallFinishBooting = true;
6447                return;
6448            }
6449            mCallFinishBooting = false;
6450        }
6451
6452        ArraySet<String> completedIsas = new ArraySet<String>();
6453        for (String abi : Build.SUPPORTED_ABIS) {
6454            Process.establishZygoteConnectionForAbi(abi);
6455            final String instructionSet = VMRuntime.getInstructionSet(abi);
6456            if (!completedIsas.contains(instructionSet)) {
6457                try {
6458                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6459                } catch (InstallerException e) {
6460                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6461                }
6462                completedIsas.add(instructionSet);
6463            }
6464        }
6465
6466        IntentFilter pkgFilter = new IntentFilter();
6467        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6468        pkgFilter.addDataScheme("package");
6469        mContext.registerReceiver(new BroadcastReceiver() {
6470            @Override
6471            public void onReceive(Context context, Intent intent) {
6472                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6473                if (pkgs != null) {
6474                    for (String pkg : pkgs) {
6475                        synchronized (ActivityManagerService.this) {
6476                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6477                                    0, "query restart")) {
6478                                setResultCode(Activity.RESULT_OK);
6479                                return;
6480                            }
6481                        }
6482                    }
6483                }
6484            }
6485        }, pkgFilter);
6486
6487        IntentFilter dumpheapFilter = new IntentFilter();
6488        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6489        mContext.registerReceiver(new BroadcastReceiver() {
6490            @Override
6491            public void onReceive(Context context, Intent intent) {
6492                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6493                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6494                } else {
6495                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6496                }
6497            }
6498        }, dumpheapFilter);
6499
6500        mProcessStartLogger.registerListener(mContext);
6501
6502        // Let system services know.
6503        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6504
6505        synchronized (this) {
6506            // Ensure that any processes we had put on hold are now started
6507            // up.
6508            final int NP = mProcessesOnHold.size();
6509            if (NP > 0) {
6510                ArrayList<ProcessRecord> procs =
6511                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6512                for (int ip=0; ip<NP; ip++) {
6513                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6514                            + procs.get(ip));
6515                    startProcessLocked(procs.get(ip), "on-hold", null);
6516                }
6517            }
6518
6519            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6520                // Start looking for apps that are abusing wake locks.
6521                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6522                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6523                // Tell anyone interested that we are done booting!
6524                SystemProperties.set("sys.boot_completed", "1");
6525
6526                // And trigger dev.bootcomplete if we are not showing encryption progress
6527                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6528                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6529                    SystemProperties.set("dev.bootcomplete", "1");
6530                }
6531                mUserController.sendBootCompletedLocked(
6532                        new IIntentReceiver.Stub() {
6533                            @Override
6534                            public void performReceive(Intent intent, int resultCode,
6535                                    String data, Bundle extras, boolean ordered,
6536                                    boolean sticky, int sendingUser) {
6537                                synchronized (ActivityManagerService.this) {
6538                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6539                                            true, false);
6540                                }
6541                            }
6542                        });
6543                scheduleStartProfilesLocked();
6544            }
6545        }
6546    }
6547
6548    @Override
6549    public void bootAnimationComplete() {
6550        final boolean callFinishBooting;
6551        synchronized (this) {
6552            callFinishBooting = mCallFinishBooting;
6553            mBootAnimationComplete = true;
6554        }
6555        if (callFinishBooting) {
6556            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6557            finishBooting();
6558            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6559        }
6560    }
6561
6562    final void ensureBootCompleted() {
6563        boolean booting;
6564        boolean enableScreen;
6565        synchronized (this) {
6566            booting = mBooting;
6567            mBooting = false;
6568            enableScreen = !mBooted;
6569            mBooted = true;
6570        }
6571
6572        if (booting) {
6573            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6574            finishBooting();
6575            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6576        }
6577
6578        if (enableScreen) {
6579            enableScreenAfterBoot();
6580        }
6581    }
6582
6583    @Override
6584    public final void activityResumed(IBinder token) {
6585        final long origId = Binder.clearCallingIdentity();
6586        synchronized(this) {
6587            ActivityStack stack = ActivityRecord.getStackLocked(token);
6588            if (stack != null) {
6589                ActivityRecord.activityResumedLocked(token);
6590            }
6591        }
6592        Binder.restoreCallingIdentity(origId);
6593    }
6594
6595    @Override
6596    public final void activityPaused(IBinder token) {
6597        final long origId = Binder.clearCallingIdentity();
6598        synchronized(this) {
6599            ActivityStack stack = ActivityRecord.getStackLocked(token);
6600            if (stack != null) {
6601                stack.activityPausedLocked(token, false);
6602            }
6603        }
6604        Binder.restoreCallingIdentity(origId);
6605    }
6606
6607    @Override
6608    public final void activityStopped(IBinder token, Bundle icicle,
6609            PersistableBundle persistentState, CharSequence description) {
6610        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6611
6612        // Refuse possible leaked file descriptors
6613        if (icicle != null && icicle.hasFileDescriptors()) {
6614            throw new IllegalArgumentException("File descriptors passed in Bundle");
6615        }
6616
6617        final long origId = Binder.clearCallingIdentity();
6618
6619        synchronized (this) {
6620            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6621            if (r != null) {
6622                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6623            }
6624        }
6625
6626        trimApplications();
6627
6628        Binder.restoreCallingIdentity(origId);
6629    }
6630
6631    @Override
6632    public final void activityDestroyed(IBinder token) {
6633        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6634        synchronized (this) {
6635            ActivityStack stack = ActivityRecord.getStackLocked(token);
6636            if (stack != null) {
6637                stack.activityDestroyedLocked(token, "activityDestroyed");
6638            }
6639        }
6640    }
6641
6642    @Override
6643    public final void activityRelaunched(IBinder token) {
6644        final long origId = Binder.clearCallingIdentity();
6645        synchronized (this) {
6646            mStackSupervisor.activityRelaunchedLocked(token);
6647        }
6648        Binder.restoreCallingIdentity(origId);
6649    }
6650
6651    @Override
6652    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6653            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6654        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6655                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6656        synchronized (this) {
6657            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6658            if (record == null) {
6659                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6660                        + "found for: " + token);
6661            }
6662            record.setSizeConfigurations(horizontalSizeConfiguration,
6663                    verticalSizeConfigurations, smallestSizeConfigurations);
6664        }
6665    }
6666
6667    @Override
6668    public final void backgroundResourcesReleased(IBinder token) {
6669        final long origId = Binder.clearCallingIdentity();
6670        try {
6671            synchronized (this) {
6672                ActivityStack stack = ActivityRecord.getStackLocked(token);
6673                if (stack != null) {
6674                    stack.backgroundResourcesReleased();
6675                }
6676            }
6677        } finally {
6678            Binder.restoreCallingIdentity(origId);
6679        }
6680    }
6681
6682    @Override
6683    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6684        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6685    }
6686
6687    @Override
6688    public final void notifyEnterAnimationComplete(IBinder token) {
6689        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6690    }
6691
6692    @Override
6693    public String getCallingPackage(IBinder token) {
6694        synchronized (this) {
6695            ActivityRecord r = getCallingRecordLocked(token);
6696            return r != null ? r.info.packageName : null;
6697        }
6698    }
6699
6700    @Override
6701    public ComponentName getCallingActivity(IBinder token) {
6702        synchronized (this) {
6703            ActivityRecord r = getCallingRecordLocked(token);
6704            return r != null ? r.intent.getComponent() : null;
6705        }
6706    }
6707
6708    private ActivityRecord getCallingRecordLocked(IBinder token) {
6709        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6710        if (r == null) {
6711            return null;
6712        }
6713        return r.resultTo;
6714    }
6715
6716    @Override
6717    public ComponentName getActivityClassForToken(IBinder token) {
6718        synchronized(this) {
6719            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6720            if (r == null) {
6721                return null;
6722            }
6723            return r.intent.getComponent();
6724        }
6725    }
6726
6727    @Override
6728    public String getPackageForToken(IBinder token) {
6729        synchronized(this) {
6730            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6731            if (r == null) {
6732                return null;
6733            }
6734            return r.packageName;
6735        }
6736    }
6737
6738    @Override
6739    public boolean isRootVoiceInteraction(IBinder token) {
6740        synchronized(this) {
6741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6742            if (r == null) {
6743                return false;
6744            }
6745            return r.rootVoiceInteraction;
6746        }
6747    }
6748
6749    @Override
6750    public IIntentSender getIntentSender(int type,
6751            String packageName, IBinder token, String resultWho,
6752            int requestCode, Intent[] intents, String[] resolvedTypes,
6753            int flags, Bundle bOptions, int userId) {
6754        enforceNotIsolatedCaller("getIntentSender");
6755        // Refuse possible leaked file descriptors
6756        if (intents != null) {
6757            if (intents.length < 1) {
6758                throw new IllegalArgumentException("Intents array length must be >= 1");
6759            }
6760            for (int i=0; i<intents.length; i++) {
6761                Intent intent = intents[i];
6762                if (intent != null) {
6763                    if (intent.hasFileDescriptors()) {
6764                        throw new IllegalArgumentException("File descriptors passed in Intent");
6765                    }
6766                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6767                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6768                        throw new IllegalArgumentException(
6769                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6770                    }
6771                    intents[i] = new Intent(intent);
6772                }
6773            }
6774            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6775                throw new IllegalArgumentException(
6776                        "Intent array length does not match resolvedTypes length");
6777            }
6778        }
6779        if (bOptions != null) {
6780            if (bOptions.hasFileDescriptors()) {
6781                throw new IllegalArgumentException("File descriptors passed in options");
6782            }
6783        }
6784
6785        synchronized(this) {
6786            int callingUid = Binder.getCallingUid();
6787            int origUserId = userId;
6788            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6789                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6790                    ALLOW_NON_FULL, "getIntentSender", null);
6791            if (origUserId == UserHandle.USER_CURRENT) {
6792                // We don't want to evaluate this until the pending intent is
6793                // actually executed.  However, we do want to always do the
6794                // security checking for it above.
6795                userId = UserHandle.USER_CURRENT;
6796            }
6797            try {
6798                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6799                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6800                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6801                    if (!UserHandle.isSameApp(callingUid, uid)) {
6802                        String msg = "Permission Denial: getIntentSender() from pid="
6803                            + Binder.getCallingPid()
6804                            + ", uid=" + Binder.getCallingUid()
6805                            + ", (need uid=" + uid + ")"
6806                            + " is not allowed to send as package " + packageName;
6807                        Slog.w(TAG, msg);
6808                        throw new SecurityException(msg);
6809                    }
6810                }
6811
6812                return getIntentSenderLocked(type, packageName, callingUid, userId,
6813                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6814
6815            } catch (RemoteException e) {
6816                throw new SecurityException(e);
6817            }
6818        }
6819    }
6820
6821    IIntentSender getIntentSenderLocked(int type, String packageName,
6822            int callingUid, int userId, IBinder token, String resultWho,
6823            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6824            Bundle bOptions) {
6825        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6826        ActivityRecord activity = null;
6827        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6828            activity = ActivityRecord.isInStackLocked(token);
6829            if (activity == null) {
6830                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6831                return null;
6832            }
6833            if (activity.finishing) {
6834                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6835                return null;
6836            }
6837        }
6838
6839        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6840        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6841        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6842        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6843                |PendingIntent.FLAG_UPDATE_CURRENT);
6844
6845        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6846                type, packageName, activity, resultWho,
6847                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6848        WeakReference<PendingIntentRecord> ref;
6849        ref = mIntentSenderRecords.get(key);
6850        PendingIntentRecord rec = ref != null ? ref.get() : null;
6851        if (rec != null) {
6852            if (!cancelCurrent) {
6853                if (updateCurrent) {
6854                    if (rec.key.requestIntent != null) {
6855                        rec.key.requestIntent.replaceExtras(intents != null ?
6856                                intents[intents.length - 1] : null);
6857                    }
6858                    if (intents != null) {
6859                        intents[intents.length-1] = rec.key.requestIntent;
6860                        rec.key.allIntents = intents;
6861                        rec.key.allResolvedTypes = resolvedTypes;
6862                    } else {
6863                        rec.key.allIntents = null;
6864                        rec.key.allResolvedTypes = null;
6865                    }
6866                }
6867                return rec;
6868            }
6869            rec.canceled = true;
6870            mIntentSenderRecords.remove(key);
6871        }
6872        if (noCreate) {
6873            return rec;
6874        }
6875        rec = new PendingIntentRecord(this, key, callingUid);
6876        mIntentSenderRecords.put(key, rec.ref);
6877        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6878            if (activity.pendingResults == null) {
6879                activity.pendingResults
6880                        = new HashSet<WeakReference<PendingIntentRecord>>();
6881            }
6882            activity.pendingResults.add(rec.ref);
6883        }
6884        return rec;
6885    }
6886
6887    @Override
6888    public void cancelIntentSender(IIntentSender sender) {
6889        if (!(sender instanceof PendingIntentRecord)) {
6890            return;
6891        }
6892        synchronized(this) {
6893            PendingIntentRecord rec = (PendingIntentRecord)sender;
6894            try {
6895                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6896                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6897                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6898                    String msg = "Permission Denial: cancelIntentSender() from pid="
6899                        + Binder.getCallingPid()
6900                        + ", uid=" + Binder.getCallingUid()
6901                        + " is not allowed to cancel packges "
6902                        + rec.key.packageName;
6903                    Slog.w(TAG, msg);
6904                    throw new SecurityException(msg);
6905                }
6906            } catch (RemoteException e) {
6907                throw new SecurityException(e);
6908            }
6909            cancelIntentSenderLocked(rec, true);
6910        }
6911    }
6912
6913    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6914        rec.canceled = true;
6915        mIntentSenderRecords.remove(rec.key);
6916        if (cleanActivity && rec.key.activity != null) {
6917            rec.key.activity.pendingResults.remove(rec.ref);
6918        }
6919    }
6920
6921    @Override
6922    public String getPackageForIntentSender(IIntentSender pendingResult) {
6923        if (!(pendingResult instanceof PendingIntentRecord)) {
6924            return null;
6925        }
6926        try {
6927            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6928            return res.key.packageName;
6929        } catch (ClassCastException e) {
6930        }
6931        return null;
6932    }
6933
6934    @Override
6935    public int getUidForIntentSender(IIntentSender sender) {
6936        if (sender instanceof PendingIntentRecord) {
6937            try {
6938                PendingIntentRecord res = (PendingIntentRecord)sender;
6939                return res.uid;
6940            } catch (ClassCastException e) {
6941            }
6942        }
6943        return -1;
6944    }
6945
6946    @Override
6947    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6948        if (!(pendingResult instanceof PendingIntentRecord)) {
6949            return false;
6950        }
6951        try {
6952            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6953            if (res.key.allIntents == null) {
6954                return false;
6955            }
6956            for (int i=0; i<res.key.allIntents.length; i++) {
6957                Intent intent = res.key.allIntents[i];
6958                if (intent.getPackage() != null && intent.getComponent() != null) {
6959                    return false;
6960                }
6961            }
6962            return true;
6963        } catch (ClassCastException e) {
6964        }
6965        return false;
6966    }
6967
6968    @Override
6969    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6970        if (!(pendingResult instanceof PendingIntentRecord)) {
6971            return false;
6972        }
6973        try {
6974            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6975            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6976                return true;
6977            }
6978            return false;
6979        } catch (ClassCastException e) {
6980        }
6981        return false;
6982    }
6983
6984    @Override
6985    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6986        if (!(pendingResult instanceof PendingIntentRecord)) {
6987            return null;
6988        }
6989        try {
6990            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6991            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6992        } catch (ClassCastException e) {
6993        }
6994        return null;
6995    }
6996
6997    @Override
6998    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6999        if (!(pendingResult instanceof PendingIntentRecord)) {
7000            return null;
7001        }
7002        try {
7003            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7004            synchronized (this) {
7005                return getTagForIntentSenderLocked(res, prefix);
7006            }
7007        } catch (ClassCastException e) {
7008        }
7009        return null;
7010    }
7011
7012    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7013        final Intent intent = res.key.requestIntent;
7014        if (intent != null) {
7015            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7016                    || res.lastTagPrefix.equals(prefix))) {
7017                return res.lastTag;
7018            }
7019            res.lastTagPrefix = prefix;
7020            final StringBuilder sb = new StringBuilder(128);
7021            if (prefix != null) {
7022                sb.append(prefix);
7023            }
7024            if (intent.getAction() != null) {
7025                sb.append(intent.getAction());
7026            } else if (intent.getComponent() != null) {
7027                intent.getComponent().appendShortString(sb);
7028            } else {
7029                sb.append("?");
7030            }
7031            return res.lastTag = sb.toString();
7032        }
7033        return null;
7034    }
7035
7036    @Override
7037    public void setProcessLimit(int max) {
7038        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7039                "setProcessLimit()");
7040        synchronized (this) {
7041            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7042            mProcessLimitOverride = max;
7043        }
7044        trimApplications();
7045    }
7046
7047    @Override
7048    public int getProcessLimit() {
7049        synchronized (this) {
7050            return mProcessLimitOverride;
7051        }
7052    }
7053
7054    void foregroundTokenDied(ForegroundToken token) {
7055        synchronized (ActivityManagerService.this) {
7056            synchronized (mPidsSelfLocked) {
7057                ForegroundToken cur
7058                    = mForegroundProcesses.get(token.pid);
7059                if (cur != token) {
7060                    return;
7061                }
7062                mForegroundProcesses.remove(token.pid);
7063                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7064                if (pr == null) {
7065                    return;
7066                }
7067                pr.forcingToForeground = null;
7068                updateProcessForegroundLocked(pr, false, false);
7069            }
7070            updateOomAdjLocked();
7071        }
7072    }
7073
7074    @Override
7075    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7076        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7077                "setProcessForeground()");
7078        synchronized(this) {
7079            boolean changed = false;
7080
7081            synchronized (mPidsSelfLocked) {
7082                ProcessRecord pr = mPidsSelfLocked.get(pid);
7083                if (pr == null && isForeground) {
7084                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7085                    return;
7086                }
7087                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7088                if (oldToken != null) {
7089                    oldToken.token.unlinkToDeath(oldToken, 0);
7090                    mForegroundProcesses.remove(pid);
7091                    if (pr != null) {
7092                        pr.forcingToForeground = null;
7093                    }
7094                    changed = true;
7095                }
7096                if (isForeground && token != null) {
7097                    ForegroundToken newToken = new ForegroundToken() {
7098                        @Override
7099                        public void binderDied() {
7100                            foregroundTokenDied(this);
7101                        }
7102                    };
7103                    newToken.pid = pid;
7104                    newToken.token = token;
7105                    try {
7106                        token.linkToDeath(newToken, 0);
7107                        mForegroundProcesses.put(pid, newToken);
7108                        pr.forcingToForeground = token;
7109                        changed = true;
7110                    } catch (RemoteException e) {
7111                        // If the process died while doing this, we will later
7112                        // do the cleanup with the process death link.
7113                    }
7114                }
7115            }
7116
7117            if (changed) {
7118                updateOomAdjLocked();
7119            }
7120        }
7121    }
7122
7123    @Override
7124    public boolean isAppForeground(int uid) throws RemoteException {
7125        synchronized (this) {
7126            UidRecord uidRec = mActiveUids.get(uid);
7127            if (uidRec == null || uidRec.idle) {
7128                return false;
7129            }
7130            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7131        }
7132    }
7133
7134    @Override
7135    public boolean inMultiWindow(IBinder token) {
7136        final long origId = Binder.clearCallingIdentity();
7137        try {
7138            synchronized(this) {
7139                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7140                if (r == null) {
7141                    return false;
7142                }
7143                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7144                return !r.task.mFullscreen;
7145            }
7146        } finally {
7147            Binder.restoreCallingIdentity(origId);
7148        }
7149    }
7150
7151    @Override
7152    public boolean inPictureInPicture(IBinder token) {
7153        final long origId = Binder.clearCallingIdentity();
7154        try {
7155            synchronized(this) {
7156                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7157                if (stack == null) {
7158                    return false;
7159                }
7160                return stack.mStackId == PINNED_STACK_ID;
7161            }
7162        } finally {
7163            Binder.restoreCallingIdentity(origId);
7164        }
7165    }
7166
7167    @Override
7168    public void enterPictureInPicture(IBinder token) {
7169        final long origId = Binder.clearCallingIdentity();
7170        try {
7171            synchronized(this) {
7172                if (!mSupportsPictureInPicture) {
7173                    throw new IllegalStateException("enterPictureInPicture: "
7174                            + "Device doesn't support picture-in-picture mode.");
7175                }
7176
7177                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7178
7179                if (r == null) {
7180                    throw new IllegalStateException("enterPictureInPicture: "
7181                            + "Can't find activity for token=" + token);
7182                }
7183
7184                if (!r.supportsPictureInPicture()) {
7185                    throw new IllegalArgumentException("enterPictureInPicture: "
7186                            + "Picture-In-Picture not supported for r=" + r);
7187                }
7188
7189                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7190                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7191                        ? mDefaultPinnedStackBounds : null;
7192
7193                mStackSupervisor.moveActivityToPinnedStackLocked(
7194                        r, "enterPictureInPicture", bounds);
7195            }
7196        } finally {
7197            Binder.restoreCallingIdentity(origId);
7198        }
7199    }
7200
7201    // =========================================================
7202    // PROCESS INFO
7203    // =========================================================
7204
7205    static class ProcessInfoService extends IProcessInfoService.Stub {
7206        final ActivityManagerService mActivityManagerService;
7207        ProcessInfoService(ActivityManagerService activityManagerService) {
7208            mActivityManagerService = activityManagerService;
7209        }
7210
7211        @Override
7212        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7213            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7214                    /*in*/ pids, /*out*/ states, null);
7215        }
7216
7217        @Override
7218        public void getProcessStatesAndOomScoresFromPids(
7219                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7220            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7221                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7222        }
7223    }
7224
7225    /**
7226     * For each PID in the given input array, write the current process state
7227     * for that process into the states array, or -1 to indicate that no
7228     * process with the given PID exists. If scores array is provided, write
7229     * the oom score for the process into the scores array, with INVALID_ADJ
7230     * indicating the PID doesn't exist.
7231     */
7232    public void getProcessStatesAndOomScoresForPIDs(
7233            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7234        if (scores != null) {
7235            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7236                    "getProcessStatesAndOomScoresForPIDs()");
7237        }
7238
7239        if (pids == null) {
7240            throw new NullPointerException("pids");
7241        } else if (states == null) {
7242            throw new NullPointerException("states");
7243        } else if (pids.length != states.length) {
7244            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7245        } else if (scores != null && pids.length != scores.length) {
7246            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7247        }
7248
7249        synchronized (mPidsSelfLocked) {
7250            for (int i = 0; i < pids.length; i++) {
7251                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7252                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7253                        pr.curProcState;
7254                if (scores != null) {
7255                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7256                }
7257            }
7258        }
7259    }
7260
7261    // =========================================================
7262    // PERMISSIONS
7263    // =========================================================
7264
7265    static class PermissionController extends IPermissionController.Stub {
7266        ActivityManagerService mActivityManagerService;
7267        PermissionController(ActivityManagerService activityManagerService) {
7268            mActivityManagerService = activityManagerService;
7269        }
7270
7271        @Override
7272        public boolean checkPermission(String permission, int pid, int uid) {
7273            return mActivityManagerService.checkPermission(permission, pid,
7274                    uid) == PackageManager.PERMISSION_GRANTED;
7275        }
7276
7277        @Override
7278        public String[] getPackagesForUid(int uid) {
7279            return mActivityManagerService.mContext.getPackageManager()
7280                    .getPackagesForUid(uid);
7281        }
7282
7283        @Override
7284        public boolean isRuntimePermission(String permission) {
7285            try {
7286                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7287                        .getPermissionInfo(permission, 0);
7288                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7289            } catch (NameNotFoundException nnfe) {
7290                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7291            }
7292            return false;
7293        }
7294    }
7295
7296    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7297        @Override
7298        public int checkComponentPermission(String permission, int pid, int uid,
7299                int owningUid, boolean exported) {
7300            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7301                    owningUid, exported);
7302        }
7303
7304        @Override
7305        public Object getAMSLock() {
7306            return ActivityManagerService.this;
7307        }
7308    }
7309
7310    /**
7311     * This can be called with or without the global lock held.
7312     */
7313    int checkComponentPermission(String permission, int pid, int uid,
7314            int owningUid, boolean exported) {
7315        if (pid == MY_PID) {
7316            return PackageManager.PERMISSION_GRANTED;
7317        }
7318        return ActivityManager.checkComponentPermission(permission, uid,
7319                owningUid, exported);
7320    }
7321
7322    /**
7323     * As the only public entry point for permissions checking, this method
7324     * can enforce the semantic that requesting a check on a null global
7325     * permission is automatically denied.  (Internally a null permission
7326     * string is used when calling {@link #checkComponentPermission} in cases
7327     * when only uid-based security is needed.)
7328     *
7329     * This can be called with or without the global lock held.
7330     */
7331    @Override
7332    public int checkPermission(String permission, int pid, int uid) {
7333        if (permission == null) {
7334            return PackageManager.PERMISSION_DENIED;
7335        }
7336        return checkComponentPermission(permission, pid, uid, -1, true);
7337    }
7338
7339    @Override
7340    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7341        if (permission == null) {
7342            return PackageManager.PERMISSION_DENIED;
7343        }
7344
7345        // We might be performing an operation on behalf of an indirect binder
7346        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7347        // client identity accordingly before proceeding.
7348        Identity tlsIdentity = sCallerIdentity.get();
7349        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7350            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7351                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7352            uid = tlsIdentity.uid;
7353            pid = tlsIdentity.pid;
7354        }
7355
7356        return checkComponentPermission(permission, pid, uid, -1, true);
7357    }
7358
7359    /**
7360     * Binder IPC calls go through the public entry point.
7361     * This can be called with or without the global lock held.
7362     */
7363    int checkCallingPermission(String permission) {
7364        return checkPermission(permission,
7365                Binder.getCallingPid(),
7366                UserHandle.getAppId(Binder.getCallingUid()));
7367    }
7368
7369    /**
7370     * This can be called with or without the global lock held.
7371     */
7372    void enforceCallingPermission(String permission, String func) {
7373        if (checkCallingPermission(permission)
7374                == PackageManager.PERMISSION_GRANTED) {
7375            return;
7376        }
7377
7378        String msg = "Permission Denial: " + func + " from pid="
7379                + Binder.getCallingPid()
7380                + ", uid=" + Binder.getCallingUid()
7381                + " requires " + permission;
7382        Slog.w(TAG, msg);
7383        throw new SecurityException(msg);
7384    }
7385
7386    /**
7387     * Determine if UID is holding permissions required to access {@link Uri} in
7388     * the given {@link ProviderInfo}. Final permission checking is always done
7389     * in {@link ContentProvider}.
7390     */
7391    private final boolean checkHoldingPermissionsLocked(
7392            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7393        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7394                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7395        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7396            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7397                    != PERMISSION_GRANTED) {
7398                return false;
7399            }
7400        }
7401        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7402    }
7403
7404    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7405            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7406        if (pi.applicationInfo.uid == uid) {
7407            return true;
7408        } else if (!pi.exported) {
7409            return false;
7410        }
7411
7412        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7413        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7414        try {
7415            // check if target holds top-level <provider> permissions
7416            if (!readMet && pi.readPermission != null && considerUidPermissions
7417                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7418                readMet = true;
7419            }
7420            if (!writeMet && pi.writePermission != null && considerUidPermissions
7421                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7422                writeMet = true;
7423            }
7424
7425            // track if unprotected read/write is allowed; any denied
7426            // <path-permission> below removes this ability
7427            boolean allowDefaultRead = pi.readPermission == null;
7428            boolean allowDefaultWrite = pi.writePermission == null;
7429
7430            // check if target holds any <path-permission> that match uri
7431            final PathPermission[] pps = pi.pathPermissions;
7432            if (pps != null) {
7433                final String path = grantUri.uri.getPath();
7434                int i = pps.length;
7435                while (i > 0 && (!readMet || !writeMet)) {
7436                    i--;
7437                    PathPermission pp = pps[i];
7438                    if (pp.match(path)) {
7439                        if (!readMet) {
7440                            final String pprperm = pp.getReadPermission();
7441                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7442                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7443                                    + ": match=" + pp.match(path)
7444                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7445                            if (pprperm != null) {
7446                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7447                                        == PERMISSION_GRANTED) {
7448                                    readMet = true;
7449                                } else {
7450                                    allowDefaultRead = false;
7451                                }
7452                            }
7453                        }
7454                        if (!writeMet) {
7455                            final String ppwperm = pp.getWritePermission();
7456                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7457                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7458                                    + ": match=" + pp.match(path)
7459                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7460                            if (ppwperm != null) {
7461                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7462                                        == PERMISSION_GRANTED) {
7463                                    writeMet = true;
7464                                } else {
7465                                    allowDefaultWrite = false;
7466                                }
7467                            }
7468                        }
7469                    }
7470                }
7471            }
7472
7473            // grant unprotected <provider> read/write, if not blocked by
7474            // <path-permission> above
7475            if (allowDefaultRead) readMet = true;
7476            if (allowDefaultWrite) writeMet = true;
7477
7478        } catch (RemoteException e) {
7479            return false;
7480        }
7481
7482        return readMet && writeMet;
7483    }
7484
7485    public int getAppStartMode(int uid, String packageName) {
7486        synchronized (this) {
7487            return checkAllowBackgroundLocked(uid, packageName, -1);
7488        }
7489    }
7490
7491    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7492        UidRecord uidRec = mActiveUids.get(uid);
7493        if (uidRec == null || uidRec.idle) {
7494            if (callingPid >= 0) {
7495                ProcessRecord proc;
7496                synchronized (mPidsSelfLocked) {
7497                    proc = mPidsSelfLocked.get(callingPid);
7498                }
7499                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7500                    // Whoever is instigating this is in the foreground, so we will allow it
7501                    // to go through.
7502                    return ActivityManager.APP_START_MODE_NORMAL;
7503                }
7504            }
7505            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7506                    != AppOpsManager.MODE_ALLOWED) {
7507                return ActivityManager.APP_START_MODE_DELAYED;
7508            }
7509        }
7510        return ActivityManager.APP_START_MODE_NORMAL;
7511    }
7512
7513    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7514        ProviderInfo pi = null;
7515        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7516        if (cpr != null) {
7517            pi = cpr.info;
7518        } else {
7519            try {
7520                pi = AppGlobals.getPackageManager().resolveContentProvider(
7521                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7522            } catch (RemoteException ex) {
7523            }
7524        }
7525        return pi;
7526    }
7527
7528    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7529        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7530        if (targetUris != null) {
7531            return targetUris.get(grantUri);
7532        }
7533        return null;
7534    }
7535
7536    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7537            String targetPkg, int targetUid, GrantUri grantUri) {
7538        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7539        if (targetUris == null) {
7540            targetUris = Maps.newArrayMap();
7541            mGrantedUriPermissions.put(targetUid, targetUris);
7542        }
7543
7544        UriPermission perm = targetUris.get(grantUri);
7545        if (perm == null) {
7546            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7547            targetUris.put(grantUri, perm);
7548        }
7549
7550        return perm;
7551    }
7552
7553    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7554            final int modeFlags) {
7555        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7556        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7557                : UriPermission.STRENGTH_OWNED;
7558
7559        // Root gets to do everything.
7560        if (uid == 0) {
7561            return true;
7562        }
7563
7564        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7565        if (perms == null) return false;
7566
7567        // First look for exact match
7568        final UriPermission exactPerm = perms.get(grantUri);
7569        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7570            return true;
7571        }
7572
7573        // No exact match, look for prefixes
7574        final int N = perms.size();
7575        for (int i = 0; i < N; i++) {
7576            final UriPermission perm = perms.valueAt(i);
7577            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7578                    && perm.getStrength(modeFlags) >= minStrength) {
7579                return true;
7580            }
7581        }
7582
7583        return false;
7584    }
7585
7586    /**
7587     * @param uri This uri must NOT contain an embedded userId.
7588     * @param userId The userId in which the uri is to be resolved.
7589     */
7590    @Override
7591    public int checkUriPermission(Uri uri, int pid, int uid,
7592            final int modeFlags, int userId, IBinder callerToken) {
7593        enforceNotIsolatedCaller("checkUriPermission");
7594
7595        // Another redirected-binder-call permissions check as in
7596        // {@link checkPermissionWithToken}.
7597        Identity tlsIdentity = sCallerIdentity.get();
7598        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7599            uid = tlsIdentity.uid;
7600            pid = tlsIdentity.pid;
7601        }
7602
7603        // Our own process gets to do everything.
7604        if (pid == MY_PID) {
7605            return PackageManager.PERMISSION_GRANTED;
7606        }
7607        synchronized (this) {
7608            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7609                    ? PackageManager.PERMISSION_GRANTED
7610                    : PackageManager.PERMISSION_DENIED;
7611        }
7612    }
7613
7614    /**
7615     * Check if the targetPkg can be granted permission to access uri by
7616     * the callingUid using the given modeFlags.  Throws a security exception
7617     * if callingUid is not allowed to do this.  Returns the uid of the target
7618     * if the URI permission grant should be performed; returns -1 if it is not
7619     * needed (for example targetPkg already has permission to access the URI).
7620     * If you already know the uid of the target, you can supply it in
7621     * lastTargetUid else set that to -1.
7622     */
7623    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7624            final int modeFlags, int lastTargetUid) {
7625        if (!Intent.isAccessUriMode(modeFlags)) {
7626            return -1;
7627        }
7628
7629        if (targetPkg != null) {
7630            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7631                    "Checking grant " + targetPkg + " permission to " + grantUri);
7632        }
7633
7634        final IPackageManager pm = AppGlobals.getPackageManager();
7635
7636        // If this is not a content: uri, we can't do anything with it.
7637        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7638            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7639                    "Can't grant URI permission for non-content URI: " + grantUri);
7640            return -1;
7641        }
7642
7643        final String authority = grantUri.uri.getAuthority();
7644        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7645        if (pi == null) {
7646            Slog.w(TAG, "No content provider found for permission check: " +
7647                    grantUri.uri.toSafeString());
7648            return -1;
7649        }
7650
7651        int targetUid = lastTargetUid;
7652        if (targetUid < 0 && targetPkg != null) {
7653            try {
7654                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7655                        UserHandle.getUserId(callingUid));
7656                if (targetUid < 0) {
7657                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7658                            "Can't grant URI permission no uid for: " + targetPkg);
7659                    return -1;
7660                }
7661            } catch (RemoteException ex) {
7662                return -1;
7663            }
7664        }
7665
7666        if (targetUid >= 0) {
7667            // First...  does the target actually need this permission?
7668            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7669                // No need to grant the target this permission.
7670                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7671                        "Target " + targetPkg + " already has full permission to " + grantUri);
7672                return -1;
7673            }
7674        } else {
7675            // First...  there is no target package, so can anyone access it?
7676            boolean allowed = pi.exported;
7677            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7678                if (pi.readPermission != null) {
7679                    allowed = false;
7680                }
7681            }
7682            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7683                if (pi.writePermission != null) {
7684                    allowed = false;
7685                }
7686            }
7687            if (allowed) {
7688                return -1;
7689            }
7690        }
7691
7692        /* There is a special cross user grant if:
7693         * - The target is on another user.
7694         * - Apps on the current user can access the uri without any uid permissions.
7695         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7696         * grant uri permissions.
7697         */
7698        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7699                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7700                modeFlags, false /*without considering the uid permissions*/);
7701
7702        // Second...  is the provider allowing granting of URI permissions?
7703        if (!specialCrossUserGrant) {
7704            if (!pi.grantUriPermissions) {
7705                throw new SecurityException("Provider " + pi.packageName
7706                        + "/" + pi.name
7707                        + " does not allow granting of Uri permissions (uri "
7708                        + grantUri + ")");
7709            }
7710            if (pi.uriPermissionPatterns != null) {
7711                final int N = pi.uriPermissionPatterns.length;
7712                boolean allowed = false;
7713                for (int i=0; i<N; i++) {
7714                    if (pi.uriPermissionPatterns[i] != null
7715                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7716                        allowed = true;
7717                        break;
7718                    }
7719                }
7720                if (!allowed) {
7721                    throw new SecurityException("Provider " + pi.packageName
7722                            + "/" + pi.name
7723                            + " does not allow granting of permission to path of Uri "
7724                            + grantUri);
7725                }
7726            }
7727        }
7728
7729        // Third...  does the caller itself have permission to access
7730        // this uri?
7731        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7732            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7733                // Require they hold a strong enough Uri permission
7734                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7735                    throw new SecurityException("Uid " + callingUid
7736                            + " does not have permission to uri " + grantUri);
7737                }
7738            }
7739        }
7740        return targetUid;
7741    }
7742
7743    /**
7744     * @param uri This uri must NOT contain an embedded userId.
7745     * @param userId The userId in which the uri is to be resolved.
7746     */
7747    @Override
7748    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7749            final int modeFlags, int userId) {
7750        enforceNotIsolatedCaller("checkGrantUriPermission");
7751        synchronized(this) {
7752            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7753                    new GrantUri(userId, uri, false), modeFlags, -1);
7754        }
7755    }
7756
7757    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7758            final int modeFlags, UriPermissionOwner owner) {
7759        if (!Intent.isAccessUriMode(modeFlags)) {
7760            return;
7761        }
7762
7763        // So here we are: the caller has the assumed permission
7764        // to the uri, and the target doesn't.  Let's now give this to
7765        // the target.
7766
7767        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7769
7770        final String authority = grantUri.uri.getAuthority();
7771        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7772        if (pi == null) {
7773            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7774            return;
7775        }
7776
7777        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7778            grantUri.prefix = true;
7779        }
7780        final UriPermission perm = findOrCreateUriPermissionLocked(
7781                pi.packageName, targetPkg, targetUid, grantUri);
7782        perm.grantModes(modeFlags, owner);
7783    }
7784
7785    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7786            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7787        if (targetPkg == null) {
7788            throw new NullPointerException("targetPkg");
7789        }
7790        int targetUid;
7791        final IPackageManager pm = AppGlobals.getPackageManager();
7792        try {
7793            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7794        } catch (RemoteException ex) {
7795            return;
7796        }
7797
7798        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7799                targetUid);
7800        if (targetUid < 0) {
7801            return;
7802        }
7803
7804        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7805                owner);
7806    }
7807
7808    static class NeededUriGrants extends ArrayList<GrantUri> {
7809        final String targetPkg;
7810        final int targetUid;
7811        final int flags;
7812
7813        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7814            this.targetPkg = targetPkg;
7815            this.targetUid = targetUid;
7816            this.flags = flags;
7817        }
7818    }
7819
7820    /**
7821     * Like checkGrantUriPermissionLocked, but takes an Intent.
7822     */
7823    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7824            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7825        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7826                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7827                + " clip=" + (intent != null ? intent.getClipData() : null)
7828                + " from " + intent + "; flags=0x"
7829                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7830
7831        if (targetPkg == null) {
7832            throw new NullPointerException("targetPkg");
7833        }
7834
7835        if (intent == null) {
7836            return null;
7837        }
7838        Uri data = intent.getData();
7839        ClipData clip = intent.getClipData();
7840        if (data == null && clip == null) {
7841            return null;
7842        }
7843        // Default userId for uris in the intent (if they don't specify it themselves)
7844        int contentUserHint = intent.getContentUserHint();
7845        if (contentUserHint == UserHandle.USER_CURRENT) {
7846            contentUserHint = UserHandle.getUserId(callingUid);
7847        }
7848        final IPackageManager pm = AppGlobals.getPackageManager();
7849        int targetUid;
7850        if (needed != null) {
7851            targetUid = needed.targetUid;
7852        } else {
7853            try {
7854                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7855                        targetUserId);
7856            } catch (RemoteException ex) {
7857                return null;
7858            }
7859            if (targetUid < 0) {
7860                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7861                        "Can't grant URI permission no uid for: " + targetPkg
7862                        + " on user " + targetUserId);
7863                return null;
7864            }
7865        }
7866        if (data != null) {
7867            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7868            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7869                    targetUid);
7870            if (targetUid > 0) {
7871                if (needed == null) {
7872                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7873                }
7874                needed.add(grantUri);
7875            }
7876        }
7877        if (clip != null) {
7878            for (int i=0; i<clip.getItemCount(); i++) {
7879                Uri uri = clip.getItemAt(i).getUri();
7880                if (uri != null) {
7881                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7882                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7883                            targetUid);
7884                    if (targetUid > 0) {
7885                        if (needed == null) {
7886                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7887                        }
7888                        needed.add(grantUri);
7889                    }
7890                } else {
7891                    Intent clipIntent = clip.getItemAt(i).getIntent();
7892                    if (clipIntent != null) {
7893                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7894                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7895                        if (newNeeded != null) {
7896                            needed = newNeeded;
7897                        }
7898                    }
7899                }
7900            }
7901        }
7902
7903        return needed;
7904    }
7905
7906    /**
7907     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7908     */
7909    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7910            UriPermissionOwner owner) {
7911        if (needed != null) {
7912            for (int i=0; i<needed.size(); i++) {
7913                GrantUri grantUri = needed.get(i);
7914                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7915                        grantUri, needed.flags, owner);
7916            }
7917        }
7918    }
7919
7920    void grantUriPermissionFromIntentLocked(int callingUid,
7921            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7922        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7923                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7924        if (needed == null) {
7925            return;
7926        }
7927
7928        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7929    }
7930
7931    /**
7932     * @param uri This uri must NOT contain an embedded userId.
7933     * @param userId The userId in which the uri is to be resolved.
7934     */
7935    @Override
7936    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7937            final int modeFlags, int userId) {
7938        enforceNotIsolatedCaller("grantUriPermission");
7939        GrantUri grantUri = new GrantUri(userId, uri, false);
7940        synchronized(this) {
7941            final ProcessRecord r = getRecordForAppLocked(caller);
7942            if (r == null) {
7943                throw new SecurityException("Unable to find app for caller "
7944                        + caller
7945                        + " when granting permission to uri " + grantUri);
7946            }
7947            if (targetPkg == null) {
7948                throw new IllegalArgumentException("null target");
7949            }
7950            if (grantUri == null) {
7951                throw new IllegalArgumentException("null uri");
7952            }
7953
7954            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7955                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7956                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7957                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7958
7959            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7960                    UserHandle.getUserId(r.uid));
7961        }
7962    }
7963
7964    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7965        if (perm.modeFlags == 0) {
7966            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7967                    perm.targetUid);
7968            if (perms != null) {
7969                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7970                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7971
7972                perms.remove(perm.uri);
7973                if (perms.isEmpty()) {
7974                    mGrantedUriPermissions.remove(perm.targetUid);
7975                }
7976            }
7977        }
7978    }
7979
7980    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7981        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                "Revoking all granted permissions to " + grantUri);
7983
7984        final IPackageManager pm = AppGlobals.getPackageManager();
7985        final String authority = grantUri.uri.getAuthority();
7986        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7987        if (pi == null) {
7988            Slog.w(TAG, "No content provider found for permission revoke: "
7989                    + grantUri.toSafeString());
7990            return;
7991        }
7992
7993        // Does the caller have this permission on the URI?
7994        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7995            // If they don't have direct access to the URI, then revoke any
7996            // ownerless URI permissions that have been granted to them.
7997            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7998            if (perms != null) {
7999                boolean persistChanged = false;
8000                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8001                    final UriPermission perm = it.next();
8002                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8003                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8004                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8005                                "Revoking non-owned " + perm.targetUid
8006                                + " permission to " + perm.uri);
8007                        persistChanged |= perm.revokeModes(
8008                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8009                        if (perm.modeFlags == 0) {
8010                            it.remove();
8011                        }
8012                    }
8013                }
8014                if (perms.isEmpty()) {
8015                    mGrantedUriPermissions.remove(callingUid);
8016                }
8017                if (persistChanged) {
8018                    schedulePersistUriGrants();
8019                }
8020            }
8021            return;
8022        }
8023
8024        boolean persistChanged = false;
8025
8026        // Go through all of the permissions and remove any that match.
8027        int N = mGrantedUriPermissions.size();
8028        for (int i = 0; i < N; i++) {
8029            final int targetUid = mGrantedUriPermissions.keyAt(i);
8030            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8031
8032            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8033                final UriPermission perm = it.next();
8034                if (perm.uri.sourceUserId == grantUri.sourceUserId
8035                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8036                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8037                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8038                    persistChanged |= perm.revokeModes(
8039                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8040                    if (perm.modeFlags == 0) {
8041                        it.remove();
8042                    }
8043                }
8044            }
8045
8046            if (perms.isEmpty()) {
8047                mGrantedUriPermissions.remove(targetUid);
8048                N--;
8049                i--;
8050            }
8051        }
8052
8053        if (persistChanged) {
8054            schedulePersistUriGrants();
8055        }
8056    }
8057
8058    /**
8059     * @param uri This uri must NOT contain an embedded userId.
8060     * @param userId The userId in which the uri is to be resolved.
8061     */
8062    @Override
8063    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8064            int userId) {
8065        enforceNotIsolatedCaller("revokeUriPermission");
8066        synchronized(this) {
8067            final ProcessRecord r = getRecordForAppLocked(caller);
8068            if (r == null) {
8069                throw new SecurityException("Unable to find app for caller "
8070                        + caller
8071                        + " when revoking permission to uri " + uri);
8072            }
8073            if (uri == null) {
8074                Slog.w(TAG, "revokeUriPermission: null uri");
8075                return;
8076            }
8077
8078            if (!Intent.isAccessUriMode(modeFlags)) {
8079                return;
8080            }
8081
8082            final String authority = uri.getAuthority();
8083            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8084            if (pi == null) {
8085                Slog.w(TAG, "No content provider found for permission revoke: "
8086                        + uri.toSafeString());
8087                return;
8088            }
8089
8090            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8091        }
8092    }
8093
8094    /**
8095     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8096     * given package.
8097     *
8098     * @param packageName Package name to match, or {@code null} to apply to all
8099     *            packages.
8100     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8101     *            to all users.
8102     * @param persistable If persistable grants should be removed.
8103     */
8104    private void removeUriPermissionsForPackageLocked(
8105            String packageName, int userHandle, boolean persistable) {
8106        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8107            throw new IllegalArgumentException("Must narrow by either package or user");
8108        }
8109
8110        boolean persistChanged = false;
8111
8112        int N = mGrantedUriPermissions.size();
8113        for (int i = 0; i < N; i++) {
8114            final int targetUid = mGrantedUriPermissions.keyAt(i);
8115            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8116
8117            // Only inspect grants matching user
8118            if (userHandle == UserHandle.USER_ALL
8119                    || userHandle == UserHandle.getUserId(targetUid)) {
8120                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8121                    final UriPermission perm = it.next();
8122
8123                    // Only inspect grants matching package
8124                    if (packageName == null || perm.sourcePkg.equals(packageName)
8125                            || perm.targetPkg.equals(packageName)) {
8126                        persistChanged |= perm.revokeModes(persistable
8127                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8128
8129                        // Only remove when no modes remain; any persisted grants
8130                        // will keep this alive.
8131                        if (perm.modeFlags == 0) {
8132                            it.remove();
8133                        }
8134                    }
8135                }
8136
8137                if (perms.isEmpty()) {
8138                    mGrantedUriPermissions.remove(targetUid);
8139                    N--;
8140                    i--;
8141                }
8142            }
8143        }
8144
8145        if (persistChanged) {
8146            schedulePersistUriGrants();
8147        }
8148    }
8149
8150    @Override
8151    public IBinder newUriPermissionOwner(String name) {
8152        enforceNotIsolatedCaller("newUriPermissionOwner");
8153        synchronized(this) {
8154            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8155            return owner.getExternalTokenLocked();
8156        }
8157    }
8158
8159    @Override
8160    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8161        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8162        synchronized(this) {
8163            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8164            if (r == null) {
8165                throw new IllegalArgumentException("Activity does not exist; token="
8166                        + activityToken);
8167            }
8168            return r.getUriPermissionsLocked().getExternalTokenLocked();
8169        }
8170    }
8171    /**
8172     * @param uri This uri must NOT contain an embedded userId.
8173     * @param sourceUserId The userId in which the uri is to be resolved.
8174     * @param targetUserId The userId of the app that receives the grant.
8175     */
8176    @Override
8177    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8178            final int modeFlags, int sourceUserId, int targetUserId) {
8179        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8180                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8181                "grantUriPermissionFromOwner", null);
8182        synchronized(this) {
8183            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8184            if (owner == null) {
8185                throw new IllegalArgumentException("Unknown owner: " + token);
8186            }
8187            if (fromUid != Binder.getCallingUid()) {
8188                if (Binder.getCallingUid() != Process.myUid()) {
8189                    // Only system code can grant URI permissions on behalf
8190                    // of other users.
8191                    throw new SecurityException("nice try");
8192                }
8193            }
8194            if (targetPkg == null) {
8195                throw new IllegalArgumentException("null target");
8196            }
8197            if (uri == null) {
8198                throw new IllegalArgumentException("null uri");
8199            }
8200
8201            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8202                    modeFlags, owner, targetUserId);
8203        }
8204    }
8205
8206    /**
8207     * @param uri This uri must NOT contain an embedded userId.
8208     * @param userId The userId in which the uri is to be resolved.
8209     */
8210    @Override
8211    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8212        synchronized(this) {
8213            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8214            if (owner == null) {
8215                throw new IllegalArgumentException("Unknown owner: " + token);
8216            }
8217
8218            if (uri == null) {
8219                owner.removeUriPermissionsLocked(mode);
8220            } else {
8221                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8222            }
8223        }
8224    }
8225
8226    private void schedulePersistUriGrants() {
8227        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8228            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8229                    10 * DateUtils.SECOND_IN_MILLIS);
8230        }
8231    }
8232
8233    private void writeGrantedUriPermissions() {
8234        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8235
8236        // Snapshot permissions so we can persist without lock
8237        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8238        synchronized (this) {
8239            final int size = mGrantedUriPermissions.size();
8240            for (int i = 0; i < size; i++) {
8241                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8242                for (UriPermission perm : perms.values()) {
8243                    if (perm.persistedModeFlags != 0) {
8244                        persist.add(perm.snapshot());
8245                    }
8246                }
8247            }
8248        }
8249
8250        FileOutputStream fos = null;
8251        try {
8252            fos = mGrantFile.startWrite();
8253
8254            XmlSerializer out = new FastXmlSerializer();
8255            out.setOutput(fos, StandardCharsets.UTF_8.name());
8256            out.startDocument(null, true);
8257            out.startTag(null, TAG_URI_GRANTS);
8258            for (UriPermission.Snapshot perm : persist) {
8259                out.startTag(null, TAG_URI_GRANT);
8260                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8261                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8262                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8263                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8264                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8265                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8266                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8267                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8268                out.endTag(null, TAG_URI_GRANT);
8269            }
8270            out.endTag(null, TAG_URI_GRANTS);
8271            out.endDocument();
8272
8273            mGrantFile.finishWrite(fos);
8274        } catch (IOException e) {
8275            if (fos != null) {
8276                mGrantFile.failWrite(fos);
8277            }
8278        }
8279    }
8280
8281    private void readGrantedUriPermissionsLocked() {
8282        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8283
8284        final long now = System.currentTimeMillis();
8285
8286        FileInputStream fis = null;
8287        try {
8288            fis = mGrantFile.openRead();
8289            final XmlPullParser in = Xml.newPullParser();
8290            in.setInput(fis, StandardCharsets.UTF_8.name());
8291
8292            int type;
8293            while ((type = in.next()) != END_DOCUMENT) {
8294                final String tag = in.getName();
8295                if (type == START_TAG) {
8296                    if (TAG_URI_GRANT.equals(tag)) {
8297                        final int sourceUserId;
8298                        final int targetUserId;
8299                        final int userHandle = readIntAttribute(in,
8300                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8301                        if (userHandle != UserHandle.USER_NULL) {
8302                            // For backwards compatibility.
8303                            sourceUserId = userHandle;
8304                            targetUserId = userHandle;
8305                        } else {
8306                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8307                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8308                        }
8309                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8310                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8311                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8312                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8313                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8314                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8315
8316                        // Sanity check that provider still belongs to source package
8317                        final ProviderInfo pi = getProviderInfoLocked(
8318                                uri.getAuthority(), sourceUserId);
8319                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8320                            int targetUid = -1;
8321                            try {
8322                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8323                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8324                            } catch (RemoteException e) {
8325                            }
8326                            if (targetUid != -1) {
8327                                final UriPermission perm = findOrCreateUriPermissionLocked(
8328                                        sourcePkg, targetPkg, targetUid,
8329                                        new GrantUri(sourceUserId, uri, prefix));
8330                                perm.initPersistedModes(modeFlags, createdTime);
8331                            }
8332                        } else {
8333                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8334                                    + " but instead found " + pi);
8335                        }
8336                    }
8337                }
8338            }
8339        } catch (FileNotFoundException e) {
8340            // Missing grants is okay
8341        } catch (IOException e) {
8342            Slog.wtf(TAG, "Failed reading Uri grants", e);
8343        } catch (XmlPullParserException e) {
8344            Slog.wtf(TAG, "Failed reading Uri grants", e);
8345        } finally {
8346            IoUtils.closeQuietly(fis);
8347        }
8348    }
8349
8350    /**
8351     * @param uri This uri must NOT contain an embedded userId.
8352     * @param userId The userId in which the uri is to be resolved.
8353     */
8354    @Override
8355    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8356        enforceNotIsolatedCaller("takePersistableUriPermission");
8357
8358        Preconditions.checkFlagsArgument(modeFlags,
8359                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8360
8361        synchronized (this) {
8362            final int callingUid = Binder.getCallingUid();
8363            boolean persistChanged = false;
8364            GrantUri grantUri = new GrantUri(userId, uri, false);
8365
8366            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8367                    new GrantUri(userId, uri, false));
8368            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8369                    new GrantUri(userId, uri, true));
8370
8371            final boolean exactValid = (exactPerm != null)
8372                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8373            final boolean prefixValid = (prefixPerm != null)
8374                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8375
8376            if (!(exactValid || prefixValid)) {
8377                throw new SecurityException("No persistable permission grants found for UID "
8378                        + callingUid + " and Uri " + grantUri.toSafeString());
8379            }
8380
8381            if (exactValid) {
8382                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8383            }
8384            if (prefixValid) {
8385                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8386            }
8387
8388            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8389
8390            if (persistChanged) {
8391                schedulePersistUriGrants();
8392            }
8393        }
8394    }
8395
8396    /**
8397     * @param uri This uri must NOT contain an embedded userId.
8398     * @param userId The userId in which the uri is to be resolved.
8399     */
8400    @Override
8401    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8402        enforceNotIsolatedCaller("releasePersistableUriPermission");
8403
8404        Preconditions.checkFlagsArgument(modeFlags,
8405                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8406
8407        synchronized (this) {
8408            final int callingUid = Binder.getCallingUid();
8409            boolean persistChanged = false;
8410
8411            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8412                    new GrantUri(userId, uri, false));
8413            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8414                    new GrantUri(userId, uri, true));
8415            if (exactPerm == null && prefixPerm == null) {
8416                throw new SecurityException("No permission grants found for UID " + callingUid
8417                        + " and Uri " + uri.toSafeString());
8418            }
8419
8420            if (exactPerm != null) {
8421                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8422                removeUriPermissionIfNeededLocked(exactPerm);
8423            }
8424            if (prefixPerm != null) {
8425                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8426                removeUriPermissionIfNeededLocked(prefixPerm);
8427            }
8428
8429            if (persistChanged) {
8430                schedulePersistUriGrants();
8431            }
8432        }
8433    }
8434
8435    /**
8436     * Prune any older {@link UriPermission} for the given UID until outstanding
8437     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8438     *
8439     * @return if any mutations occured that require persisting.
8440     */
8441    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8442        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8443        if (perms == null) return false;
8444        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8445
8446        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8447        for (UriPermission perm : perms.values()) {
8448            if (perm.persistedModeFlags != 0) {
8449                persisted.add(perm);
8450            }
8451        }
8452
8453        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8454        if (trimCount <= 0) return false;
8455
8456        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8457        for (int i = 0; i < trimCount; i++) {
8458            final UriPermission perm = persisted.get(i);
8459
8460            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8461                    "Trimming grant created at " + perm.persistedCreateTime);
8462
8463            perm.releasePersistableModes(~0);
8464            removeUriPermissionIfNeededLocked(perm);
8465        }
8466
8467        return true;
8468    }
8469
8470    @Override
8471    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8472            String packageName, boolean incoming) {
8473        enforceNotIsolatedCaller("getPersistedUriPermissions");
8474        Preconditions.checkNotNull(packageName, "packageName");
8475
8476        final int callingUid = Binder.getCallingUid();
8477        final IPackageManager pm = AppGlobals.getPackageManager();
8478        try {
8479            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8480                    UserHandle.getUserId(callingUid));
8481            if (packageUid != callingUid) {
8482                throw new SecurityException(
8483                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8484            }
8485        } catch (RemoteException e) {
8486            throw new SecurityException("Failed to verify package name ownership");
8487        }
8488
8489        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8490        synchronized (this) {
8491            if (incoming) {
8492                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8493                        callingUid);
8494                if (perms == null) {
8495                    Slog.w(TAG, "No permission grants found for " + packageName);
8496                } else {
8497                    for (UriPermission perm : perms.values()) {
8498                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8499                            result.add(perm.buildPersistedPublicApiObject());
8500                        }
8501                    }
8502                }
8503            } else {
8504                final int size = mGrantedUriPermissions.size();
8505                for (int i = 0; i < size; i++) {
8506                    final ArrayMap<GrantUri, UriPermission> perms =
8507                            mGrantedUriPermissions.valueAt(i);
8508                    for (UriPermission perm : perms.values()) {
8509                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8510                            result.add(perm.buildPersistedPublicApiObject());
8511                        }
8512                    }
8513                }
8514            }
8515        }
8516        return new ParceledListSlice<android.content.UriPermission>(result);
8517    }
8518
8519    @Override
8520    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8521            String packageName, int userId) {
8522        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8523                "getGrantedUriPermissions");
8524
8525        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8526        synchronized (this) {
8527            final int size = mGrantedUriPermissions.size();
8528            for (int i = 0; i < size; i++) {
8529                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8530                for (UriPermission perm : perms.values()) {
8531                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8532                            && perm.persistedModeFlags != 0) {
8533                        result.add(perm.buildPersistedPublicApiObject());
8534                    }
8535                }
8536            }
8537        }
8538        return new ParceledListSlice<android.content.UriPermission>(result);
8539    }
8540
8541    @Override
8542    public void clearGrantedUriPermissions(String packageName, int userId) {
8543        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8544                "clearGrantedUriPermissions");
8545        removeUriPermissionsForPackageLocked(packageName, userId, true);
8546    }
8547
8548    @Override
8549    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8550        synchronized (this) {
8551            ProcessRecord app =
8552                who != null ? getRecordForAppLocked(who) : null;
8553            if (app == null) return;
8554
8555            Message msg = Message.obtain();
8556            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8557            msg.obj = app;
8558            msg.arg1 = waiting ? 1 : 0;
8559            mUiHandler.sendMessage(msg);
8560        }
8561    }
8562
8563    @Override
8564    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8565        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8566        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8567        outInfo.availMem = Process.getFreeMemory();
8568        outInfo.totalMem = Process.getTotalMemory();
8569        outInfo.threshold = homeAppMem;
8570        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8571        outInfo.hiddenAppThreshold = cachedAppMem;
8572        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8573                ProcessList.SERVICE_ADJ);
8574        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8575                ProcessList.VISIBLE_APP_ADJ);
8576        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8577                ProcessList.FOREGROUND_APP_ADJ);
8578    }
8579
8580    // =========================================================
8581    // TASK MANAGEMENT
8582    // =========================================================
8583
8584    @Override
8585    public List<IAppTask> getAppTasks(String callingPackage) {
8586        int callingUid = Binder.getCallingUid();
8587        long ident = Binder.clearCallingIdentity();
8588
8589        synchronized(this) {
8590            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8591            try {
8592                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8593
8594                final int N = mRecentTasks.size();
8595                for (int i = 0; i < N; i++) {
8596                    TaskRecord tr = mRecentTasks.get(i);
8597                    // Skip tasks that do not match the caller.  We don't need to verify
8598                    // callingPackage, because we are also limiting to callingUid and know
8599                    // that will limit to the correct security sandbox.
8600                    if (tr.effectiveUid != callingUid) {
8601                        continue;
8602                    }
8603                    Intent intent = tr.getBaseIntent();
8604                    if (intent == null ||
8605                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8606                        continue;
8607                    }
8608                    ActivityManager.RecentTaskInfo taskInfo =
8609                            createRecentTaskInfoFromTaskRecord(tr);
8610                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8611                    list.add(taskImpl);
8612                }
8613            } finally {
8614                Binder.restoreCallingIdentity(ident);
8615            }
8616            return list;
8617        }
8618    }
8619
8620    @Override
8621    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8622        final int callingUid = Binder.getCallingUid();
8623        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8624
8625        synchronized(this) {
8626            if (DEBUG_ALL) Slog.v(
8627                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8628
8629            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8630                    callingUid);
8631
8632            // TODO: Improve with MRU list from all ActivityStacks.
8633            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8634        }
8635
8636        return list;
8637    }
8638
8639    /**
8640     * Creates a new RecentTaskInfo from a TaskRecord.
8641     */
8642    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8643        // Update the task description to reflect any changes in the task stack
8644        tr.updateTaskDescription();
8645
8646        // Compose the recent task info
8647        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8648        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8649        rti.persistentId = tr.taskId;
8650        rti.baseIntent = new Intent(tr.getBaseIntent());
8651        rti.origActivity = tr.origActivity;
8652        rti.realActivity = tr.realActivity;
8653        rti.description = tr.lastDescription;
8654        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8655        rti.userId = tr.userId;
8656        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8657        rti.firstActiveTime = tr.firstActiveTime;
8658        rti.lastActiveTime = tr.lastActiveTime;
8659        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8660        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8661        rti.numActivities = 0;
8662        if (tr.mBounds != null) {
8663            rti.bounds = new Rect(tr.mBounds);
8664        }
8665        rti.isDockable = tr.canGoInDockedStack();
8666
8667        ActivityRecord base = null;
8668        ActivityRecord top = null;
8669        ActivityRecord tmp;
8670
8671        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8672            tmp = tr.mActivities.get(i);
8673            if (tmp.finishing) {
8674                continue;
8675            }
8676            base = tmp;
8677            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8678                top = base;
8679            }
8680            rti.numActivities++;
8681        }
8682
8683        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8684        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8685
8686        return rti;
8687    }
8688
8689    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8690        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8691                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8692        if (!allowed) {
8693            if (checkPermission(android.Manifest.permission.GET_TASKS,
8694                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8695                // Temporary compatibility: some existing apps on the system image may
8696                // still be requesting the old permission and not switched to the new
8697                // one; if so, we'll still allow them full access.  This means we need
8698                // to see if they are holding the old permission and are a system app.
8699                try {
8700                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8701                        allowed = true;
8702                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8703                                + " is using old GET_TASKS but privileged; allowing");
8704                    }
8705                } catch (RemoteException e) {
8706                }
8707            }
8708        }
8709        if (!allowed) {
8710            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8711                    + " does not hold REAL_GET_TASKS; limiting output");
8712        }
8713        return allowed;
8714    }
8715
8716    @Override
8717    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8718        final int callingUid = Binder.getCallingUid();
8719        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8720                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8721
8722        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8723        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8724        synchronized (this) {
8725            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8726                    callingUid);
8727            final boolean detailed = checkCallingPermission(
8728                    android.Manifest.permission.GET_DETAILED_TASKS)
8729                    == PackageManager.PERMISSION_GRANTED;
8730
8731            mRecentTasks.loadUserRecentsLocked(userId);
8732
8733            final int recentsCount = mRecentTasks.size();
8734            ArrayList<ActivityManager.RecentTaskInfo> res =
8735                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8736
8737            final Set<Integer> includedUsers;
8738            if (includeProfiles) {
8739                includedUsers = mUserController.getProfileIds(userId);
8740            } else {
8741                includedUsers = new HashSet<>();
8742            }
8743            includedUsers.add(Integer.valueOf(userId));
8744
8745            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8746                TaskRecord tr = mRecentTasks.get(i);
8747                // Only add calling user or related users recent tasks
8748                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8749                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8750                    continue;
8751                }
8752
8753                if (tr.realActivitySuspended) {
8754                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8755                    continue;
8756                }
8757
8758                // Return the entry if desired by the caller.  We always return
8759                // the first entry, because callers always expect this to be the
8760                // foreground app.  We may filter others if the caller has
8761                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8762                // we should exclude the entry.
8763
8764                if (i == 0
8765                        || withExcluded
8766                        || (tr.intent == null)
8767                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8768                                == 0)) {
8769                    if (!allowed) {
8770                        // If the caller doesn't have the GET_TASKS permission, then only
8771                        // allow them to see a small subset of tasks -- their own and home.
8772                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8773                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8774                            continue;
8775                        }
8776                    }
8777                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8778                        if (tr.stack != null && tr.stack.isHomeStack()) {
8779                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8780                                    "Skipping, home stack task: " + tr);
8781                            continue;
8782                        }
8783                    }
8784                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8785                        if (tr.stack != null && tr.stack.isDockedStack()) {
8786                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8787                                    "Skipping, docked stack task: " + tr);
8788                            continue;
8789                        }
8790                    }
8791                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8792                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8793                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8794                                    "Skipping, pinned stack task: " + tr);
8795                            continue;
8796                        }
8797                    }
8798                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8799                        // Don't include auto remove tasks that are finished or finishing.
8800                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8801                                "Skipping, auto-remove without activity: " + tr);
8802                        continue;
8803                    }
8804                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8805                            && !tr.isAvailable) {
8806                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8807                                "Skipping, unavail real act: " + tr);
8808                        continue;
8809                    }
8810
8811                    if (!tr.mUserSetupComplete) {
8812                        // Don't include task launched while user is not done setting-up.
8813                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8814                                "Skipping, user setup not complete: " + tr);
8815                        continue;
8816                    }
8817
8818                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8819                    if (!detailed) {
8820                        rti.baseIntent.replaceExtras((Bundle)null);
8821                    }
8822
8823                    res.add(rti);
8824                    maxNum--;
8825                }
8826            }
8827            return res;
8828        }
8829    }
8830
8831    @Override
8832    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8833        synchronized (this) {
8834            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8835                    "getTaskThumbnail()");
8836            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8837                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8838            if (tr != null) {
8839                return tr.getTaskThumbnailLocked();
8840            }
8841        }
8842        return null;
8843    }
8844
8845    @Override
8846    public int addAppTask(IBinder activityToken, Intent intent,
8847            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8848        final int callingUid = Binder.getCallingUid();
8849        final long callingIdent = Binder.clearCallingIdentity();
8850
8851        try {
8852            synchronized (this) {
8853                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8854                if (r == null) {
8855                    throw new IllegalArgumentException("Activity does not exist; token="
8856                            + activityToken);
8857                }
8858                ComponentName comp = intent.getComponent();
8859                if (comp == null) {
8860                    throw new IllegalArgumentException("Intent " + intent
8861                            + " must specify explicit component");
8862                }
8863                if (thumbnail.getWidth() != mThumbnailWidth
8864                        || thumbnail.getHeight() != mThumbnailHeight) {
8865                    throw new IllegalArgumentException("Bad thumbnail size: got "
8866                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8867                            + mThumbnailWidth + "x" + mThumbnailHeight);
8868                }
8869                if (intent.getSelector() != null) {
8870                    intent.setSelector(null);
8871                }
8872                if (intent.getSourceBounds() != null) {
8873                    intent.setSourceBounds(null);
8874                }
8875                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8876                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8877                        // The caller has added this as an auto-remove task...  that makes no
8878                        // sense, so turn off auto-remove.
8879                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8880                    }
8881                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8882                    // Must be a new task.
8883                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8884                }
8885                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8886                    mLastAddedTaskActivity = null;
8887                }
8888                ActivityInfo ainfo = mLastAddedTaskActivity;
8889                if (ainfo == null) {
8890                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8891                            comp, 0, UserHandle.getUserId(callingUid));
8892                    if (ainfo.applicationInfo.uid != callingUid) {
8893                        throw new SecurityException(
8894                                "Can't add task for another application: target uid="
8895                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8896                    }
8897                }
8898
8899                // Use the full screen as the context for the task thumbnail
8900                final Point displaySize = new Point();
8901                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8902                r.task.stack.getDisplaySize(displaySize);
8903                thumbnailInfo.taskWidth = displaySize.x;
8904                thumbnailInfo.taskHeight = displaySize.y;
8905                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8906
8907                TaskRecord task = new TaskRecord(this,
8908                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
8909                        ainfo, intent, description, thumbnailInfo);
8910
8911                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8912                if (trimIdx >= 0) {
8913                    // If this would have caused a trim, then we'll abort because that
8914                    // means it would be added at the end of the list but then just removed.
8915                    return INVALID_TASK_ID;
8916                }
8917
8918                final int N = mRecentTasks.size();
8919                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8920                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8921                    tr.removedFromRecents();
8922                }
8923
8924                task.inRecents = true;
8925                mRecentTasks.add(task);
8926                r.task.stack.addTask(task, false, "addAppTask");
8927
8928                task.setLastThumbnailLocked(thumbnail);
8929                task.freeLastThumbnail();
8930
8931                return task.taskId;
8932            }
8933        } finally {
8934            Binder.restoreCallingIdentity(callingIdent);
8935        }
8936    }
8937
8938    @Override
8939    public Point getAppTaskThumbnailSize() {
8940        synchronized (this) {
8941            return new Point(mThumbnailWidth,  mThumbnailHeight);
8942        }
8943    }
8944
8945    @Override
8946    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8947        synchronized (this) {
8948            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8949            if (r != null) {
8950                r.setTaskDescription(td);
8951                r.task.updateTaskDescription();
8952            }
8953        }
8954    }
8955
8956    @Override
8957    public void setTaskResizeable(int taskId, int resizeableMode) {
8958        synchronized (this) {
8959            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8960                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8961            if (task == null) {
8962                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8963                return;
8964            }
8965            if (task.mResizeMode != resizeableMode) {
8966                task.mResizeMode = resizeableMode;
8967                mWindowManager.setTaskResizeable(taskId, resizeableMode);
8968                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8969                mStackSupervisor.resumeFocusedStackTopActivityLocked();
8970            }
8971        }
8972    }
8973
8974    @Override
8975    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8976        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
8977        long ident = Binder.clearCallingIdentity();
8978        try {
8979            synchronized (this) {
8980                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8981                if (task == null) {
8982                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8983                    return;
8984                }
8985                int stackId = task.stack.mStackId;
8986                // We allow the task to scroll instead of resizing if this is a non-resizeable task
8987                // in crop windows resize mode or if the task size is affected by the docked stack
8988                // changing size. No need to update configuration.
8989                if (bounds != null && task.inCropWindowsResizeMode()
8990                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
8991                    mWindowManager.scrollTask(task.taskId, bounds);
8992                    return;
8993                }
8994
8995                // Place the task in the right stack if it isn't there already based on
8996                // the requested bounds.
8997                // The stack transition logic is:
8998                // - a null bounds on a freeform task moves that task to fullscreen
8999                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9000                //   that task to freeform
9001                // - otherwise the task is not moved
9002                if (!StackId.isTaskResizeAllowed(stackId)) {
9003                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9004                }
9005                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9006                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9007                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9008                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9009                }
9010                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9011                if (stackId != task.stack.mStackId) {
9012                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9013                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9014                    preserveWindow = false;
9015                }
9016
9017                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9018            }
9019        } finally {
9020            Binder.restoreCallingIdentity(ident);
9021        }
9022    }
9023
9024    @Override
9025    public Rect getTaskBounds(int taskId) {
9026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9027        long ident = Binder.clearCallingIdentity();
9028        Rect rect = new Rect();
9029        try {
9030            synchronized (this) {
9031                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9032                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9033                if (task == null) {
9034                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9035                    return rect;
9036                }
9037                if (task.stack != null) {
9038                    // Return the bounds from window manager since it will be adjusted for various
9039                    // things like the presense of a docked stack for tasks that aren't resizeable.
9040                    mWindowManager.getTaskBounds(task.taskId, rect);
9041                } else {
9042                    // Task isn't in window manager yet since it isn't associated with a stack.
9043                    // Return the persist value from activity manager
9044                    if (task.mBounds != null) {
9045                        rect.set(task.mBounds);
9046                    } else if (task.mLastNonFullscreenBounds != null) {
9047                        rect.set(task.mLastNonFullscreenBounds);
9048                    }
9049                }
9050            }
9051        } finally {
9052            Binder.restoreCallingIdentity(ident);
9053        }
9054        return rect;
9055    }
9056
9057    @Override
9058    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9059        if (userId != UserHandle.getCallingUserId()) {
9060            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9061                    "getTaskDescriptionIcon");
9062        }
9063        final File passedIconFile = new File(filePath);
9064        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9065                passedIconFile.getName());
9066        if (!legitIconFile.getPath().equals(filePath)
9067                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9068            throw new IllegalArgumentException("Bad file path: " + filePath
9069                    + " passed for userId " + userId);
9070        }
9071        return mRecentTasks.getTaskDescriptionIcon(filePath);
9072    }
9073
9074    @Override
9075    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9076            throws RemoteException {
9077        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9078                opts.getCustomInPlaceResId() == 0) {
9079            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9080                    "with valid animation");
9081        }
9082        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9083        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9084                opts.getCustomInPlaceResId());
9085        mWindowManager.executeAppTransition();
9086    }
9087
9088    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9089            boolean removeFromRecents) {
9090        if (removeFromRecents) {
9091            mRecentTasks.remove(tr);
9092            tr.removedFromRecents();
9093        }
9094        ComponentName component = tr.getBaseIntent().getComponent();
9095        if (component == null) {
9096            Slog.w(TAG, "No component for base intent of task: " + tr);
9097            return;
9098        }
9099
9100        // Find any running services associated with this app and stop if needed.
9101        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9102
9103        if (!killProcess) {
9104            return;
9105        }
9106
9107        // Determine if the process(es) for this task should be killed.
9108        final String pkg = component.getPackageName();
9109        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9110        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9111        for (int i = 0; i < pmap.size(); i++) {
9112
9113            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9114            for (int j = 0; j < uids.size(); j++) {
9115                ProcessRecord proc = uids.valueAt(j);
9116                if (proc.userId != tr.userId) {
9117                    // Don't kill process for a different user.
9118                    continue;
9119                }
9120                if (proc == mHomeProcess) {
9121                    // Don't kill the home process along with tasks from the same package.
9122                    continue;
9123                }
9124                if (!proc.pkgList.containsKey(pkg)) {
9125                    // Don't kill process that is not associated with this task.
9126                    continue;
9127                }
9128
9129                for (int k = 0; k < proc.activities.size(); k++) {
9130                    TaskRecord otherTask = proc.activities.get(k).task;
9131                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9132                        // Don't kill process(es) that has an activity in a different task that is
9133                        // also in recents.
9134                        return;
9135                    }
9136                }
9137
9138                if (proc.foregroundServices) {
9139                    // Don't kill process(es) with foreground service.
9140                    return;
9141                }
9142
9143                // Add process to kill list.
9144                procsToKill.add(proc);
9145            }
9146        }
9147
9148        // Kill the running processes.
9149        for (int i = 0; i < procsToKill.size(); i++) {
9150            ProcessRecord pr = procsToKill.get(i);
9151            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9152                    && pr.curReceiver == null) {
9153                pr.kill("remove task", true);
9154            } else {
9155                // We delay killing processes that are not in the background or running a receiver.
9156                pr.waitingToKill = "remove task";
9157            }
9158        }
9159    }
9160
9161    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9162        // Remove all tasks with activities in the specified package from the list of recent tasks
9163        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9164            TaskRecord tr = mRecentTasks.get(i);
9165            if (tr.userId != userId) continue;
9166
9167            ComponentName cn = tr.intent.getComponent();
9168            if (cn != null && cn.getPackageName().equals(packageName)) {
9169                // If the package name matches, remove the task.
9170                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9171            }
9172        }
9173    }
9174
9175    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9176            int userId) {
9177
9178        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9179            TaskRecord tr = mRecentTasks.get(i);
9180            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9181                continue;
9182            }
9183
9184            ComponentName cn = tr.intent.getComponent();
9185            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9186                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9187            if (sameComponent) {
9188                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9189            }
9190        }
9191    }
9192
9193    /**
9194     * Removes the task with the specified task id.
9195     *
9196     * @param taskId Identifier of the task to be removed.
9197     * @param killProcess Kill any process associated with the task if possible.
9198     * @param removeFromRecents Whether to also remove the task from recents.
9199     * @return Returns true if the given task was found and removed.
9200     */
9201    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9202            boolean removeFromRecents) {
9203        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9204                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9205        if (tr != null) {
9206            tr.removeTaskActivitiesLocked();
9207            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9208            if (tr.isPersistable) {
9209                notifyTaskPersisterLocked(null, true);
9210            }
9211            return true;
9212        }
9213        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9214        return false;
9215    }
9216
9217    @Override
9218    public void removeStack(int stackId) {
9219        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9220        if (stackId == HOME_STACK_ID) {
9221            throw new IllegalArgumentException("Removing home stack is not allowed.");
9222        }
9223
9224        synchronized (this) {
9225            final long ident = Binder.clearCallingIdentity();
9226            try {
9227                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9228                if (stack == null) {
9229                    return;
9230                }
9231                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9232                for (int i = tasks.size() - 1; i >= 0; i--) {
9233                    removeTaskByIdLocked(
9234                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9235                }
9236            } finally {
9237                Binder.restoreCallingIdentity(ident);
9238            }
9239        }
9240    }
9241
9242    @Override
9243    public boolean removeTask(int taskId) {
9244        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9245        synchronized (this) {
9246            final long ident = Binder.clearCallingIdentity();
9247            try {
9248                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9249            } finally {
9250                Binder.restoreCallingIdentity(ident);
9251            }
9252        }
9253    }
9254
9255    /**
9256     * TODO: Add mController hook
9257     */
9258    @Override
9259    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9260        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9261
9262        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9263        synchronized(this) {
9264            moveTaskToFrontLocked(taskId, flags, bOptions);
9265        }
9266    }
9267
9268    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9269        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9270
9271        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9272                Binder.getCallingUid(), -1, -1, "Task to front")) {
9273            ActivityOptions.abort(options);
9274            return;
9275        }
9276        final long origId = Binder.clearCallingIdentity();
9277        try {
9278            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9279            if (task == null) {
9280                Slog.d(TAG, "Could not find task for id: "+ taskId);
9281                return;
9282            }
9283            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9284                mStackSupervisor.showLockTaskToast();
9285                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9286                return;
9287            }
9288            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9289            if (prev != null && prev.isRecentsActivity()) {
9290                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9291            }
9292            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9293        } finally {
9294            Binder.restoreCallingIdentity(origId);
9295        }
9296        ActivityOptions.abort(options);
9297    }
9298
9299    /**
9300     * Moves an activity, and all of the other activities within the same task, to the bottom
9301     * of the history stack.  The activity's order within the task is unchanged.
9302     *
9303     * @param token A reference to the activity we wish to move
9304     * @param nonRoot If false then this only works if the activity is the root
9305     *                of a task; if true it will work for any activity in a task.
9306     * @return Returns true if the move completed, false if not.
9307     */
9308    @Override
9309    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9310        enforceNotIsolatedCaller("moveActivityTaskToBack");
9311        synchronized(this) {
9312            final long origId = Binder.clearCallingIdentity();
9313            try {
9314                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9315                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9316                if (task != null) {
9317                    if (mStackSupervisor.isLockedTask(task)) {
9318                        mStackSupervisor.showLockTaskToast();
9319                        return false;
9320                    }
9321                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9322                }
9323            } finally {
9324                Binder.restoreCallingIdentity(origId);
9325            }
9326        }
9327        return false;
9328    }
9329
9330    @Override
9331    public void moveTaskBackwards(int task) {
9332        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9333                "moveTaskBackwards()");
9334
9335        synchronized(this) {
9336            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9337                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9338                return;
9339            }
9340            final long origId = Binder.clearCallingIdentity();
9341            moveTaskBackwardsLocked(task);
9342            Binder.restoreCallingIdentity(origId);
9343        }
9344    }
9345
9346    private final void moveTaskBackwardsLocked(int task) {
9347        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9348    }
9349
9350    @Override
9351    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9352            IActivityContainerCallback callback) throws RemoteException {
9353        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9354        synchronized (this) {
9355            if (parentActivityToken == null) {
9356                throw new IllegalArgumentException("parent token must not be null");
9357            }
9358            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9359            if (r == null) {
9360                return null;
9361            }
9362            if (callback == null) {
9363                throw new IllegalArgumentException("callback must not be null");
9364            }
9365            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9366        }
9367    }
9368
9369    @Override
9370    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9371        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9372        synchronized (this) {
9373            mStackSupervisor.deleteActivityContainer(container);
9374        }
9375    }
9376
9377    @Override
9378    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9379        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9380        synchronized (this) {
9381            final int stackId = mStackSupervisor.getNextStackId();
9382            final ActivityStack stack =
9383                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9384            if (stack == null) {
9385                return null;
9386            }
9387            return stack.mActivityContainer;
9388        }
9389    }
9390
9391    @Override
9392    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9393        synchronized (this) {
9394            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9395            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9396                return stack.mActivityContainer.getDisplayId();
9397            }
9398            return Display.DEFAULT_DISPLAY;
9399        }
9400    }
9401
9402    @Override
9403    public int getActivityStackId(IBinder token) throws RemoteException {
9404        synchronized (this) {
9405            ActivityStack stack = ActivityRecord.getStackLocked(token);
9406            if (stack == null) {
9407                return INVALID_STACK_ID;
9408            }
9409            return stack.mStackId;
9410        }
9411    }
9412
9413    @Override
9414    public void exitFreeformMode(IBinder token) throws RemoteException {
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                            "exitFreeformMode: No activity record matching token=" + token);
9422                }
9423                final ActivityStack stack = r.getStackLocked(token);
9424                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9425                    throw new IllegalStateException(
9426                            "exitFreeformMode: You can only go fullscreen from freeform.");
9427                }
9428                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9429                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9430                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9431            } finally {
9432                Binder.restoreCallingIdentity(ident);
9433            }
9434        }
9435    }
9436
9437    @Override
9438    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9439        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9440        if (stackId == HOME_STACK_ID) {
9441            throw new IllegalArgumentException(
9442                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9443        }
9444        synchronized (this) {
9445            long ident = Binder.clearCallingIdentity();
9446            try {
9447                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9448                        + " to stackId=" + stackId + " toTop=" + toTop);
9449                if (stackId == DOCKED_STACK_ID) {
9450                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9451                            null /* initialBounds */);
9452                }
9453                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9454                        "moveTaskToStack", ANIMATE);
9455            } finally {
9456                Binder.restoreCallingIdentity(ident);
9457            }
9458        }
9459    }
9460
9461    /**
9462     * Moves the input task to the docked stack.
9463     *
9464     * @param taskId Id of task to move.
9465     * @param createMode The mode the docked stack should be created in if it doesn't exist
9466     *                   already. See
9467     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9468     *                   and
9469     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9470     * @param toTop If the task and stack should be moved to the top.
9471     * @param animate Whether we should play an animation for the moving the task
9472     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9473     *                      docked stack. Pass {@code null} to use default bounds.
9474     */
9475    @Override
9476    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9477            Rect initialBounds) {
9478        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9479        synchronized (this) {
9480            long ident = Binder.clearCallingIdentity();
9481            try {
9482                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9483                        + " to createMode=" + createMode + " toTop=" + toTop);
9484                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9485                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9486                        "moveTaskToDockedStack", animate);
9487            } finally {
9488                Binder.restoreCallingIdentity(ident);
9489            }
9490        }
9491    }
9492
9493    /**
9494     * Moves the top activity in the input stackId to the pinned stack.
9495     *
9496     * @param stackId Id of stack to move the top activity to pinned stack.
9497     * @param bounds Bounds to use for pinned stack.
9498     *
9499     * @return True if the top activity of the input stack was successfully moved to the pinned
9500     *          stack.
9501     */
9502    @Override
9503    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9504        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9505        synchronized (this) {
9506            if (!mSupportsPictureInPicture) {
9507                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9508                        + "Device doesn't support picture-in-pciture mode");
9509            }
9510
9511            long ident = Binder.clearCallingIdentity();
9512            try {
9513                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9514            } finally {
9515                Binder.restoreCallingIdentity(ident);
9516            }
9517        }
9518    }
9519
9520    @Override
9521    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9522            boolean preserveWindows, boolean animate) {
9523        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9524        long ident = Binder.clearCallingIdentity();
9525        try {
9526            synchronized (this) {
9527                if (animate) {
9528                    if (stackId == PINNED_STACK_ID) {
9529                        mWindowManager.animateResizePinnedStack(bounds);
9530                    } else {
9531                        throw new IllegalArgumentException("Stack: " + stackId
9532                                + " doesn't support animated resize.");
9533                    }
9534                } else {
9535                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9536                            null /* tempTaskInsetBounds */, preserveWindows,
9537                            allowResizeInDockedMode);
9538                }
9539            }
9540        } finally {
9541            Binder.restoreCallingIdentity(ident);
9542        }
9543    }
9544
9545    @Override
9546    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9547            Rect tempDockedTaskInsetBounds,
9548            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9549        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9550                "resizeDockedStack()");
9551        long ident = Binder.clearCallingIdentity();
9552        try {
9553            synchronized (this) {
9554                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9555                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9556                        PRESERVE_WINDOWS);
9557            }
9558        } finally {
9559            Binder.restoreCallingIdentity(ident);
9560        }
9561    }
9562
9563    @Override
9564    public void positionTaskInStack(int taskId, int stackId, int position) {
9565        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9566        if (stackId == HOME_STACK_ID) {
9567            throw new IllegalArgumentException(
9568                    "positionTaskInStack: Attempt to change the position of task "
9569                    + taskId + " in/to home stack");
9570        }
9571        synchronized (this) {
9572            long ident = Binder.clearCallingIdentity();
9573            try {
9574                if (DEBUG_STACK) Slog.d(TAG_STACK,
9575                        "positionTaskInStack: positioning task=" + taskId
9576                        + " in stackId=" + stackId + " at position=" + position);
9577                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9578            } finally {
9579                Binder.restoreCallingIdentity(ident);
9580            }
9581        }
9582    }
9583
9584    @Override
9585    public List<StackInfo> getAllStackInfos() {
9586        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9587        long ident = Binder.clearCallingIdentity();
9588        try {
9589            synchronized (this) {
9590                return mStackSupervisor.getAllStackInfosLocked();
9591            }
9592        } finally {
9593            Binder.restoreCallingIdentity(ident);
9594        }
9595    }
9596
9597    @Override
9598    public StackInfo getStackInfo(int stackId) {
9599        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9600        long ident = Binder.clearCallingIdentity();
9601        try {
9602            synchronized (this) {
9603                return mStackSupervisor.getStackInfoLocked(stackId);
9604            }
9605        } finally {
9606            Binder.restoreCallingIdentity(ident);
9607        }
9608    }
9609
9610    @Override
9611    public boolean isInHomeStack(int taskId) {
9612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9613        long ident = Binder.clearCallingIdentity();
9614        try {
9615            synchronized (this) {
9616                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9617                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9618                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9619            }
9620        } finally {
9621            Binder.restoreCallingIdentity(ident);
9622        }
9623    }
9624
9625    @Override
9626    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9627        synchronized(this) {
9628            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9629        }
9630    }
9631
9632    @Override
9633    public void updateDeviceOwner(String packageName) {
9634        final int callingUid = Binder.getCallingUid();
9635        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9636            throw new SecurityException("updateDeviceOwner called from non-system process");
9637        }
9638        synchronized (this) {
9639            mDeviceOwnerName = packageName;
9640        }
9641    }
9642
9643    @Override
9644    public void updateLockTaskPackages(int userId, String[] packages) {
9645        final int callingUid = Binder.getCallingUid();
9646        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9647            throw new SecurityException("updateLockTaskPackage called from non-system process");
9648        }
9649        synchronized (this) {
9650            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9651                    Arrays.toString(packages));
9652            mLockTaskPackages.put(userId, packages);
9653            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9654        }
9655    }
9656
9657
9658    void startLockTaskModeLocked(TaskRecord task) {
9659        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9660        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9661            return;
9662        }
9663
9664        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9665        // is initiated by system after the pinning request was shown and locked mode is initiated
9666        // by an authorized app directly
9667        final int callingUid = Binder.getCallingUid();
9668        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9669        long ident = Binder.clearCallingIdentity();
9670        try {
9671            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9672            if (!isSystemInitiated) {
9673                task.mLockTaskUid = callingUid;
9674                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9675                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9676                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9677                    StatusBarManagerInternal statusBarManager =
9678                            LocalServices.getService(StatusBarManagerInternal.class);
9679                    if (statusBarManager != null) {
9680                        statusBarManager.showScreenPinningRequest();
9681                    }
9682                    return;
9683                }
9684
9685                if (stack == null || task != stack.topTask()) {
9686                    throw new IllegalArgumentException("Invalid task, not in foreground");
9687                }
9688            }
9689            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9690                    "Locking fully");
9691            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9692                    ActivityManager.LOCK_TASK_MODE_PINNED :
9693                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9694                    "startLockTask", true);
9695        } finally {
9696            Binder.restoreCallingIdentity(ident);
9697        }
9698    }
9699
9700    @Override
9701    public void startLockTaskMode(int taskId) {
9702        synchronized (this) {
9703            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9704            if (task != null) {
9705                startLockTaskModeLocked(task);
9706            }
9707        }
9708    }
9709
9710    @Override
9711    public void startLockTaskMode(IBinder token) {
9712        synchronized (this) {
9713            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9714            if (r == null) {
9715                return;
9716            }
9717            final TaskRecord task = r.task;
9718            if (task != null) {
9719                startLockTaskModeLocked(task);
9720            }
9721        }
9722    }
9723
9724    @Override
9725    public void startLockTaskModeOnCurrent() throws RemoteException {
9726        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9727        long ident = Binder.clearCallingIdentity();
9728        try {
9729            synchronized (this) {
9730                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9731                if (r != null) {
9732                    startLockTaskModeLocked(r.task);
9733                }
9734            }
9735        } finally {
9736            Binder.restoreCallingIdentity(ident);
9737        }
9738    }
9739
9740    @Override
9741    public void stopLockTaskMode() {
9742        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9743        if (lockTask == null) {
9744            // Our work here is done.
9745            return;
9746        }
9747
9748        final int callingUid = Binder.getCallingUid();
9749        final int lockTaskUid = lockTask.mLockTaskUid;
9750        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9751        // It is possible lockTaskMode was started by the system process because
9752        // android:lockTaskMode is set to a locking value in the application manifest instead of
9753        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9754        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9755        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9756                callingUid != lockTaskUid
9757                && (lockTaskUid != 0
9758                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9759            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9760                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9761        }
9762
9763        long ident = Binder.clearCallingIdentity();
9764        try {
9765            Log.d(TAG, "stopLockTaskMode");
9766            // Stop lock task
9767            synchronized (this) {
9768                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9769                        "stopLockTask", true);
9770            }
9771        } finally {
9772            Binder.restoreCallingIdentity(ident);
9773        }
9774    }
9775
9776    @Override
9777    public void stopLockTaskModeOnCurrent() throws RemoteException {
9778        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9779        long ident = Binder.clearCallingIdentity();
9780        try {
9781            stopLockTaskMode();
9782        } finally {
9783            Binder.restoreCallingIdentity(ident);
9784        }
9785    }
9786
9787    @Override
9788    public boolean isInLockTaskMode() {
9789        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9790    }
9791
9792    @Override
9793    public int getLockTaskModeState() {
9794        synchronized (this) {
9795            return mStackSupervisor.getLockTaskModeState();
9796        }
9797    }
9798
9799    @Override
9800    public void showLockTaskEscapeMessage(IBinder token) {
9801        synchronized (this) {
9802            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9803            if (r == null) {
9804                return;
9805            }
9806            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9807        }
9808    }
9809
9810    // =========================================================
9811    // CONTENT PROVIDERS
9812    // =========================================================
9813
9814    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9815        List<ProviderInfo> providers = null;
9816        try {
9817            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9818                    .queryContentProviders(app.processName, app.uid,
9819                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9820                                    | MATCH_DEBUG_TRIAGED_MISSING);
9821            providers = slice != null ? slice.getList() : null;
9822        } catch (RemoteException ex) {
9823        }
9824        if (DEBUG_MU) Slog.v(TAG_MU,
9825                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9826        int userId = app.userId;
9827        if (providers != null) {
9828            int N = providers.size();
9829            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9830            for (int i=0; i<N; i++) {
9831                ProviderInfo cpi =
9832                    (ProviderInfo)providers.get(i);
9833                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9834                        cpi.name, cpi.flags);
9835                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9836                    // This is a singleton provider, but a user besides the
9837                    // default user is asking to initialize a process it runs
9838                    // in...  well, no, it doesn't actually run in this process,
9839                    // it runs in the process of the default user.  Get rid of it.
9840                    providers.remove(i);
9841                    N--;
9842                    i--;
9843                    continue;
9844                }
9845
9846                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9847                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9848                if (cpr == null) {
9849                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9850                    mProviderMap.putProviderByClass(comp, cpr);
9851                }
9852                if (DEBUG_MU) Slog.v(TAG_MU,
9853                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9854                app.pubProviders.put(cpi.name, cpr);
9855                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9856                    // Don't add this if it is a platform component that is marked
9857                    // to run in multiple processes, because this is actually
9858                    // part of the framework so doesn't make sense to track as a
9859                    // separate apk in the process.
9860                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9861                            mProcessStats);
9862                }
9863                notifyPackageUse(cpi.applicationInfo.packageName);
9864            }
9865        }
9866        return providers;
9867    }
9868
9869    /**
9870     * Check if {@link ProcessRecord} has a possible chance at accessing the
9871     * given {@link ProviderInfo}. Final permission checking is always done
9872     * in {@link ContentProvider}.
9873     */
9874    private final String checkContentProviderPermissionLocked(
9875            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9876        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9877        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9878        boolean checkedGrants = false;
9879        if (checkUser) {
9880            // Looking for cross-user grants before enforcing the typical cross-users permissions
9881            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9882            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9883                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9884                    return null;
9885                }
9886                checkedGrants = true;
9887            }
9888            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9889                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9890            if (userId != tmpTargetUserId) {
9891                // When we actually went to determine the final targer user ID, this ended
9892                // up different than our initial check for the authority.  This is because
9893                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9894                // SELF.  So we need to re-check the grants again.
9895                checkedGrants = false;
9896            }
9897        }
9898        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9899                cpi.applicationInfo.uid, cpi.exported)
9900                == PackageManager.PERMISSION_GRANTED) {
9901            return null;
9902        }
9903        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9904                cpi.applicationInfo.uid, cpi.exported)
9905                == PackageManager.PERMISSION_GRANTED) {
9906            return null;
9907        }
9908
9909        PathPermission[] pps = cpi.pathPermissions;
9910        if (pps != null) {
9911            int i = pps.length;
9912            while (i > 0) {
9913                i--;
9914                PathPermission pp = pps[i];
9915                String pprperm = pp.getReadPermission();
9916                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9917                        cpi.applicationInfo.uid, cpi.exported)
9918                        == PackageManager.PERMISSION_GRANTED) {
9919                    return null;
9920                }
9921                String ppwperm = pp.getWritePermission();
9922                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9923                        cpi.applicationInfo.uid, cpi.exported)
9924                        == PackageManager.PERMISSION_GRANTED) {
9925                    return null;
9926                }
9927            }
9928        }
9929        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9930            return null;
9931        }
9932
9933        String msg;
9934        if (!cpi.exported) {
9935            msg = "Permission Denial: opening provider " + cpi.name
9936                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9937                    + ", uid=" + callingUid + ") that is not exported from uid "
9938                    + cpi.applicationInfo.uid;
9939        } else {
9940            msg = "Permission Denial: opening provider " + cpi.name
9941                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9942                    + ", uid=" + callingUid + ") requires "
9943                    + cpi.readPermission + " or " + cpi.writePermission;
9944        }
9945        Slog.w(TAG, msg);
9946        return msg;
9947    }
9948
9949    /**
9950     * Returns if the ContentProvider has granted a uri to callingUid
9951     */
9952    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9953        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9954        if (perms != null) {
9955            for (int i=perms.size()-1; i>=0; i--) {
9956                GrantUri grantUri = perms.keyAt(i);
9957                if (grantUri.sourceUserId == userId || !checkUser) {
9958                    if (matchesProvider(grantUri.uri, cpi)) {
9959                        return true;
9960                    }
9961                }
9962            }
9963        }
9964        return false;
9965    }
9966
9967    /**
9968     * Returns true if the uri authority is one of the authorities specified in the provider.
9969     */
9970    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9971        String uriAuth = uri.getAuthority();
9972        String cpiAuth = cpi.authority;
9973        if (cpiAuth.indexOf(';') == -1) {
9974            return cpiAuth.equals(uriAuth);
9975        }
9976        String[] cpiAuths = cpiAuth.split(";");
9977        int length = cpiAuths.length;
9978        for (int i = 0; i < length; i++) {
9979            if (cpiAuths[i].equals(uriAuth)) return true;
9980        }
9981        return false;
9982    }
9983
9984    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9985            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9986        if (r != null) {
9987            for (int i=0; i<r.conProviders.size(); i++) {
9988                ContentProviderConnection conn = r.conProviders.get(i);
9989                if (conn.provider == cpr) {
9990                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9991                            "Adding provider requested by "
9992                            + r.processName + " from process "
9993                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9994                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9995                    if (stable) {
9996                        conn.stableCount++;
9997                        conn.numStableIncs++;
9998                    } else {
9999                        conn.unstableCount++;
10000                        conn.numUnstableIncs++;
10001                    }
10002                    return conn;
10003                }
10004            }
10005            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10006            if (stable) {
10007                conn.stableCount = 1;
10008                conn.numStableIncs = 1;
10009            } else {
10010                conn.unstableCount = 1;
10011                conn.numUnstableIncs = 1;
10012            }
10013            cpr.connections.add(conn);
10014            r.conProviders.add(conn);
10015            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10016            return conn;
10017        }
10018        cpr.addExternalProcessHandleLocked(externalProcessToken);
10019        return null;
10020    }
10021
10022    boolean decProviderCountLocked(ContentProviderConnection conn,
10023            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10024        if (conn != null) {
10025            cpr = conn.provider;
10026            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10027                    "Removing provider requested by "
10028                    + conn.client.processName + " from process "
10029                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10030                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10031            if (stable) {
10032                conn.stableCount--;
10033            } else {
10034                conn.unstableCount--;
10035            }
10036            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10037                cpr.connections.remove(conn);
10038                conn.client.conProviders.remove(conn);
10039                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10040                    // The client is more important than last activity -- note the time this
10041                    // is happening, so we keep the old provider process around a bit as last
10042                    // activity to avoid thrashing it.
10043                    if (cpr.proc != null) {
10044                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10045                    }
10046                }
10047                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10048                return true;
10049            }
10050            return false;
10051        }
10052        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10053        return false;
10054    }
10055
10056    private void checkTime(long startTime, String where) {
10057        long now = SystemClock.elapsedRealtime();
10058        if ((now-startTime) > 1000) {
10059            // If we are taking more than a second, log about it.
10060            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10061        }
10062    }
10063
10064    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10065            String name, IBinder token, boolean stable, int userId) {
10066        ContentProviderRecord cpr;
10067        ContentProviderConnection conn = null;
10068        ProviderInfo cpi = null;
10069
10070        synchronized(this) {
10071            long startTime = SystemClock.elapsedRealtime();
10072
10073            ProcessRecord r = null;
10074            if (caller != null) {
10075                r = getRecordForAppLocked(caller);
10076                if (r == null) {
10077                    throw new SecurityException(
10078                            "Unable to find app for caller " + caller
10079                          + " (pid=" + Binder.getCallingPid()
10080                          + ") when getting content provider " + name);
10081                }
10082            }
10083
10084            boolean checkCrossUser = true;
10085
10086            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10087
10088            // First check if this content provider has been published...
10089            cpr = mProviderMap.getProviderByName(name, userId);
10090            // If that didn't work, check if it exists for user 0 and then
10091            // verify that it's a singleton provider before using it.
10092            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10093                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10094                if (cpr != null) {
10095                    cpi = cpr.info;
10096                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10097                            cpi.name, cpi.flags)
10098                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10099                        userId = UserHandle.USER_SYSTEM;
10100                        checkCrossUser = false;
10101                    } else {
10102                        cpr = null;
10103                        cpi = null;
10104                    }
10105                }
10106            }
10107
10108            boolean providerRunning = cpr != null;
10109            if (providerRunning) {
10110                cpi = cpr.info;
10111                String msg;
10112                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10113                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10114                        != null) {
10115                    throw new SecurityException(msg);
10116                }
10117                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10118
10119                if (r != null && cpr.canRunHere(r)) {
10120                    // This provider has been published or is in the process
10121                    // of being published...  but it is also allowed to run
10122                    // in the caller's process, so don't make a connection
10123                    // and just let the caller instantiate its own instance.
10124                    ContentProviderHolder holder = cpr.newHolder(null);
10125                    // don't give caller the provider object, it needs
10126                    // to make its own.
10127                    holder.provider = null;
10128                    return holder;
10129                }
10130
10131                final long origId = Binder.clearCallingIdentity();
10132
10133                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10134
10135                // In this case the provider instance already exists, so we can
10136                // return it right away.
10137                conn = incProviderCountLocked(r, cpr, token, stable);
10138                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10139                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10140                        // If this is a perceptible app accessing the provider,
10141                        // make sure to count it as being accessed and thus
10142                        // back up on the LRU list.  This is good because
10143                        // content providers are often expensive to start.
10144                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10145                        updateLruProcessLocked(cpr.proc, false, null);
10146                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10147                    }
10148                }
10149
10150                if (cpr.proc != null) {
10151                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10152                    boolean success = updateOomAdjLocked(cpr.proc);
10153                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10154                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10155                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10156                    // NOTE: there is still a race here where a signal could be
10157                    // pending on the process even though we managed to update its
10158                    // adj level.  Not sure what to do about this, but at least
10159                    // the race is now smaller.
10160                    if (!success) {
10161                        // Uh oh...  it looks like the provider's process
10162                        // has been killed on us.  We need to wait for a new
10163                        // process to be started, and make sure its death
10164                        // doesn't kill our process.
10165                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10166                                + " is crashing; detaching " + r);
10167                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10168                        checkTime(startTime, "getContentProviderImpl: before appDied");
10169                        appDiedLocked(cpr.proc);
10170                        checkTime(startTime, "getContentProviderImpl: after appDied");
10171                        if (!lastRef) {
10172                            // This wasn't the last ref our process had on
10173                            // the provider...  we have now been killed, bail.
10174                            return null;
10175                        }
10176                        providerRunning = false;
10177                        conn = null;
10178                    }
10179                }
10180
10181                Binder.restoreCallingIdentity(origId);
10182            }
10183
10184            if (!providerRunning) {
10185                try {
10186                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10187                    cpi = AppGlobals.getPackageManager().
10188                        resolveContentProvider(name,
10189                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10190                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10191                } catch (RemoteException ex) {
10192                }
10193                if (cpi == null) {
10194                    return null;
10195                }
10196                // If the provider is a singleton AND
10197                // (it's a call within the same user || the provider is a
10198                // privileged app)
10199                // Then allow connecting to the singleton provider
10200                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10201                        cpi.name, cpi.flags)
10202                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10203                if (singleton) {
10204                    userId = UserHandle.USER_SYSTEM;
10205                }
10206                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10207                checkTime(startTime, "getContentProviderImpl: got app info for user");
10208
10209                String msg;
10210                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10211                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10212                        != null) {
10213                    throw new SecurityException(msg);
10214                }
10215                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10216
10217                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10218                        && !cpi.processName.equals("system")) {
10219                    // If this content provider does not run in the system
10220                    // process, and the system is not yet ready to run other
10221                    // processes, then fail fast instead of hanging.
10222                    throw new IllegalArgumentException(
10223                            "Attempt to launch content provider before system ready");
10224                }
10225
10226                // Make sure that the user who owns this provider is running.  If not,
10227                // we don't want to allow it to run.
10228                if (!mUserController.isUserRunningLocked(userId, 0)) {
10229                    Slog.w(TAG, "Unable to launch app "
10230                            + cpi.applicationInfo.packageName + "/"
10231                            + cpi.applicationInfo.uid + " for provider "
10232                            + name + ": user " + userId + " is stopped");
10233                    return null;
10234                }
10235
10236                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10237                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10238                cpr = mProviderMap.getProviderByClass(comp, userId);
10239                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10240                final boolean firstClass = cpr == null;
10241                if (firstClass) {
10242                    final long ident = Binder.clearCallingIdentity();
10243
10244                    // If permissions need a review before any of the app components can run,
10245                    // we return no provider and launch a review activity if the calling app
10246                    // is in the foreground.
10247                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10248                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10249                            return null;
10250                        }
10251                    }
10252
10253                    try {
10254                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10255                        ApplicationInfo ai =
10256                            AppGlobals.getPackageManager().
10257                                getApplicationInfo(
10258                                        cpi.applicationInfo.packageName,
10259                                        STOCK_PM_FLAGS, userId);
10260                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10261                        if (ai == null) {
10262                            Slog.w(TAG, "No package info for content provider "
10263                                    + cpi.name);
10264                            return null;
10265                        }
10266                        ai = getAppInfoForUser(ai, userId);
10267                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10268                    } catch (RemoteException ex) {
10269                        // pm is in same process, this will never happen.
10270                    } finally {
10271                        Binder.restoreCallingIdentity(ident);
10272                    }
10273                }
10274
10275                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10276
10277                if (r != null && cpr.canRunHere(r)) {
10278                    // If this is a multiprocess provider, then just return its
10279                    // info and allow the caller to instantiate it.  Only do
10280                    // this if the provider is the same user as the caller's
10281                    // process, or can run as root (so can be in any process).
10282                    return cpr.newHolder(null);
10283                }
10284
10285                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10286                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10287                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10288
10289                // This is single process, and our app is now connecting to it.
10290                // See if we are already in the process of launching this
10291                // provider.
10292                final int N = mLaunchingProviders.size();
10293                int i;
10294                for (i = 0; i < N; i++) {
10295                    if (mLaunchingProviders.get(i) == cpr) {
10296                        break;
10297                    }
10298                }
10299
10300                // If the provider is not already being launched, then get it
10301                // started.
10302                if (i >= N) {
10303                    final long origId = Binder.clearCallingIdentity();
10304
10305                    try {
10306                        // Content provider is now in use, its package can't be stopped.
10307                        try {
10308                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10309                            AppGlobals.getPackageManager().setPackageStoppedState(
10310                                    cpr.appInfo.packageName, false, userId);
10311                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10312                        } catch (RemoteException e) {
10313                        } catch (IllegalArgumentException e) {
10314                            Slog.w(TAG, "Failed trying to unstop package "
10315                                    + cpr.appInfo.packageName + ": " + e);
10316                        }
10317
10318                        // Use existing process if already started
10319                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10320                        ProcessRecord proc = getProcessRecordLocked(
10321                                cpi.processName, cpr.appInfo.uid, false);
10322                        if (proc != null && proc.thread != null) {
10323                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10324                                    "Installing in existing process " + proc);
10325                            if (!proc.pubProviders.containsKey(cpi.name)) {
10326                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10327                                proc.pubProviders.put(cpi.name, cpr);
10328                                try {
10329                                    proc.thread.scheduleInstallProvider(cpi);
10330                                } catch (RemoteException e) {
10331                                }
10332                            }
10333                        } else {
10334                            checkTime(startTime, "getContentProviderImpl: before start process");
10335                            proc = startProcessLocked(cpi.processName,
10336                                    cpr.appInfo, false, 0, "content provider",
10337                                    new ComponentName(cpi.applicationInfo.packageName,
10338                                            cpi.name), false, false, false);
10339                            checkTime(startTime, "getContentProviderImpl: after start process");
10340                            if (proc == null) {
10341                                Slog.w(TAG, "Unable to launch app "
10342                                        + cpi.applicationInfo.packageName + "/"
10343                                        + cpi.applicationInfo.uid + " for provider "
10344                                        + name + ": process is bad");
10345                                return null;
10346                            }
10347                        }
10348                        cpr.launchingApp = proc;
10349                        mLaunchingProviders.add(cpr);
10350                    } finally {
10351                        Binder.restoreCallingIdentity(origId);
10352                    }
10353                }
10354
10355                checkTime(startTime, "getContentProviderImpl: updating data structures");
10356
10357                // Make sure the provider is published (the same provider class
10358                // may be published under multiple names).
10359                if (firstClass) {
10360                    mProviderMap.putProviderByClass(comp, cpr);
10361                }
10362
10363                mProviderMap.putProviderByName(name, cpr);
10364                conn = incProviderCountLocked(r, cpr, token, stable);
10365                if (conn != null) {
10366                    conn.waiting = true;
10367                }
10368            }
10369            checkTime(startTime, "getContentProviderImpl: done!");
10370        }
10371
10372        // Wait for the provider to be published...
10373        synchronized (cpr) {
10374            while (cpr.provider == null) {
10375                if (cpr.launchingApp == null) {
10376                    Slog.w(TAG, "Unable to launch app "
10377                            + cpi.applicationInfo.packageName + "/"
10378                            + cpi.applicationInfo.uid + " for provider "
10379                            + name + ": launching app became null");
10380                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10381                            UserHandle.getUserId(cpi.applicationInfo.uid),
10382                            cpi.applicationInfo.packageName,
10383                            cpi.applicationInfo.uid, name);
10384                    return null;
10385                }
10386                try {
10387                    if (DEBUG_MU) Slog.v(TAG_MU,
10388                            "Waiting to start provider " + cpr
10389                            + " launchingApp=" + cpr.launchingApp);
10390                    if (conn != null) {
10391                        conn.waiting = true;
10392                    }
10393                    cpr.wait();
10394                } catch (InterruptedException ex) {
10395                } finally {
10396                    if (conn != null) {
10397                        conn.waiting = false;
10398                    }
10399                }
10400            }
10401        }
10402        return cpr != null ? cpr.newHolder(conn) : null;
10403    }
10404
10405    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10406            ProcessRecord r, final int userId) {
10407        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10408                cpi.packageName, r.userId)) {
10409
10410            final boolean callerForeground = r != null ? r.setSchedGroup
10411                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10412
10413            // Show a permission review UI only for starting from a foreground app
10414            if (!callerForeground) {
10415                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10416                        + cpi.packageName + " requires a permissions review");
10417                return false;
10418            }
10419
10420            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10421            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10422                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10423            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10424
10425            if (DEBUG_PERMISSIONS_REVIEW) {
10426                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10427                        + "for package " + cpi.packageName);
10428            }
10429
10430            final UserHandle userHandle = new UserHandle(userId);
10431            mHandler.post(new Runnable() {
10432                @Override
10433                public void run() {
10434                    mContext.startActivityAsUser(intent, userHandle);
10435                }
10436            });
10437
10438            return false;
10439        }
10440
10441        return true;
10442    }
10443
10444    PackageManagerInternal getPackageManagerInternalLocked() {
10445        if (mPackageManagerInt == null) {
10446            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10447        }
10448        return mPackageManagerInt;
10449    }
10450
10451    @Override
10452    public final ContentProviderHolder getContentProvider(
10453            IApplicationThread caller, String name, int userId, boolean stable) {
10454        enforceNotIsolatedCaller("getContentProvider");
10455        if (caller == null) {
10456            String msg = "null IApplicationThread when getting content provider "
10457                    + name;
10458            Slog.w(TAG, msg);
10459            throw new SecurityException(msg);
10460        }
10461        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10462        // with cross-user grant.
10463        return getContentProviderImpl(caller, name, null, stable, userId);
10464    }
10465
10466    public ContentProviderHolder getContentProviderExternal(
10467            String name, int userId, IBinder token) {
10468        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10469            "Do not have permission in call getContentProviderExternal()");
10470        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10471                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10472        return getContentProviderExternalUnchecked(name, token, userId);
10473    }
10474
10475    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10476            IBinder token, int userId) {
10477        return getContentProviderImpl(null, name, token, true, userId);
10478    }
10479
10480    /**
10481     * Drop a content provider from a ProcessRecord's bookkeeping
10482     */
10483    public void removeContentProvider(IBinder connection, boolean stable) {
10484        enforceNotIsolatedCaller("removeContentProvider");
10485        long ident = Binder.clearCallingIdentity();
10486        try {
10487            synchronized (this) {
10488                ContentProviderConnection conn;
10489                try {
10490                    conn = (ContentProviderConnection)connection;
10491                } catch (ClassCastException e) {
10492                    String msg ="removeContentProvider: " + connection
10493                            + " not a ContentProviderConnection";
10494                    Slog.w(TAG, msg);
10495                    throw new IllegalArgumentException(msg);
10496                }
10497                if (conn == null) {
10498                    throw new NullPointerException("connection is null");
10499                }
10500                if (decProviderCountLocked(conn, null, null, stable)) {
10501                    updateOomAdjLocked();
10502                }
10503            }
10504        } finally {
10505            Binder.restoreCallingIdentity(ident);
10506        }
10507    }
10508
10509    public void removeContentProviderExternal(String name, IBinder token) {
10510        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10511            "Do not have permission in call removeContentProviderExternal()");
10512        int userId = UserHandle.getCallingUserId();
10513        long ident = Binder.clearCallingIdentity();
10514        try {
10515            removeContentProviderExternalUnchecked(name, token, userId);
10516        } finally {
10517            Binder.restoreCallingIdentity(ident);
10518        }
10519    }
10520
10521    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10522        synchronized (this) {
10523            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10524            if(cpr == null) {
10525                //remove from mProvidersByClass
10526                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10527                return;
10528            }
10529
10530            //update content provider record entry info
10531            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10532            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10533            if (localCpr.hasExternalProcessHandles()) {
10534                if (localCpr.removeExternalProcessHandleLocked(token)) {
10535                    updateOomAdjLocked();
10536                } else {
10537                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10538                            + " with no external reference for token: "
10539                            + token + ".");
10540                }
10541            } else {
10542                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10543                        + " with no external references.");
10544            }
10545        }
10546    }
10547
10548    public final void publishContentProviders(IApplicationThread caller,
10549            List<ContentProviderHolder> providers) {
10550        if (providers == null) {
10551            return;
10552        }
10553
10554        enforceNotIsolatedCaller("publishContentProviders");
10555        synchronized (this) {
10556            final ProcessRecord r = getRecordForAppLocked(caller);
10557            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10558            if (r == null) {
10559                throw new SecurityException(
10560                        "Unable to find app for caller " + caller
10561                      + " (pid=" + Binder.getCallingPid()
10562                      + ") when publishing content providers");
10563            }
10564
10565            final long origId = Binder.clearCallingIdentity();
10566
10567            final int N = providers.size();
10568            for (int i = 0; i < N; i++) {
10569                ContentProviderHolder src = providers.get(i);
10570                if (src == null || src.info == null || src.provider == null) {
10571                    continue;
10572                }
10573                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10574                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10575                if (dst != null) {
10576                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10577                    mProviderMap.putProviderByClass(comp, dst);
10578                    String names[] = dst.info.authority.split(";");
10579                    for (int j = 0; j < names.length; j++) {
10580                        mProviderMap.putProviderByName(names[j], dst);
10581                    }
10582
10583                    int launchingCount = mLaunchingProviders.size();
10584                    int j;
10585                    boolean wasInLaunchingProviders = false;
10586                    for (j = 0; j < launchingCount; j++) {
10587                        if (mLaunchingProviders.get(j) == dst) {
10588                            mLaunchingProviders.remove(j);
10589                            wasInLaunchingProviders = true;
10590                            j--;
10591                            launchingCount--;
10592                        }
10593                    }
10594                    if (wasInLaunchingProviders) {
10595                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10596                    }
10597                    synchronized (dst) {
10598                        dst.provider = src.provider;
10599                        dst.proc = r;
10600                        dst.notifyAll();
10601                    }
10602                    updateOomAdjLocked(r);
10603                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10604                            src.info.authority);
10605                }
10606            }
10607
10608            Binder.restoreCallingIdentity(origId);
10609        }
10610    }
10611
10612    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10613        ContentProviderConnection conn;
10614        try {
10615            conn = (ContentProviderConnection)connection;
10616        } catch (ClassCastException e) {
10617            String msg ="refContentProvider: " + connection
10618                    + " not a ContentProviderConnection";
10619            Slog.w(TAG, msg);
10620            throw new IllegalArgumentException(msg);
10621        }
10622        if (conn == null) {
10623            throw new NullPointerException("connection is null");
10624        }
10625
10626        synchronized (this) {
10627            if (stable > 0) {
10628                conn.numStableIncs += stable;
10629            }
10630            stable = conn.stableCount + stable;
10631            if (stable < 0) {
10632                throw new IllegalStateException("stableCount < 0: " + stable);
10633            }
10634
10635            if (unstable > 0) {
10636                conn.numUnstableIncs += unstable;
10637            }
10638            unstable = conn.unstableCount + unstable;
10639            if (unstable < 0) {
10640                throw new IllegalStateException("unstableCount < 0: " + unstable);
10641            }
10642
10643            if ((stable+unstable) <= 0) {
10644                throw new IllegalStateException("ref counts can't go to zero here: stable="
10645                        + stable + " unstable=" + unstable);
10646            }
10647            conn.stableCount = stable;
10648            conn.unstableCount = unstable;
10649            return !conn.dead;
10650        }
10651    }
10652
10653    public void unstableProviderDied(IBinder connection) {
10654        ContentProviderConnection conn;
10655        try {
10656            conn = (ContentProviderConnection)connection;
10657        } catch (ClassCastException e) {
10658            String msg ="refContentProvider: " + connection
10659                    + " not a ContentProviderConnection";
10660            Slog.w(TAG, msg);
10661            throw new IllegalArgumentException(msg);
10662        }
10663        if (conn == null) {
10664            throw new NullPointerException("connection is null");
10665        }
10666
10667        // Safely retrieve the content provider associated with the connection.
10668        IContentProvider provider;
10669        synchronized (this) {
10670            provider = conn.provider.provider;
10671        }
10672
10673        if (provider == null) {
10674            // Um, yeah, we're way ahead of you.
10675            return;
10676        }
10677
10678        // Make sure the caller is being honest with us.
10679        if (provider.asBinder().pingBinder()) {
10680            // Er, no, still looks good to us.
10681            synchronized (this) {
10682                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10683                        + " says " + conn + " died, but we don't agree");
10684                return;
10685            }
10686        }
10687
10688        // Well look at that!  It's dead!
10689        synchronized (this) {
10690            if (conn.provider.provider != provider) {
10691                // But something changed...  good enough.
10692                return;
10693            }
10694
10695            ProcessRecord proc = conn.provider.proc;
10696            if (proc == null || proc.thread == null) {
10697                // Seems like the process is already cleaned up.
10698                return;
10699            }
10700
10701            // As far as we're concerned, this is just like receiving a
10702            // death notification...  just a bit prematurely.
10703            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10704                    + ") early provider death");
10705            final long ident = Binder.clearCallingIdentity();
10706            try {
10707                appDiedLocked(proc);
10708            } finally {
10709                Binder.restoreCallingIdentity(ident);
10710            }
10711        }
10712    }
10713
10714    @Override
10715    public void appNotRespondingViaProvider(IBinder connection) {
10716        enforceCallingPermission(
10717                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10718
10719        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10720        if (conn == null) {
10721            Slog.w(TAG, "ContentProviderConnection is null");
10722            return;
10723        }
10724
10725        final ProcessRecord host = conn.provider.proc;
10726        if (host == null) {
10727            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10728            return;
10729        }
10730
10731        final long token = Binder.clearCallingIdentity();
10732        try {
10733            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10734        } finally {
10735            Binder.restoreCallingIdentity(token);
10736        }
10737    }
10738
10739    public final void installSystemProviders() {
10740        List<ProviderInfo> providers;
10741        synchronized (this) {
10742            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10743            providers = generateApplicationProvidersLocked(app);
10744            if (providers != null) {
10745                for (int i=providers.size()-1; i>=0; i--) {
10746                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10747                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10748                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10749                                + ": not system .apk");
10750                        providers.remove(i);
10751                    }
10752                }
10753            }
10754        }
10755        if (providers != null) {
10756            mSystemThread.installSystemProviders(providers);
10757        }
10758
10759        mCoreSettingsObserver = new CoreSettingsObserver(this);
10760        mFontScaleSettingObserver = new FontScaleSettingObserver();
10761
10762        //mUsageStatsService.monitorPackages();
10763    }
10764
10765    /**
10766     * When a user is unlocked, we need to install encryption-unaware providers
10767     * belonging to any running apps.
10768     */
10769    private void installEncryptionUnawareProviders(int userId) {
10770        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10771            // TODO: eventually pivot this back to look at current user state,
10772            // similar to the comment in UserManager.isUserUnlocked(), but for
10773            // now, if we started apps when "unlocked" then unaware providers
10774            // have already been spun up.
10775            return;
10776        }
10777
10778        // We're only interested in providers that are encryption unaware, and
10779        // we don't care about uninstalled apps, since there's no way they're
10780        // running at this point.
10781        final int matchFlags = GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE
10782                | MATCH_DEBUG_TRIAGED_MISSING;
10783
10784        synchronized (this) {
10785            final int NP = mProcessNames.getMap().size();
10786            for (int ip = 0; ip < NP; ip++) {
10787                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10788                final int NA = apps.size();
10789                for (int ia = 0; ia < NA; ia++) {
10790                    final ProcessRecord app = apps.valueAt(ia);
10791                    if (app.userId != userId || app.thread == null) continue;
10792
10793                    final int NG = app.pkgList.size();
10794                    for (int ig = 0; ig < NG; ig++) {
10795                        try {
10796                            final String pkgName = app.pkgList.keyAt(ig);
10797                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10798                                    .getPackageInfo(pkgName, matchFlags, userId);
10799                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10800                                for (ProviderInfo provInfo : pkgInfo.providers) {
10801                                    Log.v(TAG, "Installing " + provInfo);
10802                                    app.thread.scheduleInstallProvider(provInfo);
10803                                }
10804                            }
10805                        } catch (RemoteException ignored) {
10806                        }
10807                    }
10808                }
10809            }
10810        }
10811    }
10812
10813    /**
10814     * Allows apps to retrieve the MIME type of a URI.
10815     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10816     * users, then it does not need permission to access the ContentProvider.
10817     * Either, it needs cross-user uri grants.
10818     *
10819     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10820     *
10821     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10822     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10823     */
10824    public String getProviderMimeType(Uri uri, int userId) {
10825        enforceNotIsolatedCaller("getProviderMimeType");
10826        final String name = uri.getAuthority();
10827        int callingUid = Binder.getCallingUid();
10828        int callingPid = Binder.getCallingPid();
10829        long ident = 0;
10830        boolean clearedIdentity = false;
10831        synchronized (this) {
10832            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10833        }
10834        if (canClearIdentity(callingPid, callingUid, userId)) {
10835            clearedIdentity = true;
10836            ident = Binder.clearCallingIdentity();
10837        }
10838        ContentProviderHolder holder = null;
10839        try {
10840            holder = getContentProviderExternalUnchecked(name, null, userId);
10841            if (holder != null) {
10842                return holder.provider.getType(uri);
10843            }
10844        } catch (RemoteException e) {
10845            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10846            return null;
10847        } finally {
10848            // We need to clear the identity to call removeContentProviderExternalUnchecked
10849            if (!clearedIdentity) {
10850                ident = Binder.clearCallingIdentity();
10851            }
10852            try {
10853                if (holder != null) {
10854                    removeContentProviderExternalUnchecked(name, null, userId);
10855                }
10856            } finally {
10857                Binder.restoreCallingIdentity(ident);
10858            }
10859        }
10860
10861        return null;
10862    }
10863
10864    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10865        if (UserHandle.getUserId(callingUid) == userId) {
10866            return true;
10867        }
10868        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10869                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10870                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10871                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10872                return true;
10873        }
10874        return false;
10875    }
10876
10877    // =========================================================
10878    // GLOBAL MANAGEMENT
10879    // =========================================================
10880
10881    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10882            boolean isolated, int isolatedUid) {
10883        String proc = customProcess != null ? customProcess : info.processName;
10884        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10885        final int userId = UserHandle.getUserId(info.uid);
10886        int uid = info.uid;
10887        if (isolated) {
10888            if (isolatedUid == 0) {
10889                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10890                while (true) {
10891                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10892                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10893                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10894                    }
10895                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10896                    mNextIsolatedProcessUid++;
10897                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10898                        // No process for this uid, use it.
10899                        break;
10900                    }
10901                    stepsLeft--;
10902                    if (stepsLeft <= 0) {
10903                        return null;
10904                    }
10905                }
10906            } else {
10907                // Special case for startIsolatedProcess (internal only), where
10908                // the uid of the isolated process is specified by the caller.
10909                uid = isolatedUid;
10910            }
10911        }
10912        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10913        if (!mBooted && !mBooting
10914                && userId == UserHandle.USER_SYSTEM
10915                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10916            r.persistent = true;
10917        }
10918        addProcessNameLocked(r);
10919        return r;
10920    }
10921
10922    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10923            String abiOverride) {
10924        ProcessRecord app;
10925        if (!isolated) {
10926            app = getProcessRecordLocked(info.processName, info.uid, true);
10927        } else {
10928            app = null;
10929        }
10930
10931        if (app == null) {
10932            app = newProcessRecordLocked(info, null, isolated, 0);
10933            updateLruProcessLocked(app, false, null);
10934            updateOomAdjLocked();
10935        }
10936
10937        // This package really, really can not be stopped.
10938        try {
10939            AppGlobals.getPackageManager().setPackageStoppedState(
10940                    info.packageName, false, UserHandle.getUserId(app.uid));
10941        } catch (RemoteException e) {
10942        } catch (IllegalArgumentException e) {
10943            Slog.w(TAG, "Failed trying to unstop package "
10944                    + info.packageName + ": " + e);
10945        }
10946
10947        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10948            app.persistent = true;
10949            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10950        }
10951        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10952            mPersistentStartingProcesses.add(app);
10953            startProcessLocked(app, "added application", app.processName, abiOverride,
10954                    null /* entryPoint */, null /* entryPointArgs */);
10955        }
10956
10957        return app;
10958    }
10959
10960    public void unhandledBack() {
10961        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10962                "unhandledBack()");
10963
10964        synchronized(this) {
10965            final long origId = Binder.clearCallingIdentity();
10966            try {
10967                getFocusedStack().unhandledBackLocked();
10968            } finally {
10969                Binder.restoreCallingIdentity(origId);
10970            }
10971        }
10972    }
10973
10974    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10975        enforceNotIsolatedCaller("openContentUri");
10976        final int userId = UserHandle.getCallingUserId();
10977        String name = uri.getAuthority();
10978        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10979        ParcelFileDescriptor pfd = null;
10980        if (cph != null) {
10981            // We record the binder invoker's uid in thread-local storage before
10982            // going to the content provider to open the file.  Later, in the code
10983            // that handles all permissions checks, we look for this uid and use
10984            // that rather than the Activity Manager's own uid.  The effect is that
10985            // we do the check against the caller's permissions even though it looks
10986            // to the content provider like the Activity Manager itself is making
10987            // the request.
10988            Binder token = new Binder();
10989            sCallerIdentity.set(new Identity(
10990                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10991            try {
10992                pfd = cph.provider.openFile(null, uri, "r", null, token);
10993            } catch (FileNotFoundException e) {
10994                // do nothing; pfd will be returned null
10995            } finally {
10996                // Ensure that whatever happens, we clean up the identity state
10997                sCallerIdentity.remove();
10998                // Ensure we're done with the provider.
10999                removeContentProviderExternalUnchecked(name, null, userId);
11000            }
11001        } else {
11002            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11003        }
11004        return pfd;
11005    }
11006
11007    // Actually is sleeping or shutting down or whatever else in the future
11008    // is an inactive state.
11009    public boolean isSleepingOrShuttingDown() {
11010        return isSleeping() || mShuttingDown;
11011    }
11012
11013    public boolean isSleeping() {
11014        return mSleeping;
11015    }
11016
11017    void onWakefulnessChanged(int wakefulness) {
11018        synchronized(this) {
11019            mWakefulness = wakefulness;
11020            updateSleepIfNeededLocked();
11021        }
11022    }
11023
11024    void finishRunningVoiceLocked() {
11025        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
11026        if (mRunningVoice != null) {
11027            mRunningVoice = null;
11028            mVoiceWakeLock.release();
11029            updateSleepIfNeededLocked();
11030        }
11031    }
11032
11033    void startTimeTrackingFocusedActivityLocked() {
11034        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11035            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11036        }
11037    }
11038
11039    void updateSleepIfNeededLocked() {
11040        if (mSleeping && !shouldSleepLocked()) {
11041            mSleeping = false;
11042            startTimeTrackingFocusedActivityLocked();
11043            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11044            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11045            updateOomAdjLocked();
11046        } else if (!mSleeping && shouldSleepLocked()) {
11047            mSleeping = true;
11048            if (mCurAppTimeTracker != null) {
11049                mCurAppTimeTracker.stop();
11050            }
11051            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11052            mStackSupervisor.goingToSleepLocked();
11053            updateOomAdjLocked();
11054
11055            // Initialize the wake times of all processes.
11056            checkExcessivePowerUsageLocked(false);
11057            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11058            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11059            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11060        }
11061    }
11062
11063    private boolean shouldSleepLocked() {
11064        // Resume applications while running a voice interactor.
11065        if (mRunningVoice != null) {
11066            return false;
11067        }
11068
11069        // TODO: Transform the lock screen state into a sleep token instead.
11070        switch (mWakefulness) {
11071            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11072            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11073            case PowerManagerInternal.WAKEFULNESS_DOZING:
11074                // Pause applications whenever the lock screen is shown or any sleep
11075                // tokens have been acquired.
11076                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11077            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11078            default:
11079                // If we're asleep then pause applications unconditionally.
11080                return true;
11081        }
11082    }
11083
11084    /** Pokes the task persister. */
11085    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11086        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11087    }
11088
11089    /** Notifies all listeners when the task stack has changed. */
11090    void notifyTaskStackChangedLocked() {
11091        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11092        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11093        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11094        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11095    }
11096
11097    /** Notifies all listeners when an Activity is pinned. */
11098    void notifyActivityPinnedLocked() {
11099        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11100        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11101    }
11102
11103    /**
11104     * Notifies all listeners when an attempt was made to start an an activity that is already
11105     * running in the pinned stack and the activity was not actually started, but the task is
11106     * either brought to the front or a new Intent is delivered to it.
11107     */
11108    void notifyPinnedActivityRestartAttemptLocked() {
11109        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11110        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11111    }
11112
11113    /** Notifies all listeners when the pinned stack animation ends. */
11114    @Override
11115    public void notifyPinnedStackAnimationEnded() {
11116        synchronized (this) {
11117            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11118            mHandler.obtainMessage(
11119                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11120        }
11121    }
11122
11123    @Override
11124    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11125        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11126    }
11127
11128    @Override
11129    public boolean shutdown(int timeout) {
11130        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11131                != PackageManager.PERMISSION_GRANTED) {
11132            throw new SecurityException("Requires permission "
11133                    + android.Manifest.permission.SHUTDOWN);
11134        }
11135
11136        boolean timedout = false;
11137
11138        synchronized(this) {
11139            mShuttingDown = true;
11140            updateEventDispatchingLocked();
11141            timedout = mStackSupervisor.shutdownLocked(timeout);
11142        }
11143
11144        mAppOpsService.shutdown();
11145        if (mUsageStatsService != null) {
11146            mUsageStatsService.prepareShutdown();
11147        }
11148        mBatteryStatsService.shutdown();
11149        synchronized (this) {
11150            mProcessStats.shutdownLocked();
11151            notifyTaskPersisterLocked(null, true);
11152        }
11153
11154        return timedout;
11155    }
11156
11157    public final void activitySlept(IBinder token) {
11158        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11159
11160        final long origId = Binder.clearCallingIdentity();
11161
11162        synchronized (this) {
11163            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11164            if (r != null) {
11165                mStackSupervisor.activitySleptLocked(r);
11166            }
11167        }
11168
11169        Binder.restoreCallingIdentity(origId);
11170    }
11171
11172    private String lockScreenShownToString() {
11173        switch (mLockScreenShown) {
11174            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11175            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11176            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11177            default: return "Unknown=" + mLockScreenShown;
11178        }
11179    }
11180
11181    void logLockScreen(String msg) {
11182        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11183                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11184                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11185                + " mSleeping=" + mSleeping);
11186    }
11187
11188    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11189        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11190        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11191        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11192            boolean wasRunningVoice = mRunningVoice != null;
11193            mRunningVoice = session;
11194            if (!wasRunningVoice) {
11195                mVoiceWakeLock.acquire();
11196                updateSleepIfNeededLocked();
11197            }
11198        }
11199    }
11200
11201    private void updateEventDispatchingLocked() {
11202        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11203    }
11204
11205    public void setLockScreenShown(boolean shown) {
11206        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11207                != PackageManager.PERMISSION_GRANTED) {
11208            throw new SecurityException("Requires permission "
11209                    + android.Manifest.permission.DEVICE_POWER);
11210        }
11211
11212        final int user = UserHandle.myUserId();
11213        synchronized(this) {
11214            long ident = Binder.clearCallingIdentity();
11215            try {
11216                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11217                    startHomeActivityLocked(user, "setLockScreenShown");
11218                }
11219                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11220                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11221                updateSleepIfNeededLocked();
11222            } finally {
11223                Binder.restoreCallingIdentity(ident);
11224            }
11225        }
11226    }
11227
11228    @Override
11229    public void stopAppSwitches() {
11230        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11231                != PackageManager.PERMISSION_GRANTED) {
11232            throw new SecurityException("viewquires permission "
11233                    + android.Manifest.permission.STOP_APP_SWITCHES);
11234        }
11235
11236        synchronized(this) {
11237            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11238                    + APP_SWITCH_DELAY_TIME;
11239            mDidAppSwitch = false;
11240            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11241            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11242            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11243        }
11244    }
11245
11246    public void resumeAppSwitches() {
11247        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11248                != PackageManager.PERMISSION_GRANTED) {
11249            throw new SecurityException("Requires permission "
11250                    + android.Manifest.permission.STOP_APP_SWITCHES);
11251        }
11252
11253        synchronized(this) {
11254            // Note that we don't execute any pending app switches... we will
11255            // let those wait until either the timeout, or the next start
11256            // activity request.
11257            mAppSwitchesAllowedTime = 0;
11258        }
11259    }
11260
11261    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11262            int callingPid, int callingUid, String name) {
11263        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11264            return true;
11265        }
11266
11267        int perm = checkComponentPermission(
11268                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11269                sourceUid, -1, true);
11270        if (perm == PackageManager.PERMISSION_GRANTED) {
11271            return true;
11272        }
11273
11274        // If the actual IPC caller is different from the logical source, then
11275        // also see if they are allowed to control app switches.
11276        if (callingUid != -1 && callingUid != sourceUid) {
11277            perm = checkComponentPermission(
11278                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11279                    callingUid, -1, true);
11280            if (perm == PackageManager.PERMISSION_GRANTED) {
11281                return true;
11282            }
11283        }
11284
11285        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11286        return false;
11287    }
11288
11289    public void setDebugApp(String packageName, boolean waitForDebugger,
11290            boolean persistent) {
11291        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11292                "setDebugApp()");
11293
11294        long ident = Binder.clearCallingIdentity();
11295        try {
11296            // Note that this is not really thread safe if there are multiple
11297            // callers into it at the same time, but that's not a situation we
11298            // care about.
11299            if (persistent) {
11300                final ContentResolver resolver = mContext.getContentResolver();
11301                Settings.Global.putString(
11302                    resolver, Settings.Global.DEBUG_APP,
11303                    packageName);
11304                Settings.Global.putInt(
11305                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11306                    waitForDebugger ? 1 : 0);
11307            }
11308
11309            synchronized (this) {
11310                if (!persistent) {
11311                    mOrigDebugApp = mDebugApp;
11312                    mOrigWaitForDebugger = mWaitForDebugger;
11313                }
11314                mDebugApp = packageName;
11315                mWaitForDebugger = waitForDebugger;
11316                mDebugTransient = !persistent;
11317                if (packageName != null) {
11318                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11319                            false, UserHandle.USER_ALL, "set debug app");
11320                }
11321            }
11322        } finally {
11323            Binder.restoreCallingIdentity(ident);
11324        }
11325    }
11326
11327    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11328        synchronized (this) {
11329            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11330            if (!isDebuggable) {
11331                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11332                    throw new SecurityException("Process not debuggable: " + app.packageName);
11333                }
11334            }
11335
11336            mTrackAllocationApp = processName;
11337        }
11338    }
11339
11340    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11341        synchronized (this) {
11342            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11343            if (!isDebuggable) {
11344                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11345                    throw new SecurityException("Process not debuggable: " + app.packageName);
11346                }
11347            }
11348            mProfileApp = processName;
11349            mProfileFile = profilerInfo.profileFile;
11350            if (mProfileFd != null) {
11351                try {
11352                    mProfileFd.close();
11353                } catch (IOException e) {
11354                }
11355                mProfileFd = null;
11356            }
11357            mProfileFd = profilerInfo.profileFd;
11358            mSamplingInterval = profilerInfo.samplingInterval;
11359            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11360            mProfileType = 0;
11361        }
11362    }
11363
11364    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11365        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11366        if (!isDebuggable) {
11367            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11368                throw new SecurityException("Process not debuggable: " + app.packageName);
11369            }
11370        }
11371        mNativeDebuggingApp = processName;
11372    }
11373
11374    @Override
11375    public void setAlwaysFinish(boolean enabled) {
11376        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11377                "setAlwaysFinish()");
11378
11379        Settings.Global.putInt(
11380                mContext.getContentResolver(),
11381                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11382
11383        synchronized (this) {
11384            mAlwaysFinishActivities = enabled;
11385        }
11386    }
11387
11388    @Override
11389    public void setActivityController(IActivityController controller) {
11390        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11391                "setActivityController()");
11392        synchronized (this) {
11393            mController = controller;
11394            Watchdog.getInstance().setActivityController(controller);
11395        }
11396    }
11397
11398    @Override
11399    public void setUserIsMonkey(boolean userIsMonkey) {
11400        synchronized (this) {
11401            synchronized (mPidsSelfLocked) {
11402                final int callingPid = Binder.getCallingPid();
11403                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11404                if (precessRecord == null) {
11405                    throw new SecurityException("Unknown process: " + callingPid);
11406                }
11407                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11408                    throw new SecurityException("Only an instrumentation process "
11409                            + "with a UiAutomation can call setUserIsMonkey");
11410                }
11411            }
11412            mUserIsMonkey = userIsMonkey;
11413        }
11414    }
11415
11416    @Override
11417    public boolean isUserAMonkey() {
11418        synchronized (this) {
11419            // If there is a controller also implies the user is a monkey.
11420            return (mUserIsMonkey || mController != null);
11421        }
11422    }
11423
11424    public void requestBugReport(int bugreportType) {
11425        String service = null;
11426        switch (bugreportType) {
11427            case ActivityManager.BUGREPORT_OPTION_FULL:
11428                service = "bugreport";
11429                break;
11430            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11431                service = "bugreportplus";
11432                break;
11433            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11434                service = "bugreportremote";
11435                break;
11436        }
11437        if (service == null) {
11438            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11439                    + bugreportType);
11440        }
11441        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11442        SystemProperties.set("ctl.start", service);
11443    }
11444
11445    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11446        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11447    }
11448
11449    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11450        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11451            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11452        }
11453        return KEY_DISPATCHING_TIMEOUT;
11454    }
11455
11456    @Override
11457    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11458        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11459                != PackageManager.PERMISSION_GRANTED) {
11460            throw new SecurityException("Requires permission "
11461                    + android.Manifest.permission.FILTER_EVENTS);
11462        }
11463        ProcessRecord proc;
11464        long timeout;
11465        synchronized (this) {
11466            synchronized (mPidsSelfLocked) {
11467                proc = mPidsSelfLocked.get(pid);
11468            }
11469            timeout = getInputDispatchingTimeoutLocked(proc);
11470        }
11471
11472        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11473            return -1;
11474        }
11475
11476        return timeout;
11477    }
11478
11479    /**
11480     * Handle input dispatching timeouts.
11481     * Returns whether input dispatching should be aborted or not.
11482     */
11483    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11484            final ActivityRecord activity, final ActivityRecord parent,
11485            final boolean aboveSystem, String reason) {
11486        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11487                != PackageManager.PERMISSION_GRANTED) {
11488            throw new SecurityException("Requires permission "
11489                    + android.Manifest.permission.FILTER_EVENTS);
11490        }
11491
11492        final String annotation;
11493        if (reason == null) {
11494            annotation = "Input dispatching timed out";
11495        } else {
11496            annotation = "Input dispatching timed out (" + reason + ")";
11497        }
11498
11499        if (proc != null) {
11500            synchronized (this) {
11501                if (proc.debugging) {
11502                    return false;
11503                }
11504
11505                if (mDidDexOpt) {
11506                    // Give more time since we were dexopting.
11507                    mDidDexOpt = false;
11508                    return false;
11509                }
11510
11511                if (proc.instrumentationClass != null) {
11512                    Bundle info = new Bundle();
11513                    info.putString("shortMsg", "keyDispatchingTimedOut");
11514                    info.putString("longMsg", annotation);
11515                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11516                    return true;
11517                }
11518            }
11519            mHandler.post(new Runnable() {
11520                @Override
11521                public void run() {
11522                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11523                }
11524            });
11525        }
11526
11527        return true;
11528    }
11529
11530    @Override
11531    public Bundle getAssistContextExtras(int requestType) {
11532        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11533                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11534        if (pae == null) {
11535            return null;
11536        }
11537        synchronized (pae) {
11538            while (!pae.haveResult) {
11539                try {
11540                    pae.wait();
11541                } catch (InterruptedException e) {
11542                }
11543            }
11544        }
11545        synchronized (this) {
11546            buildAssistBundleLocked(pae, pae.result);
11547            mPendingAssistExtras.remove(pae);
11548            mUiHandler.removeCallbacks(pae);
11549        }
11550        return pae.extras;
11551    }
11552
11553    @Override
11554    public boolean isAssistDataAllowedOnCurrentActivity() {
11555        int userId;
11556        synchronized (this) {
11557            userId = mUserController.getCurrentUserIdLocked();
11558            ActivityRecord activity = getFocusedStack().topActivity();
11559            if (activity == null) {
11560                return false;
11561            }
11562            userId = activity.userId;
11563        }
11564        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11565                Context.DEVICE_POLICY_SERVICE);
11566        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11567    }
11568
11569    @Override
11570    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11571        long ident = Binder.clearCallingIdentity();
11572        try {
11573            synchronized (this) {
11574                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11575                ActivityRecord top = getFocusedStack().topActivity();
11576                if (top != caller) {
11577                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11578                            + " is not current top " + top);
11579                    return false;
11580                }
11581                if (!top.nowVisible) {
11582                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11583                            + " is not visible");
11584                    return false;
11585                }
11586            }
11587            AssistUtils utils = new AssistUtils(mContext);
11588            return utils.showSessionForActiveService(args,
11589                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11590        } finally {
11591            Binder.restoreCallingIdentity(ident);
11592        }
11593    }
11594
11595    @Override
11596    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11597            IBinder activityToken) {
11598        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11599                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11600    }
11601
11602    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11603            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11604            long timeout) {
11605        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11606                "enqueueAssistContext()");
11607        synchronized (this) {
11608            ActivityRecord activity = getFocusedStack().topActivity();
11609            if (activity == null) {
11610                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11611                return null;
11612            }
11613            if (activity.app == null || activity.app.thread == null) {
11614                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11615                return null;
11616            }
11617            if (activityToken != null) {
11618                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11619                if (activity != caller) {
11620                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11621                            + " is not current top " + activity);
11622                    return null;
11623                }
11624            }
11625            PendingAssistExtras pae;
11626            Bundle extras = new Bundle();
11627            if (args != null) {
11628                extras.putAll(args);
11629            }
11630            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11631            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11632            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11633            try {
11634                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11635                        requestType);
11636                mPendingAssistExtras.add(pae);
11637                mUiHandler.postDelayed(pae, timeout);
11638            } catch (RemoteException e) {
11639                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11640                return null;
11641            }
11642            return pae;
11643        }
11644    }
11645
11646    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11647        IResultReceiver receiver;
11648        synchronized (this) {
11649            mPendingAssistExtras.remove(pae);
11650            receiver = pae.receiver;
11651        }
11652        if (receiver != null) {
11653            // Caller wants result sent back to them.
11654            try {
11655                pae.receiver.send(0, null);
11656            } catch (RemoteException e) {
11657            }
11658        }
11659    }
11660
11661    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11662        if (result != null) {
11663            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11664        }
11665        if (pae.hint != null) {
11666            pae.extras.putBoolean(pae.hint, true);
11667        }
11668    }
11669
11670    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11671            AssistContent content, Uri referrer) {
11672        PendingAssistExtras pae = (PendingAssistExtras)token;
11673        synchronized (pae) {
11674            pae.result = extras;
11675            pae.structure = structure;
11676            pae.content = content;
11677            if (referrer != null) {
11678                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11679            }
11680            pae.haveResult = true;
11681            pae.notifyAll();
11682            if (pae.intent == null && pae.receiver == null) {
11683                // Caller is just waiting for the result.
11684                return;
11685            }
11686        }
11687
11688        // We are now ready to launch the assist activity.
11689        IResultReceiver sendReceiver = null;
11690        Bundle sendBundle = null;
11691        synchronized (this) {
11692            buildAssistBundleLocked(pae, extras);
11693            boolean exists = mPendingAssistExtras.remove(pae);
11694            mUiHandler.removeCallbacks(pae);
11695            if (!exists) {
11696                // Timed out.
11697                return;
11698            }
11699            if ((sendReceiver=pae.receiver) != null) {
11700                // Caller wants result sent back to them.
11701                sendBundle = new Bundle();
11702                sendBundle.putBundle("data", pae.extras);
11703                sendBundle.putParcelable("structure", pae.structure);
11704                sendBundle.putParcelable("content", pae.content);
11705            }
11706        }
11707        if (sendReceiver != null) {
11708            try {
11709                sendReceiver.send(0, sendBundle);
11710            } catch (RemoteException e) {
11711            }
11712            return;
11713        }
11714
11715        long ident = Binder.clearCallingIdentity();
11716        try {
11717            pae.intent.replaceExtras(pae.extras);
11718            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11719                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11720                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11721            closeSystemDialogs("assist");
11722            try {
11723                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11724            } catch (ActivityNotFoundException e) {
11725                Slog.w(TAG, "No activity to handle assist action.", e);
11726            }
11727        } finally {
11728            Binder.restoreCallingIdentity(ident);
11729        }
11730    }
11731
11732    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11733            Bundle args) {
11734        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11735                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11736    }
11737
11738    public void registerProcessObserver(IProcessObserver observer) {
11739        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11740                "registerProcessObserver()");
11741        synchronized (this) {
11742            mProcessObservers.register(observer);
11743        }
11744    }
11745
11746    @Override
11747    public void unregisterProcessObserver(IProcessObserver observer) {
11748        synchronized (this) {
11749            mProcessObservers.unregister(observer);
11750        }
11751    }
11752
11753    @Override
11754    public void registerUidObserver(IUidObserver observer, int which) {
11755        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11756                "registerUidObserver()");
11757        synchronized (this) {
11758            mUidObservers.register(observer, which);
11759        }
11760    }
11761
11762    @Override
11763    public void unregisterUidObserver(IUidObserver observer) {
11764        synchronized (this) {
11765            mUidObservers.unregister(observer);
11766        }
11767    }
11768
11769    @Override
11770    public boolean convertFromTranslucent(IBinder token) {
11771        final long origId = Binder.clearCallingIdentity();
11772        try {
11773            synchronized (this) {
11774                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11775                if (r == null) {
11776                    return false;
11777                }
11778                final boolean translucentChanged = r.changeWindowTranslucency(true);
11779                if (translucentChanged) {
11780                    r.task.stack.releaseBackgroundResources(r);
11781                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11782                }
11783                mWindowManager.setAppFullscreen(token, true);
11784                return translucentChanged;
11785            }
11786        } finally {
11787            Binder.restoreCallingIdentity(origId);
11788        }
11789    }
11790
11791    @Override
11792    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11793        final long origId = Binder.clearCallingIdentity();
11794        try {
11795            synchronized (this) {
11796                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11797                if (r == null) {
11798                    return false;
11799                }
11800                int index = r.task.mActivities.lastIndexOf(r);
11801                if (index > 0) {
11802                    ActivityRecord under = r.task.mActivities.get(index - 1);
11803                    under.returningOptions = options;
11804                }
11805                final boolean translucentChanged = r.changeWindowTranslucency(false);
11806                if (translucentChanged) {
11807                    r.task.stack.convertActivityToTranslucent(r);
11808                }
11809                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11810                mWindowManager.setAppFullscreen(token, false);
11811                return translucentChanged;
11812            }
11813        } finally {
11814            Binder.restoreCallingIdentity(origId);
11815        }
11816    }
11817
11818    @Override
11819    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11820        final long origId = Binder.clearCallingIdentity();
11821        try {
11822            synchronized (this) {
11823                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11824                if (r != null) {
11825                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11826                }
11827            }
11828            return false;
11829        } finally {
11830            Binder.restoreCallingIdentity(origId);
11831        }
11832    }
11833
11834    @Override
11835    public boolean isBackgroundVisibleBehind(IBinder token) {
11836        final long origId = Binder.clearCallingIdentity();
11837        try {
11838            synchronized (this) {
11839                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11840                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11841                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11842                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11843                return visible;
11844            }
11845        } finally {
11846            Binder.restoreCallingIdentity(origId);
11847        }
11848    }
11849
11850    @Override
11851    public ActivityOptions getActivityOptions(IBinder token) {
11852        final long origId = Binder.clearCallingIdentity();
11853        try {
11854            synchronized (this) {
11855                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11856                if (r != null) {
11857                    final ActivityOptions activityOptions = r.pendingOptions;
11858                    r.pendingOptions = null;
11859                    return activityOptions;
11860                }
11861                return null;
11862            }
11863        } finally {
11864            Binder.restoreCallingIdentity(origId);
11865        }
11866    }
11867
11868    @Override
11869    public void setImmersive(IBinder token, boolean immersive) {
11870        synchronized(this) {
11871            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11872            if (r == null) {
11873                throw new IllegalArgumentException();
11874            }
11875            r.immersive = immersive;
11876
11877            // update associated state if we're frontmost
11878            if (r == mFocusedActivity) {
11879                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11880                applyUpdateLockStateLocked(r);
11881            }
11882        }
11883    }
11884
11885    @Override
11886    public boolean isImmersive(IBinder token) {
11887        synchronized (this) {
11888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11889            if (r == null) {
11890                throw new IllegalArgumentException();
11891            }
11892            return r.immersive;
11893        }
11894    }
11895
11896    @Override
11897    public void setVrMode(IBinder token, boolean enabled) {
11898        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11899            throw new UnsupportedOperationException("VR mode not supported on this device!");
11900        }
11901
11902        synchronized(this) {
11903            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11904            if (r == null) {
11905                throw new IllegalArgumentException();
11906            }
11907            r.isVrActivity = enabled;
11908
11909            // Update associated state if this activity is currently focused
11910            if (r == mFocusedActivity) {
11911                applyUpdateVrModeLocked(r);
11912            }
11913        }
11914    }
11915
11916    public boolean isTopActivityImmersive() {
11917        enforceNotIsolatedCaller("startActivity");
11918        synchronized (this) {
11919            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11920            return (r != null) ? r.immersive : false;
11921        }
11922    }
11923
11924    @Override
11925    public boolean isTopOfTask(IBinder token) {
11926        synchronized (this) {
11927            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11928            if (r == null) {
11929                throw new IllegalArgumentException();
11930            }
11931            return r.task.getTopActivity() == r;
11932        }
11933    }
11934
11935    public final void enterSafeMode() {
11936        synchronized(this) {
11937            // It only makes sense to do this before the system is ready
11938            // and started launching other packages.
11939            if (!mSystemReady) {
11940                try {
11941                    AppGlobals.getPackageManager().enterSafeMode();
11942                } catch (RemoteException e) {
11943                }
11944            }
11945
11946            mSafeMode = true;
11947        }
11948    }
11949
11950    public final void showSafeModeOverlay() {
11951        View v = LayoutInflater.from(mContext).inflate(
11952                com.android.internal.R.layout.safe_mode, null);
11953        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11954        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11955        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11956        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11957        lp.gravity = Gravity.BOTTOM | Gravity.START;
11958        lp.format = v.getBackground().getOpacity();
11959        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11960                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11961        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11962        ((WindowManager)mContext.getSystemService(
11963                Context.WINDOW_SERVICE)).addView(v, lp);
11964    }
11965
11966    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11967        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11968            return;
11969        }
11970        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11971        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11972        synchronized (stats) {
11973            if (mBatteryStatsService.isOnBattery()) {
11974                mBatteryStatsService.enforceCallingPermission();
11975                int MY_UID = Binder.getCallingUid();
11976                final int uid;
11977                if (sender == null) {
11978                    uid = sourceUid;
11979                } else {
11980                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11981                }
11982                BatteryStatsImpl.Uid.Pkg pkg =
11983                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11984                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11985                pkg.noteWakeupAlarmLocked(tag);
11986            }
11987        }
11988    }
11989
11990    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11991        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11992            return;
11993        }
11994        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11995        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11996        synchronized (stats) {
11997            mBatteryStatsService.enforceCallingPermission();
11998            int MY_UID = Binder.getCallingUid();
11999            final int uid;
12000            if (sender == null) {
12001                uid = sourceUid;
12002            } else {
12003                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12004            }
12005            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12006        }
12007    }
12008
12009    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12010        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12011            return;
12012        }
12013        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12014        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12015        synchronized (stats) {
12016            mBatteryStatsService.enforceCallingPermission();
12017            int MY_UID = Binder.getCallingUid();
12018            final int uid;
12019            if (sender == null) {
12020                uid = sourceUid;
12021            } else {
12022                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12023            }
12024            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12025        }
12026    }
12027
12028    public boolean killPids(int[] pids, String pReason, boolean secure) {
12029        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12030            throw new SecurityException("killPids only available to the system");
12031        }
12032        String reason = (pReason == null) ? "Unknown" : pReason;
12033        // XXX Note: don't acquire main activity lock here, because the window
12034        // manager calls in with its locks held.
12035
12036        boolean killed = false;
12037        synchronized (mPidsSelfLocked) {
12038            int worstType = 0;
12039            for (int i=0; i<pids.length; i++) {
12040                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12041                if (proc != null) {
12042                    int type = proc.setAdj;
12043                    if (type > worstType) {
12044                        worstType = type;
12045                    }
12046                }
12047            }
12048
12049            // If the worst oom_adj is somewhere in the cached proc LRU range,
12050            // then constrain it so we will kill all cached procs.
12051            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12052                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12053                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12054            }
12055
12056            // If this is not a secure call, don't let it kill processes that
12057            // are important.
12058            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12059                worstType = ProcessList.SERVICE_ADJ;
12060            }
12061
12062            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12063            for (int i=0; i<pids.length; i++) {
12064                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12065                if (proc == null) {
12066                    continue;
12067                }
12068                int adj = proc.setAdj;
12069                if (adj >= worstType && !proc.killedByAm) {
12070                    proc.kill(reason, true);
12071                    killed = true;
12072                }
12073            }
12074        }
12075        return killed;
12076    }
12077
12078    @Override
12079    public void killUid(int appId, int userId, String reason) {
12080        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12081        synchronized (this) {
12082            final long identity = Binder.clearCallingIdentity();
12083            try {
12084                killPackageProcessesLocked(null, appId, userId,
12085                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12086                        reason != null ? reason : "kill uid");
12087            } finally {
12088                Binder.restoreCallingIdentity(identity);
12089            }
12090        }
12091    }
12092
12093    @Override
12094    public boolean killProcessesBelowForeground(String reason) {
12095        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12096            throw new SecurityException("killProcessesBelowForeground() only available to system");
12097        }
12098
12099        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12100    }
12101
12102    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12103        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12104            throw new SecurityException("killProcessesBelowAdj() only available to system");
12105        }
12106
12107        boolean killed = false;
12108        synchronized (mPidsSelfLocked) {
12109            final int size = mPidsSelfLocked.size();
12110            for (int i = 0; i < size; i++) {
12111                final int pid = mPidsSelfLocked.keyAt(i);
12112                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12113                if (proc == null) continue;
12114
12115                final int adj = proc.setAdj;
12116                if (adj > belowAdj && !proc.killedByAm) {
12117                    proc.kill(reason, true);
12118                    killed = true;
12119                }
12120            }
12121        }
12122        return killed;
12123    }
12124
12125    @Override
12126    public void hang(final IBinder who, boolean allowRestart) {
12127        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12128                != PackageManager.PERMISSION_GRANTED) {
12129            throw new SecurityException("Requires permission "
12130                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12131        }
12132
12133        final IBinder.DeathRecipient death = new DeathRecipient() {
12134            @Override
12135            public void binderDied() {
12136                synchronized (this) {
12137                    notifyAll();
12138                }
12139            }
12140        };
12141
12142        try {
12143            who.linkToDeath(death, 0);
12144        } catch (RemoteException e) {
12145            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12146            return;
12147        }
12148
12149        synchronized (this) {
12150            Watchdog.getInstance().setAllowRestart(allowRestart);
12151            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12152            synchronized (death) {
12153                while (who.isBinderAlive()) {
12154                    try {
12155                        death.wait();
12156                    } catch (InterruptedException e) {
12157                    }
12158                }
12159            }
12160            Watchdog.getInstance().setAllowRestart(true);
12161        }
12162    }
12163
12164    @Override
12165    public void restart() {
12166        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12167                != PackageManager.PERMISSION_GRANTED) {
12168            throw new SecurityException("Requires permission "
12169                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12170        }
12171
12172        Log.i(TAG, "Sending shutdown broadcast...");
12173
12174        BroadcastReceiver br = new BroadcastReceiver() {
12175            @Override public void onReceive(Context context, Intent intent) {
12176                // Now the broadcast is done, finish up the low-level shutdown.
12177                Log.i(TAG, "Shutting down activity manager...");
12178                shutdown(10000);
12179                Log.i(TAG, "Shutdown complete, restarting!");
12180                Process.killProcess(Process.myPid());
12181                System.exit(10);
12182            }
12183        };
12184
12185        // First send the high-level shut down broadcast.
12186        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12187        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12188        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12189        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12190        mContext.sendOrderedBroadcastAsUser(intent,
12191                UserHandle.ALL, null, br, mHandler, 0, null, null);
12192        */
12193        br.onReceive(mContext, intent);
12194    }
12195
12196    private long getLowRamTimeSinceIdle(long now) {
12197        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12198    }
12199
12200    @Override
12201    public void performIdleMaintenance() {
12202        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12203                != PackageManager.PERMISSION_GRANTED) {
12204            throw new SecurityException("Requires permission "
12205                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12206        }
12207
12208        synchronized (this) {
12209            final long now = SystemClock.uptimeMillis();
12210            final long timeSinceLastIdle = now - mLastIdleTime;
12211            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12212            mLastIdleTime = now;
12213            mLowRamTimeSinceLastIdle = 0;
12214            if (mLowRamStartTime != 0) {
12215                mLowRamStartTime = now;
12216            }
12217
12218            StringBuilder sb = new StringBuilder(128);
12219            sb.append("Idle maintenance over ");
12220            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12221            sb.append(" low RAM for ");
12222            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12223            Slog.i(TAG, sb.toString());
12224
12225            // If at least 1/3 of our time since the last idle period has been spent
12226            // with RAM low, then we want to kill processes.
12227            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12228
12229            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12230                ProcessRecord proc = mLruProcesses.get(i);
12231                if (proc.notCachedSinceIdle) {
12232                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12233                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12234                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12235                        if (doKilling && proc.initialIdlePss != 0
12236                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12237                            sb = new StringBuilder(128);
12238                            sb.append("Kill");
12239                            sb.append(proc.processName);
12240                            sb.append(" in idle maint: pss=");
12241                            sb.append(proc.lastPss);
12242                            sb.append(", swapPss=");
12243                            sb.append(proc.lastSwapPss);
12244                            sb.append(", initialPss=");
12245                            sb.append(proc.initialIdlePss);
12246                            sb.append(", period=");
12247                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12248                            sb.append(", lowRamPeriod=");
12249                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12250                            Slog.wtfQuiet(TAG, sb.toString());
12251                            proc.kill("idle maint (pss " + proc.lastPss
12252                                    + " from " + proc.initialIdlePss + ")", true);
12253                        }
12254                    }
12255                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12256                    proc.notCachedSinceIdle = true;
12257                    proc.initialIdlePss = 0;
12258                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12259                            mTestPssMode, isSleeping(), now);
12260                }
12261            }
12262
12263            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12264            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12265        }
12266    }
12267
12268    private void retrieveSettings() {
12269        final ContentResolver resolver = mContext.getContentResolver();
12270        final boolean freeformWindowManagement =
12271                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12272                        || Settings.Global.getInt(
12273                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12274        final boolean supportsPictureInPicture =
12275                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12276
12277        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12278        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12279        final boolean alwaysFinishActivities =
12280                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12281        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12282        final boolean forceResizable = Settings.Global.getInt(
12283                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12284        // Transfer any global setting for forcing RTL layout, into a System Property
12285        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12286
12287        final Configuration configuration = new Configuration();
12288        Settings.System.getConfiguration(resolver, configuration);
12289        if (forceRtl) {
12290            // This will take care of setting the correct layout direction flags
12291            configuration.setLayoutDirection(configuration.locale);
12292        }
12293
12294        synchronized (this) {
12295            mDebugApp = mOrigDebugApp = debugApp;
12296            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12297            mAlwaysFinishActivities = alwaysFinishActivities;
12298            mForceResizableActivities = forceResizable;
12299            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12300            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12301            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12302            // This happens before any activities are started, so we can
12303            // change mConfiguration in-place.
12304            updateConfigurationLocked(configuration, null, true);
12305            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12306                    "Initial config: " + mConfiguration);
12307
12308            // Load resources only after the current configuration has been set.
12309            final Resources res = mContext.getResources();
12310            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12311            mThumbnailWidth = res.getDimensionPixelSize(
12312                    com.android.internal.R.dimen.thumbnail_width);
12313            mThumbnailHeight = res.getDimensionPixelSize(
12314                    com.android.internal.R.dimen.thumbnail_height);
12315            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12316                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12317            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12318                    com.android.internal.R.string.config_appsNotReportingCrashes));
12319        }
12320    }
12321
12322    public boolean testIsSystemReady() {
12323        // no need to synchronize(this) just to read & return the value
12324        return mSystemReady;
12325    }
12326
12327    private static File getCalledPreBootReceiversFile() {
12328        File dataDir = Environment.getDataDirectory();
12329        File systemDir = new File(dataDir, "system");
12330        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12331        return fname;
12332    }
12333
12334    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12335        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12336        File file = getCalledPreBootReceiversFile();
12337        FileInputStream fis = null;
12338        try {
12339            fis = new FileInputStream(file);
12340            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12341            int fvers = dis.readInt();
12342            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12343                String vers = dis.readUTF();
12344                String codename = dis.readUTF();
12345                String build = dis.readUTF();
12346                if (android.os.Build.VERSION.RELEASE.equals(vers)
12347                        && android.os.Build.VERSION.CODENAME.equals(codename)
12348                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12349                    int num = dis.readInt();
12350                    while (num > 0) {
12351                        num--;
12352                        String pkg = dis.readUTF();
12353                        String cls = dis.readUTF();
12354                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12355                    }
12356                }
12357            }
12358        } catch (FileNotFoundException e) {
12359        } catch (IOException e) {
12360            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12361        } finally {
12362            if (fis != null) {
12363                try {
12364                    fis.close();
12365                } catch (IOException e) {
12366                }
12367            }
12368        }
12369        return lastDoneReceivers;
12370    }
12371
12372    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12373        File file = getCalledPreBootReceiversFile();
12374        FileOutputStream fos = null;
12375        DataOutputStream dos = null;
12376        try {
12377            fos = new FileOutputStream(file);
12378            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12379            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12380            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12381            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12382            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12383            dos.writeInt(list.size());
12384            for (int i=0; i<list.size(); i++) {
12385                dos.writeUTF(list.get(i).getPackageName());
12386                dos.writeUTF(list.get(i).getClassName());
12387            }
12388        } catch (IOException e) {
12389            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12390            file.delete();
12391        } finally {
12392            FileUtils.sync(fos);
12393            if (dos != null) {
12394                try {
12395                    dos.close();
12396                } catch (IOException e) {
12397                    // TODO Auto-generated catch block
12398                    e.printStackTrace();
12399                }
12400            }
12401        }
12402    }
12403
12404    final class PreBootContinuation extends IIntentReceiver.Stub {
12405        final Intent intent;
12406        final Runnable onFinishCallback;
12407        final ArrayList<ComponentName> doneReceivers;
12408        final List<ResolveInfo> ris;
12409        final int[] users;
12410        int lastRi = -1;
12411        int curRi = 0;
12412        int curUser = 0;
12413
12414        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12415                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12416            intent = _intent;
12417            onFinishCallback = _onFinishCallback;
12418            doneReceivers = _doneReceivers;
12419            ris = _ris;
12420            users = _users;
12421        }
12422
12423        void go() {
12424            if (lastRi != curRi) {
12425                ActivityInfo ai = ris.get(curRi).activityInfo;
12426                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12427                intent.setComponent(comp);
12428                doneReceivers.add(comp);
12429                lastRi = curRi;
12430                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12431                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12432            }
12433            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12434                    + " for user " + users[curUser]);
12435            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12436            broadcastIntentLocked(null, null, intent, null, this,
12437                    0, null, null, null, AppOpsManager.OP_NONE,
12438                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12439        }
12440
12441        public void performReceive(Intent intent, int resultCode,
12442                String data, Bundle extras, boolean ordered,
12443                boolean sticky, int sendingUser) {
12444            curUser++;
12445            if (curUser >= users.length) {
12446                curUser = 0;
12447                curRi++;
12448                if (curRi >= ris.size()) {
12449                    // All done sending broadcasts!
12450                    if (onFinishCallback != null) {
12451                        // The raw IIntentReceiver interface is called
12452                        // with the AM lock held, so redispatch to
12453                        // execute our code without the lock.
12454                        mHandler.post(onFinishCallback);
12455                    }
12456                    return;
12457                }
12458            }
12459            go();
12460        }
12461    }
12462
12463    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12464            ArrayList<ComponentName> doneReceivers) {
12465        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12466        List<ResolveInfo> ris = null;
12467        try {
12468            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12469                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12470        } catch (RemoteException e) {
12471        }
12472        if (ris == null) {
12473            return false;
12474        }
12475        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12476
12477        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12478        for (int i=0; i<ris.size(); i++) {
12479            ActivityInfo ai = ris.get(i).activityInfo;
12480            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12481            if (lastDoneReceivers.contains(comp)) {
12482                // We already did the pre boot receiver for this app with the current
12483                // platform version, so don't do it again...
12484                ris.remove(i);
12485                i--;
12486                // ...however, do keep it as one that has been done, so we don't
12487                // forget about it when rewriting the file of last done receivers.
12488                doneReceivers.add(comp);
12489            }
12490        }
12491
12492        if (ris.size() <= 0) {
12493            return false;
12494        }
12495
12496        // TODO: can we still do this with per user encryption?
12497        final int[] users = mUserController.getUsers();
12498        if (users.length <= 0) {
12499            return false;
12500        }
12501
12502        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12503                ris, users);
12504        cont.go();
12505        return true;
12506    }
12507
12508    public void systemReady(final Runnable goingCallback) {
12509        synchronized(this) {
12510            if (mSystemReady) {
12511                // If we're done calling all the receivers, run the next "boot phase" passed in
12512                // by the SystemServer
12513                if (goingCallback != null) {
12514                    goingCallback.run();
12515                }
12516                return;
12517            }
12518
12519            mLocalDeviceIdleController
12520                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12521
12522            // Make sure we have the current profile info, since it is needed for security checks.
12523            mUserController.onSystemReady();
12524
12525            mRecentTasks.onSystemReady();
12526            // Check to see if there are any update receivers to run.
12527            if (!mDidUpdate) {
12528                if (mWaitingUpdate) {
12529                    return;
12530                }
12531                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12532                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12533                    public void run() {
12534                        synchronized (ActivityManagerService.this) {
12535                            mDidUpdate = true;
12536                        }
12537                        showBootMessage(mContext.getText(
12538                                R.string.android_upgrading_complete),
12539                                false);
12540                        writeLastDonePreBootReceivers(doneReceivers);
12541                        systemReady(goingCallback);
12542                    }
12543                }, doneReceivers);
12544
12545                if (mWaitingUpdate) {
12546                    return;
12547                }
12548                mDidUpdate = true;
12549            }
12550
12551            mAppOpsService.systemReady();
12552            mSystemReady = true;
12553        }
12554
12555        ArrayList<ProcessRecord> procsToKill = null;
12556        synchronized(mPidsSelfLocked) {
12557            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12558                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12559                if (!isAllowedWhileBooting(proc.info)){
12560                    if (procsToKill == null) {
12561                        procsToKill = new ArrayList<ProcessRecord>();
12562                    }
12563                    procsToKill.add(proc);
12564                }
12565            }
12566        }
12567
12568        synchronized(this) {
12569            if (procsToKill != null) {
12570                for (int i=procsToKill.size()-1; i>=0; i--) {
12571                    ProcessRecord proc = procsToKill.get(i);
12572                    Slog.i(TAG, "Removing system update proc: " + proc);
12573                    removeProcessLocked(proc, true, false, "system update done");
12574                }
12575            }
12576
12577            // Now that we have cleaned up any update processes, we
12578            // are ready to start launching real processes and know that
12579            // we won't trample on them any more.
12580            mProcessesReady = true;
12581        }
12582
12583        Slog.i(TAG, "System now ready");
12584        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12585            SystemClock.uptimeMillis());
12586
12587        synchronized(this) {
12588            // Make sure we have no pre-ready processes sitting around.
12589
12590            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12591                ResolveInfo ri = mContext.getPackageManager()
12592                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12593                                STOCK_PM_FLAGS);
12594                CharSequence errorMsg = null;
12595                if (ri != null) {
12596                    ActivityInfo ai = ri.activityInfo;
12597                    ApplicationInfo app = ai.applicationInfo;
12598                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12599                        mTopAction = Intent.ACTION_FACTORY_TEST;
12600                        mTopData = null;
12601                        mTopComponent = new ComponentName(app.packageName,
12602                                ai.name);
12603                    } else {
12604                        errorMsg = mContext.getResources().getText(
12605                                com.android.internal.R.string.factorytest_not_system);
12606                    }
12607                } else {
12608                    errorMsg = mContext.getResources().getText(
12609                            com.android.internal.R.string.factorytest_no_action);
12610                }
12611                if (errorMsg != null) {
12612                    mTopAction = null;
12613                    mTopData = null;
12614                    mTopComponent = null;
12615                    Message msg = Message.obtain();
12616                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12617                    msg.getData().putCharSequence("msg", errorMsg);
12618                    mUiHandler.sendMessage(msg);
12619                }
12620            }
12621        }
12622
12623        retrieveSettings();
12624        final int currentUserId;
12625        synchronized (this) {
12626            currentUserId = mUserController.getCurrentUserIdLocked();
12627            readGrantedUriPermissionsLocked();
12628        }
12629
12630        if (goingCallback != null) goingCallback.run();
12631
12632        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12633                Integer.toString(currentUserId), currentUserId);
12634        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12635                Integer.toString(currentUserId), currentUserId);
12636        mSystemServiceManager.startUser(currentUserId);
12637
12638        synchronized (this) {
12639            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12640                try {
12641                    List apps = AppGlobals.getPackageManager().
12642                        getPersistentApplications(STOCK_PM_FLAGS);
12643                    if (apps != null) {
12644                        int N = apps.size();
12645                        int i;
12646                        for (i=0; i<N; i++) {
12647                            ApplicationInfo info
12648                                = (ApplicationInfo)apps.get(i);
12649                            if (info != null &&
12650                                    !info.packageName.equals("android")) {
12651                                addAppLocked(info, false, null /* ABI override */);
12652                            }
12653                        }
12654                    }
12655                } catch (RemoteException ex) {
12656                    // pm is in same process, this will never happen.
12657                }
12658            }
12659
12660            // Start up initial activity.
12661            mBooting = true;
12662            // Enable home activity for system user, so that the system can always boot
12663            if (UserManager.isSplitSystemUser()) {
12664                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12665                try {
12666                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12667                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12668                            UserHandle.USER_SYSTEM);
12669                } catch (RemoteException e) {
12670                    e.rethrowAsRuntimeException();
12671                }
12672            }
12673            startHomeActivityLocked(currentUserId, "systemReady");
12674
12675            try {
12676                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12677                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12678                            + " data partition or your device will be unstable.");
12679                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12680                }
12681            } catch (RemoteException e) {
12682            }
12683
12684            if (!Build.isBuildConsistent()) {
12685                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12686                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12687            }
12688
12689            long ident = Binder.clearCallingIdentity();
12690            try {
12691                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12693                        | Intent.FLAG_RECEIVER_FOREGROUND);
12694                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12695                broadcastIntentLocked(null, null, intent,
12696                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12697                        null, false, false, MY_PID, Process.SYSTEM_UID,
12698                        currentUserId);
12699                intent = new Intent(Intent.ACTION_USER_STARTING);
12700                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12701                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12702                broadcastIntentLocked(null, null, intent,
12703                        null, new IIntentReceiver.Stub() {
12704                            @Override
12705                            public void performReceive(Intent intent, int resultCode, String data,
12706                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12707                                    throws RemoteException {
12708                            }
12709                        }, 0, null, null,
12710                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12711                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12712            } catch (Throwable t) {
12713                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12714            } finally {
12715                Binder.restoreCallingIdentity(ident);
12716            }
12717            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12718            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12719        }
12720    }
12721
12722    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12723        synchronized (this) {
12724            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12725        }
12726    }
12727
12728    void skipCurrentReceiverLocked(ProcessRecord app) {
12729        for (BroadcastQueue queue : mBroadcastQueues) {
12730            queue.skipCurrentReceiverLocked(app);
12731        }
12732    }
12733
12734    /**
12735     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12736     * The application process will exit immediately after this call returns.
12737     * @param app object of the crashing app, null for the system server
12738     * @param crashInfo describing the exception
12739     */
12740    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12741        ProcessRecord r = findAppProcess(app, "Crash");
12742        final String processName = app == null ? "system_server"
12743                : (r == null ? "unknown" : r.processName);
12744
12745        handleApplicationCrashInner("crash", r, processName, crashInfo);
12746    }
12747
12748    /* Native crash reporting uses this inner version because it needs to be somewhat
12749     * decoupled from the AM-managed cleanup lifecycle
12750     */
12751    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12752            ApplicationErrorReport.CrashInfo crashInfo) {
12753        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12754                UserHandle.getUserId(Binder.getCallingUid()), processName,
12755                r == null ? -1 : r.info.flags,
12756                crashInfo.exceptionClassName,
12757                crashInfo.exceptionMessage,
12758                crashInfo.throwFileName,
12759                crashInfo.throwLineNumber);
12760
12761        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12762
12763        mAppErrors.crashApplication(r, crashInfo);
12764    }
12765
12766    public void handleApplicationStrictModeViolation(
12767            IBinder app,
12768            int violationMask,
12769            StrictMode.ViolationInfo info) {
12770        ProcessRecord r = findAppProcess(app, "StrictMode");
12771        if (r == null) {
12772            return;
12773        }
12774
12775        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12776            Integer stackFingerprint = info.hashCode();
12777            boolean logIt = true;
12778            synchronized (mAlreadyLoggedViolatedStacks) {
12779                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12780                    logIt = false;
12781                    // TODO: sub-sample into EventLog for these, with
12782                    // the info.durationMillis?  Then we'd get
12783                    // the relative pain numbers, without logging all
12784                    // the stack traces repeatedly.  We'd want to do
12785                    // likewise in the client code, which also does
12786                    // dup suppression, before the Binder call.
12787                } else {
12788                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12789                        mAlreadyLoggedViolatedStacks.clear();
12790                    }
12791                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12792                }
12793            }
12794            if (logIt) {
12795                logStrictModeViolationToDropBox(r, info);
12796            }
12797        }
12798
12799        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12800            AppErrorResult result = new AppErrorResult();
12801            synchronized (this) {
12802                final long origId = Binder.clearCallingIdentity();
12803
12804                Message msg = Message.obtain();
12805                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12806                HashMap<String, Object> data = new HashMap<String, Object>();
12807                data.put("result", result);
12808                data.put("app", r);
12809                data.put("violationMask", violationMask);
12810                data.put("info", info);
12811                msg.obj = data;
12812                mUiHandler.sendMessage(msg);
12813
12814                Binder.restoreCallingIdentity(origId);
12815            }
12816            int res = result.get();
12817            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12818        }
12819    }
12820
12821    // Depending on the policy in effect, there could be a bunch of
12822    // these in quick succession so we try to batch these together to
12823    // minimize disk writes, number of dropbox entries, and maximize
12824    // compression, by having more fewer, larger records.
12825    private void logStrictModeViolationToDropBox(
12826            ProcessRecord process,
12827            StrictMode.ViolationInfo info) {
12828        if (info == null) {
12829            return;
12830        }
12831        final boolean isSystemApp = process == null ||
12832                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12833                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12834        final String processName = process == null ? "unknown" : process.processName;
12835        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12836        final DropBoxManager dbox = (DropBoxManager)
12837                mContext.getSystemService(Context.DROPBOX_SERVICE);
12838
12839        // Exit early if the dropbox isn't configured to accept this report type.
12840        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12841
12842        boolean bufferWasEmpty;
12843        boolean needsFlush;
12844        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12845        synchronized (sb) {
12846            bufferWasEmpty = sb.length() == 0;
12847            appendDropBoxProcessHeaders(process, processName, sb);
12848            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12849            sb.append("System-App: ").append(isSystemApp).append("\n");
12850            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12851            if (info.violationNumThisLoop != 0) {
12852                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12853            }
12854            if (info.numAnimationsRunning != 0) {
12855                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12856            }
12857            if (info.broadcastIntentAction != null) {
12858                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12859            }
12860            if (info.durationMillis != -1) {
12861                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12862            }
12863            if (info.numInstances != -1) {
12864                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12865            }
12866            if (info.tags != null) {
12867                for (String tag : info.tags) {
12868                    sb.append("Span-Tag: ").append(tag).append("\n");
12869                }
12870            }
12871            sb.append("\n");
12872            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12873                sb.append(info.crashInfo.stackTrace);
12874                sb.append("\n");
12875            }
12876            if (info.message != null) {
12877                sb.append(info.message);
12878                sb.append("\n");
12879            }
12880
12881            // Only buffer up to ~64k.  Various logging bits truncate
12882            // things at 128k.
12883            needsFlush = (sb.length() > 64 * 1024);
12884        }
12885
12886        // Flush immediately if the buffer's grown too large, or this
12887        // is a non-system app.  Non-system apps are isolated with a
12888        // different tag & policy and not batched.
12889        //
12890        // Batching is useful during internal testing with
12891        // StrictMode settings turned up high.  Without batching,
12892        // thousands of separate files could be created on boot.
12893        if (!isSystemApp || needsFlush) {
12894            new Thread("Error dump: " + dropboxTag) {
12895                @Override
12896                public void run() {
12897                    String report;
12898                    synchronized (sb) {
12899                        report = sb.toString();
12900                        sb.delete(0, sb.length());
12901                        sb.trimToSize();
12902                    }
12903                    if (report.length() != 0) {
12904                        dbox.addText(dropboxTag, report);
12905                    }
12906                }
12907            }.start();
12908            return;
12909        }
12910
12911        // System app batching:
12912        if (!bufferWasEmpty) {
12913            // An existing dropbox-writing thread is outstanding, so
12914            // we don't need to start it up.  The existing thread will
12915            // catch the buffer appends we just did.
12916            return;
12917        }
12918
12919        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12920        // (After this point, we shouldn't access AMS internal data structures.)
12921        new Thread("Error dump: " + dropboxTag) {
12922            @Override
12923            public void run() {
12924                // 5 second sleep to let stacks arrive and be batched together
12925                try {
12926                    Thread.sleep(5000);  // 5 seconds
12927                } catch (InterruptedException e) {}
12928
12929                String errorReport;
12930                synchronized (mStrictModeBuffer) {
12931                    errorReport = mStrictModeBuffer.toString();
12932                    if (errorReport.length() == 0) {
12933                        return;
12934                    }
12935                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12936                    mStrictModeBuffer.trimToSize();
12937                }
12938                dbox.addText(dropboxTag, errorReport);
12939            }
12940        }.start();
12941    }
12942
12943    /**
12944     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12945     * @param app object of the crashing app, null for the system server
12946     * @param tag reported by the caller
12947     * @param system whether this wtf is coming from the system
12948     * @param crashInfo describing the context of the error
12949     * @return true if the process should exit immediately (WTF is fatal)
12950     */
12951    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12952            final ApplicationErrorReport.CrashInfo crashInfo) {
12953        final int callingUid = Binder.getCallingUid();
12954        final int callingPid = Binder.getCallingPid();
12955
12956        if (system) {
12957            // If this is coming from the system, we could very well have low-level
12958            // system locks held, so we want to do this all asynchronously.  And we
12959            // never want this to become fatal, so there is that too.
12960            mHandler.post(new Runnable() {
12961                @Override public void run() {
12962                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12963                }
12964            });
12965            return false;
12966        }
12967
12968        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12969                crashInfo);
12970
12971        if (r != null && r.pid != Process.myPid() &&
12972                Settings.Global.getInt(mContext.getContentResolver(),
12973                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12974            mAppErrors.crashApplication(r, crashInfo);
12975            return true;
12976        } else {
12977            return false;
12978        }
12979    }
12980
12981    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12982            final ApplicationErrorReport.CrashInfo crashInfo) {
12983        final ProcessRecord r = findAppProcess(app, "WTF");
12984        final String processName = app == null ? "system_server"
12985                : (r == null ? "unknown" : r.processName);
12986
12987        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12988                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12989
12990        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12991
12992        return r;
12993    }
12994
12995    /**
12996     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12997     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12998     */
12999    private ProcessRecord findAppProcess(IBinder app, String reason) {
13000        if (app == null) {
13001            return null;
13002        }
13003
13004        synchronized (this) {
13005            final int NP = mProcessNames.getMap().size();
13006            for (int ip=0; ip<NP; ip++) {
13007                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13008                final int NA = apps.size();
13009                for (int ia=0; ia<NA; ia++) {
13010                    ProcessRecord p = apps.valueAt(ia);
13011                    if (p.thread != null && p.thread.asBinder() == app) {
13012                        return p;
13013                    }
13014                }
13015            }
13016
13017            Slog.w(TAG, "Can't find mystery application for " + reason
13018                    + " from pid=" + Binder.getCallingPid()
13019                    + " uid=" + Binder.getCallingUid() + ": " + app);
13020            return null;
13021        }
13022    }
13023
13024    /**
13025     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13026     * to append various headers to the dropbox log text.
13027     */
13028    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13029            StringBuilder sb) {
13030        // Watchdog thread ends up invoking this function (with
13031        // a null ProcessRecord) to add the stack file to dropbox.
13032        // Do not acquire a lock on this (am) in such cases, as it
13033        // could cause a potential deadlock, if and when watchdog
13034        // is invoked due to unavailability of lock on am and it
13035        // would prevent watchdog from killing system_server.
13036        if (process == null) {
13037            sb.append("Process: ").append(processName).append("\n");
13038            return;
13039        }
13040        // Note: ProcessRecord 'process' is guarded by the service
13041        // instance.  (notably process.pkgList, which could otherwise change
13042        // concurrently during execution of this method)
13043        synchronized (this) {
13044            sb.append("Process: ").append(processName).append("\n");
13045            int flags = process.info.flags;
13046            IPackageManager pm = AppGlobals.getPackageManager();
13047            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13048            for (int ip=0; ip<process.pkgList.size(); ip++) {
13049                String pkg = process.pkgList.keyAt(ip);
13050                sb.append("Package: ").append(pkg);
13051                try {
13052                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13053                    if (pi != null) {
13054                        sb.append(" v").append(pi.versionCode);
13055                        if (pi.versionName != null) {
13056                            sb.append(" (").append(pi.versionName).append(")");
13057                        }
13058                    }
13059                } catch (RemoteException e) {
13060                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13061                }
13062                sb.append("\n");
13063            }
13064        }
13065    }
13066
13067    private static String processClass(ProcessRecord process) {
13068        if (process == null || process.pid == MY_PID) {
13069            return "system_server";
13070        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13071            return "system_app";
13072        } else {
13073            return "data_app";
13074        }
13075    }
13076
13077    /**
13078     * Write a description of an error (crash, WTF, ANR) to the drop box.
13079     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13080     * @param process which caused the error, null means the system server
13081     * @param activity which triggered the error, null if unknown
13082     * @param parent activity related to the error, null if unknown
13083     * @param subject line related to the error, null if absent
13084     * @param report in long form describing the error, null if absent
13085     * @param logFile to include in the report, null if none
13086     * @param crashInfo giving an application stack trace, null if absent
13087     */
13088    public void addErrorToDropBox(String eventType,
13089            ProcessRecord process, String processName, ActivityRecord activity,
13090            ActivityRecord parent, String subject,
13091            final String report, final File logFile,
13092            final ApplicationErrorReport.CrashInfo crashInfo) {
13093        // NOTE -- this must never acquire the ActivityManagerService lock,
13094        // otherwise the watchdog may be prevented from resetting the system.
13095
13096        final String dropboxTag = processClass(process) + "_" + eventType;
13097        final DropBoxManager dbox = (DropBoxManager)
13098                mContext.getSystemService(Context.DROPBOX_SERVICE);
13099
13100        // Exit early if the dropbox isn't configured to accept this report type.
13101        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13102
13103        final StringBuilder sb = new StringBuilder(1024);
13104        appendDropBoxProcessHeaders(process, processName, sb);
13105        if (process != null) {
13106            sb.append("Foreground: ")
13107                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13108                    .append("\n");
13109        }
13110        if (activity != null) {
13111            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13112        }
13113        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13114            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13115        }
13116        if (parent != null && parent != activity) {
13117            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13118        }
13119        if (subject != null) {
13120            sb.append("Subject: ").append(subject).append("\n");
13121        }
13122        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13123        if (Debug.isDebuggerConnected()) {
13124            sb.append("Debugger: Connected\n");
13125        }
13126        sb.append("\n");
13127
13128        // Do the rest in a worker thread to avoid blocking the caller on I/O
13129        // (After this point, we shouldn't access AMS internal data structures.)
13130        Thread worker = new Thread("Error dump: " + dropboxTag) {
13131            @Override
13132            public void run() {
13133                if (report != null) {
13134                    sb.append(report);
13135                }
13136                if (logFile != null) {
13137                    try {
13138                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13139                                    "\n\n[[TRUNCATED]]"));
13140                    } catch (IOException e) {
13141                        Slog.e(TAG, "Error reading " + logFile, e);
13142                    }
13143                }
13144                if (crashInfo != null && crashInfo.stackTrace != null) {
13145                    sb.append(crashInfo.stackTrace);
13146                }
13147
13148                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13149                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13150                if (lines > 0) {
13151                    sb.append("\n");
13152
13153                    // Merge several logcat streams, and take the last N lines
13154                    InputStreamReader input = null;
13155                    try {
13156                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13157                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13158                                "-b", "crash",
13159                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13160
13161                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13162                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13163                        input = new InputStreamReader(logcat.getInputStream());
13164
13165                        int num;
13166                        char[] buf = new char[8192];
13167                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13168                    } catch (IOException e) {
13169                        Slog.e(TAG, "Error running logcat", e);
13170                    } finally {
13171                        if (input != null) try { input.close(); } catch (IOException e) {}
13172                    }
13173                }
13174
13175                dbox.addText(dropboxTag, sb.toString());
13176            }
13177        };
13178
13179        if (process == null) {
13180            // If process is null, we are being called from some internal code
13181            // and may be about to die -- run this synchronously.
13182            worker.run();
13183        } else {
13184            worker.start();
13185        }
13186    }
13187
13188    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13189        enforceNotIsolatedCaller("getProcessesInErrorState");
13190        // assume our apps are happy - lazy create the list
13191        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13192
13193        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13194                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13195        int userId = UserHandle.getUserId(Binder.getCallingUid());
13196
13197        synchronized (this) {
13198
13199            // iterate across all processes
13200            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13201                ProcessRecord app = mLruProcesses.get(i);
13202                if (!allUsers && app.userId != userId) {
13203                    continue;
13204                }
13205                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13206                    // This one's in trouble, so we'll generate a report for it
13207                    // crashes are higher priority (in case there's a crash *and* an anr)
13208                    ActivityManager.ProcessErrorStateInfo report = null;
13209                    if (app.crashing) {
13210                        report = app.crashingReport;
13211                    } else if (app.notResponding) {
13212                        report = app.notRespondingReport;
13213                    }
13214
13215                    if (report != null) {
13216                        if (errList == null) {
13217                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13218                        }
13219                        errList.add(report);
13220                    } else {
13221                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13222                                " crashing = " + app.crashing +
13223                                " notResponding = " + app.notResponding);
13224                    }
13225                }
13226            }
13227        }
13228
13229        return errList;
13230    }
13231
13232    static int procStateToImportance(int procState, int memAdj,
13233            ActivityManager.RunningAppProcessInfo currApp) {
13234        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13235        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13236            currApp.lru = memAdj;
13237        } else {
13238            currApp.lru = 0;
13239        }
13240        return imp;
13241    }
13242
13243    private void fillInProcMemInfo(ProcessRecord app,
13244            ActivityManager.RunningAppProcessInfo outInfo) {
13245        outInfo.pid = app.pid;
13246        outInfo.uid = app.info.uid;
13247        if (mHeavyWeightProcess == app) {
13248            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13249        }
13250        if (app.persistent) {
13251            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13252        }
13253        if (app.activities.size() > 0) {
13254            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13255        }
13256        outInfo.lastTrimLevel = app.trimMemoryLevel;
13257        int adj = app.curAdj;
13258        int procState = app.curProcState;
13259        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13260        outInfo.importanceReasonCode = app.adjTypeCode;
13261        outInfo.processState = app.curProcState;
13262    }
13263
13264    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13265        enforceNotIsolatedCaller("getRunningAppProcesses");
13266
13267        final int callingUid = Binder.getCallingUid();
13268
13269        // Lazy instantiation of list
13270        List<ActivityManager.RunningAppProcessInfo> runList = null;
13271        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13272                callingUid) == PackageManager.PERMISSION_GRANTED;
13273        final int userId = UserHandle.getUserId(callingUid);
13274        final boolean allUids = isGetTasksAllowed(
13275                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13276
13277        synchronized (this) {
13278            // Iterate across all processes
13279            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13280                ProcessRecord app = mLruProcesses.get(i);
13281                if ((!allUsers && app.userId != userId)
13282                        || (!allUids && app.uid != callingUid)) {
13283                    continue;
13284                }
13285                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13286                    // Generate process state info for running application
13287                    ActivityManager.RunningAppProcessInfo currApp =
13288                        new ActivityManager.RunningAppProcessInfo(app.processName,
13289                                app.pid, app.getPackageList());
13290                    fillInProcMemInfo(app, currApp);
13291                    if (app.adjSource instanceof ProcessRecord) {
13292                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13293                        currApp.importanceReasonImportance =
13294                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13295                                        app.adjSourceProcState);
13296                    } else if (app.adjSource instanceof ActivityRecord) {
13297                        ActivityRecord r = (ActivityRecord)app.adjSource;
13298                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13299                    }
13300                    if (app.adjTarget instanceof ComponentName) {
13301                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13302                    }
13303                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13304                    //        + " lru=" + currApp.lru);
13305                    if (runList == null) {
13306                        runList = new ArrayList<>();
13307                    }
13308                    runList.add(currApp);
13309                }
13310            }
13311        }
13312        return runList;
13313    }
13314
13315    public List<ApplicationInfo> getRunningExternalApplications() {
13316        enforceNotIsolatedCaller("getRunningExternalApplications");
13317        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13318        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13319        if (runningApps != null && runningApps.size() > 0) {
13320            Set<String> extList = new HashSet<String>();
13321            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13322                if (app.pkgList != null) {
13323                    for (String pkg : app.pkgList) {
13324                        extList.add(pkg);
13325                    }
13326                }
13327            }
13328            IPackageManager pm = AppGlobals.getPackageManager();
13329            for (String pkg : extList) {
13330                try {
13331                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13332                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13333                        retList.add(info);
13334                    }
13335                } catch (RemoteException e) {
13336                }
13337            }
13338        }
13339        return retList;
13340    }
13341
13342    @Override
13343    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13344        enforceNotIsolatedCaller("getMyMemoryState");
13345        synchronized (this) {
13346            ProcessRecord proc;
13347            synchronized (mPidsSelfLocked) {
13348                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13349            }
13350            fillInProcMemInfo(proc, outInfo);
13351        }
13352    }
13353
13354    @Override
13355    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13356            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13357        (new ActivityManagerShellCommand(this, false)).exec(
13358                this, in, out, err, args, resultReceiver);
13359    }
13360
13361    @Override
13362    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13363        if (checkCallingPermission(android.Manifest.permission.DUMP)
13364                != PackageManager.PERMISSION_GRANTED) {
13365            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13366                    + Binder.getCallingPid()
13367                    + ", uid=" + Binder.getCallingUid()
13368                    + " without permission "
13369                    + android.Manifest.permission.DUMP);
13370            return;
13371        }
13372
13373        boolean dumpAll = false;
13374        boolean dumpClient = false;
13375        String dumpPackage = null;
13376
13377        int opti = 0;
13378        while (opti < args.length) {
13379            String opt = args[opti];
13380            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13381                break;
13382            }
13383            opti++;
13384            if ("-a".equals(opt)) {
13385                dumpAll = true;
13386            } else if ("-c".equals(opt)) {
13387                dumpClient = true;
13388            } else if ("-p".equals(opt)) {
13389                if (opti < args.length) {
13390                    dumpPackage = args[opti];
13391                    opti++;
13392                } else {
13393                    pw.println("Error: -p option requires package argument");
13394                    return;
13395                }
13396                dumpClient = true;
13397            } else if ("-h".equals(opt)) {
13398                ActivityManagerShellCommand.dumpHelp(pw, true);
13399                return;
13400            } else {
13401                pw.println("Unknown argument: " + opt + "; use -h for help");
13402            }
13403        }
13404
13405        long origId = Binder.clearCallingIdentity();
13406        boolean more = false;
13407        // Is the caller requesting to dump a particular piece of data?
13408        if (opti < args.length) {
13409            String cmd = args[opti];
13410            opti++;
13411            if ("activities".equals(cmd) || "a".equals(cmd)) {
13412                synchronized (this) {
13413                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13414                }
13415            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13416                synchronized (this) {
13417                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13418                }
13419            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13420                String[] newArgs;
13421                String name;
13422                if (opti >= args.length) {
13423                    name = null;
13424                    newArgs = EMPTY_STRING_ARRAY;
13425                } else {
13426                    dumpPackage = args[opti];
13427                    opti++;
13428                    newArgs = new String[args.length - opti];
13429                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13430                            args.length - opti);
13431                }
13432                synchronized (this) {
13433                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13434                }
13435            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13436                String[] newArgs;
13437                String name;
13438                if (opti >= args.length) {
13439                    name = null;
13440                    newArgs = EMPTY_STRING_ARRAY;
13441                } else {
13442                    dumpPackage = args[opti];
13443                    opti++;
13444                    newArgs = new String[args.length - opti];
13445                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13446                            args.length - opti);
13447                }
13448                synchronized (this) {
13449                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13450                }
13451            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13452                String[] newArgs;
13453                String name;
13454                if (opti >= args.length) {
13455                    name = null;
13456                    newArgs = EMPTY_STRING_ARRAY;
13457                } else {
13458                    dumpPackage = args[opti];
13459                    opti++;
13460                    newArgs = new String[args.length - opti];
13461                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13462                            args.length - opti);
13463                }
13464                synchronized (this) {
13465                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13466                }
13467            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13468                synchronized (this) {
13469                    dumpOomLocked(fd, pw, args, opti, true);
13470                }
13471            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13472                synchronized (this) {
13473                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13474                }
13475            } else if ("provider".equals(cmd)) {
13476                String[] newArgs;
13477                String name;
13478                if (opti >= args.length) {
13479                    name = null;
13480                    newArgs = EMPTY_STRING_ARRAY;
13481                } else {
13482                    name = args[opti];
13483                    opti++;
13484                    newArgs = new String[args.length - opti];
13485                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13486                }
13487                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13488                    pw.println("No providers match: " + name);
13489                    pw.println("Use -h for help.");
13490                }
13491            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13492                synchronized (this) {
13493                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13494                }
13495            } else if ("service".equals(cmd)) {
13496                String[] newArgs;
13497                String name;
13498                if (opti >= args.length) {
13499                    name = null;
13500                    newArgs = EMPTY_STRING_ARRAY;
13501                } else {
13502                    name = args[opti];
13503                    opti++;
13504                    newArgs = new String[args.length - opti];
13505                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13506                            args.length - opti);
13507                }
13508                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13509                    pw.println("No services match: " + name);
13510                    pw.println("Use -h for help.");
13511                }
13512            } else if ("package".equals(cmd)) {
13513                String[] newArgs;
13514                if (opti >= args.length) {
13515                    pw.println("package: no package name specified");
13516                    pw.println("Use -h for help.");
13517                } else {
13518                    dumpPackage = args[opti];
13519                    opti++;
13520                    newArgs = new String[args.length - opti];
13521                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13522                            args.length - opti);
13523                    args = newArgs;
13524                    opti = 0;
13525                    more = true;
13526                }
13527            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13528                synchronized (this) {
13529                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13530                }
13531            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13532                synchronized (this) {
13533                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13534                }
13535            } else {
13536                // Dumping a single activity?
13537                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13538                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13539                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13540                    if (res < 0) {
13541                        pw.println("Bad activity command, or no activities match: " + cmd);
13542                        pw.println("Use -h for help.");
13543                    }
13544                }
13545            }
13546            if (!more) {
13547                Binder.restoreCallingIdentity(origId);
13548                return;
13549            }
13550        }
13551
13552        // No piece of data specified, dump everything.
13553        synchronized (this) {
13554            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13555            pw.println();
13556            if (dumpAll) {
13557                pw.println("-------------------------------------------------------------------------------");
13558            }
13559            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13560            pw.println();
13561            if (dumpAll) {
13562                pw.println("-------------------------------------------------------------------------------");
13563            }
13564            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13565            pw.println();
13566            if (dumpAll) {
13567                pw.println("-------------------------------------------------------------------------------");
13568            }
13569            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13570            pw.println();
13571            if (dumpAll) {
13572                pw.println("-------------------------------------------------------------------------------");
13573            }
13574            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13575            pw.println();
13576            if (dumpAll) {
13577                pw.println("-------------------------------------------------------------------------------");
13578            }
13579            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13580            pw.println();
13581            if (dumpAll) {
13582                pw.println("-------------------------------------------------------------------------------");
13583            }
13584            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13585            if (mAssociations.size() > 0) {
13586                pw.println();
13587                if (dumpAll) {
13588                    pw.println("-------------------------------------------------------------------------------");
13589                }
13590                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13591            }
13592            pw.println();
13593            if (dumpAll) {
13594                pw.println("-------------------------------------------------------------------------------");
13595            }
13596            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13597        }
13598        Binder.restoreCallingIdentity(origId);
13599    }
13600
13601    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13602            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13603        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13604
13605        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13606                dumpPackage);
13607        boolean needSep = printedAnything;
13608
13609        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13610                dumpPackage, needSep, "  mFocusedActivity: ");
13611        if (printed) {
13612            printedAnything = true;
13613            needSep = false;
13614        }
13615
13616        if (dumpPackage == null) {
13617            if (needSep) {
13618                pw.println();
13619            }
13620            needSep = true;
13621            printedAnything = true;
13622            mStackSupervisor.dump(pw, "  ");
13623        }
13624
13625        if (!printedAnything) {
13626            pw.println("  (nothing)");
13627        }
13628    }
13629
13630    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13631            int opti, boolean dumpAll, String dumpPackage) {
13632        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13633
13634        boolean printedAnything = false;
13635
13636        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13637            boolean printedHeader = false;
13638
13639            final int N = mRecentTasks.size();
13640            for (int i=0; i<N; i++) {
13641                TaskRecord tr = mRecentTasks.get(i);
13642                if (dumpPackage != null) {
13643                    if (tr.realActivity == null ||
13644                            !dumpPackage.equals(tr.realActivity)) {
13645                        continue;
13646                    }
13647                }
13648                if (!printedHeader) {
13649                    pw.println("  Recent tasks:");
13650                    printedHeader = true;
13651                    printedAnything = true;
13652                }
13653                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13654                        pw.println(tr);
13655                if (dumpAll) {
13656                    mRecentTasks.get(i).dump(pw, "    ");
13657                }
13658            }
13659        }
13660
13661        if (!printedAnything) {
13662            pw.println("  (nothing)");
13663        }
13664    }
13665
13666    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13667            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13668        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13669
13670        int dumpUid = 0;
13671        if (dumpPackage != null) {
13672            IPackageManager pm = AppGlobals.getPackageManager();
13673            try {
13674                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13675            } catch (RemoteException e) {
13676            }
13677        }
13678
13679        boolean printedAnything = false;
13680
13681        final long now = SystemClock.uptimeMillis();
13682
13683        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13684            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13685                    = mAssociations.valueAt(i1);
13686            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13687                SparseArray<ArrayMap<String, Association>> sourceUids
13688                        = targetComponents.valueAt(i2);
13689                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13690                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13691                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13692                        Association ass = sourceProcesses.valueAt(i4);
13693                        if (dumpPackage != null) {
13694                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13695                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13696                                continue;
13697                            }
13698                        }
13699                        printedAnything = true;
13700                        pw.print("  ");
13701                        pw.print(ass.mTargetProcess);
13702                        pw.print("/");
13703                        UserHandle.formatUid(pw, ass.mTargetUid);
13704                        pw.print(" <- ");
13705                        pw.print(ass.mSourceProcess);
13706                        pw.print("/");
13707                        UserHandle.formatUid(pw, ass.mSourceUid);
13708                        pw.println();
13709                        pw.print("    via ");
13710                        pw.print(ass.mTargetComponent.flattenToShortString());
13711                        pw.println();
13712                        pw.print("    ");
13713                        long dur = ass.mTime;
13714                        if (ass.mNesting > 0) {
13715                            dur += now - ass.mStartTime;
13716                        }
13717                        TimeUtils.formatDuration(dur, pw);
13718                        pw.print(" (");
13719                        pw.print(ass.mCount);
13720                        pw.println(" times)");
13721                        if (ass.mNesting > 0) {
13722                            pw.print("    ");
13723                            pw.print(" Currently active: ");
13724                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13725                            pw.println();
13726                        }
13727                    }
13728                }
13729            }
13730
13731        }
13732
13733        if (!printedAnything) {
13734            pw.println("  (nothing)");
13735        }
13736    }
13737
13738    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13739            String header, boolean needSep) {
13740        boolean printed = false;
13741        int whichAppId = -1;
13742        if (dumpPackage != null) {
13743            try {
13744                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13745                        dumpPackage, 0);
13746                whichAppId = UserHandle.getAppId(info.uid);
13747            } catch (NameNotFoundException e) {
13748                e.printStackTrace();
13749            }
13750        }
13751        for (int i=0; i<uids.size(); i++) {
13752            UidRecord uidRec = uids.valueAt(i);
13753            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13754                continue;
13755            }
13756            if (!printed) {
13757                printed = true;
13758                if (needSep) {
13759                    pw.println();
13760                }
13761                pw.print("  ");
13762                pw.println(header);
13763                needSep = true;
13764            }
13765            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13766            pw.print(": "); pw.println(uidRec);
13767        }
13768        return printed;
13769    }
13770
13771    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13772            int opti, boolean dumpAll, String dumpPackage) {
13773        boolean needSep = false;
13774        boolean printedAnything = false;
13775        int numPers = 0;
13776
13777        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13778
13779        if (dumpAll) {
13780            final int NP = mProcessNames.getMap().size();
13781            for (int ip=0; ip<NP; ip++) {
13782                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13783                final int NA = procs.size();
13784                for (int ia=0; ia<NA; ia++) {
13785                    ProcessRecord r = procs.valueAt(ia);
13786                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13787                        continue;
13788                    }
13789                    if (!needSep) {
13790                        pw.println("  All known processes:");
13791                        needSep = true;
13792                        printedAnything = true;
13793                    }
13794                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13795                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13796                        pw.print(" "); pw.println(r);
13797                    r.dump(pw, "    ");
13798                    if (r.persistent) {
13799                        numPers++;
13800                    }
13801                }
13802            }
13803        }
13804
13805        if (mIsolatedProcesses.size() > 0) {
13806            boolean printed = false;
13807            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13808                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13809                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13810                    continue;
13811                }
13812                if (!printed) {
13813                    if (needSep) {
13814                        pw.println();
13815                    }
13816                    pw.println("  Isolated process list (sorted by uid):");
13817                    printedAnything = true;
13818                    printed = true;
13819                    needSep = true;
13820                }
13821                pw.println(String.format("%sIsolated #%2d: %s",
13822                        "    ", i, r.toString()));
13823            }
13824        }
13825
13826        if (mActiveUids.size() > 0) {
13827            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13828                printedAnything = needSep = true;
13829            }
13830        }
13831        if (mValidateUids.size() > 0) {
13832            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13833                printedAnything = needSep = true;
13834            }
13835        }
13836
13837        if (mLruProcesses.size() > 0) {
13838            if (needSep) {
13839                pw.println();
13840            }
13841            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13842                    pw.print(" total, non-act at ");
13843                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13844                    pw.print(", non-svc at ");
13845                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13846                    pw.println("):");
13847            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13848            needSep = true;
13849            printedAnything = true;
13850        }
13851
13852        if (dumpAll || dumpPackage != null) {
13853            synchronized (mPidsSelfLocked) {
13854                boolean printed = false;
13855                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13856                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13857                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13858                        continue;
13859                    }
13860                    if (!printed) {
13861                        if (needSep) pw.println();
13862                        needSep = true;
13863                        pw.println("  PID mappings:");
13864                        printed = true;
13865                        printedAnything = true;
13866                    }
13867                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13868                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13869                }
13870            }
13871        }
13872
13873        if (mForegroundProcesses.size() > 0) {
13874            synchronized (mPidsSelfLocked) {
13875                boolean printed = false;
13876                for (int i=0; i<mForegroundProcesses.size(); i++) {
13877                    ProcessRecord r = mPidsSelfLocked.get(
13878                            mForegroundProcesses.valueAt(i).pid);
13879                    if (dumpPackage != null && (r == null
13880                            || !r.pkgList.containsKey(dumpPackage))) {
13881                        continue;
13882                    }
13883                    if (!printed) {
13884                        if (needSep) pw.println();
13885                        needSep = true;
13886                        pw.println("  Foreground Processes:");
13887                        printed = true;
13888                        printedAnything = true;
13889                    }
13890                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13891                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13892                }
13893            }
13894        }
13895
13896        if (mPersistentStartingProcesses.size() > 0) {
13897            if (needSep) pw.println();
13898            needSep = true;
13899            printedAnything = true;
13900            pw.println("  Persisent processes that are starting:");
13901            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13902                    "Starting Norm", "Restarting PERS", dumpPackage);
13903        }
13904
13905        if (mRemovedProcesses.size() > 0) {
13906            if (needSep) pw.println();
13907            needSep = true;
13908            printedAnything = true;
13909            pw.println("  Processes that are being removed:");
13910            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13911                    "Removed Norm", "Removed PERS", dumpPackage);
13912        }
13913
13914        if (mProcessesOnHold.size() > 0) {
13915            if (needSep) pw.println();
13916            needSep = true;
13917            printedAnything = true;
13918            pw.println("  Processes that are on old until the system is ready:");
13919            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13920                    "OnHold Norm", "OnHold PERS", dumpPackage);
13921        }
13922
13923        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13924
13925        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
13926        if (needSep) {
13927            printedAnything = true;
13928        }
13929
13930        if (dumpPackage == null) {
13931            pw.println();
13932            needSep = false;
13933            mUserController.dump(pw, dumpAll);
13934        }
13935        if (mHomeProcess != null && (dumpPackage == null
13936                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13937            if (needSep) {
13938                pw.println();
13939                needSep = false;
13940            }
13941            pw.println("  mHomeProcess: " + mHomeProcess);
13942        }
13943        if (mPreviousProcess != null && (dumpPackage == null
13944                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13945            if (needSep) {
13946                pw.println();
13947                needSep = false;
13948            }
13949            pw.println("  mPreviousProcess: " + mPreviousProcess);
13950        }
13951        if (dumpAll) {
13952            StringBuilder sb = new StringBuilder(128);
13953            sb.append("  mPreviousProcessVisibleTime: ");
13954            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13955            pw.println(sb);
13956        }
13957        if (mHeavyWeightProcess != null && (dumpPackage == null
13958                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13959            if (needSep) {
13960                pw.println();
13961                needSep = false;
13962            }
13963            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13964        }
13965        if (dumpPackage == null) {
13966            pw.println("  mConfiguration: " + mConfiguration);
13967        }
13968        if (dumpAll) {
13969            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13970            if (mCompatModePackages.getPackages().size() > 0) {
13971                boolean printed = false;
13972                for (Map.Entry<String, Integer> entry
13973                        : mCompatModePackages.getPackages().entrySet()) {
13974                    String pkg = entry.getKey();
13975                    int mode = entry.getValue();
13976                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13977                        continue;
13978                    }
13979                    if (!printed) {
13980                        pw.println("  mScreenCompatPackages:");
13981                        printed = true;
13982                    }
13983                    pw.print("    "); pw.print(pkg); pw.print(": ");
13984                            pw.print(mode); pw.println();
13985                }
13986            }
13987        }
13988        if (dumpPackage == null) {
13989            pw.println("  mWakefulness="
13990                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13991            pw.println("  mSleepTokens=" + mSleepTokens);
13992            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13993                    + lockScreenShownToString());
13994            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13995            if (mRunningVoice != null) {
13996                pw.println("  mRunningVoice=" + mRunningVoice);
13997                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13998            }
13999        }
14000        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14001                || mOrigWaitForDebugger) {
14002            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14003                    || dumpPackage.equals(mOrigDebugApp)) {
14004                if (needSep) {
14005                    pw.println();
14006                    needSep = false;
14007                }
14008                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14009                        + " mDebugTransient=" + mDebugTransient
14010                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14011            }
14012        }
14013        if (mCurAppTimeTracker != null) {
14014            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14015        }
14016        if (mMemWatchProcesses.getMap().size() > 0) {
14017            pw.println("  Mem watch processes:");
14018            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14019                    = mMemWatchProcesses.getMap();
14020            for (int i=0; i<procs.size(); i++) {
14021                final String proc = procs.keyAt(i);
14022                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14023                for (int j=0; j<uids.size(); j++) {
14024                    if (needSep) {
14025                        pw.println();
14026                        needSep = false;
14027                    }
14028                    StringBuilder sb = new StringBuilder();
14029                    sb.append("    ").append(proc).append('/');
14030                    UserHandle.formatUid(sb, uids.keyAt(j));
14031                    Pair<Long, String> val = uids.valueAt(j);
14032                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14033                    if (val.second != null) {
14034                        sb.append(", report to ").append(val.second);
14035                    }
14036                    pw.println(sb.toString());
14037                }
14038            }
14039            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14040            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14041            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14042                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14043        }
14044        if (mTrackAllocationApp != null) {
14045            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14046                if (needSep) {
14047                    pw.println();
14048                    needSep = false;
14049                }
14050                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14051            }
14052        }
14053        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14054                || mProfileFd != null) {
14055            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14056                if (needSep) {
14057                    pw.println();
14058                    needSep = false;
14059                }
14060                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14061                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14062                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14063                        + mAutoStopProfiler);
14064                pw.println("  mProfileType=" + mProfileType);
14065            }
14066        }
14067        if (mNativeDebuggingApp != null) {
14068            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14069                if (needSep) {
14070                    pw.println();
14071                    needSep = false;
14072                }
14073                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14074            }
14075        }
14076        if (dumpPackage == null) {
14077            if (mAlwaysFinishActivities || mController != null) {
14078                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14079                        + " mController=" + mController);
14080            }
14081            if (dumpAll) {
14082                pw.println("  Total persistent processes: " + numPers);
14083                pw.println("  mProcessesReady=" + mProcessesReady
14084                        + " mSystemReady=" + mSystemReady
14085                        + " mBooted=" + mBooted
14086                        + " mFactoryTest=" + mFactoryTest);
14087                pw.println("  mBooting=" + mBooting
14088                        + " mCallFinishBooting=" + mCallFinishBooting
14089                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14090                pw.print("  mLastPowerCheckRealtime=");
14091                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14092                        pw.println("");
14093                pw.print("  mLastPowerCheckUptime=");
14094                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14095                        pw.println("");
14096                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14097                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14098                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14099                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14100                        + " (" + mLruProcesses.size() + " total)"
14101                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14102                        + " mNumServiceProcs=" + mNumServiceProcs
14103                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14104                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14105                        + " mLastMemoryLevel" + mLastMemoryLevel
14106                        + " mLastNumProcesses" + mLastNumProcesses);
14107                long now = SystemClock.uptimeMillis();
14108                pw.print("  mLastIdleTime=");
14109                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14110                        pw.print(" mLowRamSinceLastIdle=");
14111                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14112                        pw.println();
14113            }
14114        }
14115
14116        if (!printedAnything) {
14117            pw.println("  (nothing)");
14118        }
14119    }
14120
14121    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14122            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14123        if (mProcessesToGc.size() > 0) {
14124            boolean printed = false;
14125            long now = SystemClock.uptimeMillis();
14126            for (int i=0; i<mProcessesToGc.size(); i++) {
14127                ProcessRecord proc = mProcessesToGc.get(i);
14128                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14129                    continue;
14130                }
14131                if (!printed) {
14132                    if (needSep) pw.println();
14133                    needSep = true;
14134                    pw.println("  Processes that are waiting to GC:");
14135                    printed = true;
14136                }
14137                pw.print("    Process "); pw.println(proc);
14138                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14139                        pw.print(", last gced=");
14140                        pw.print(now-proc.lastRequestedGc);
14141                        pw.print(" ms ago, last lowMem=");
14142                        pw.print(now-proc.lastLowMemory);
14143                        pw.println(" ms ago");
14144
14145            }
14146        }
14147        return needSep;
14148    }
14149
14150    void printOomLevel(PrintWriter pw, String name, int adj) {
14151        pw.print("    ");
14152        if (adj >= 0) {
14153            pw.print(' ');
14154            if (adj < 10) pw.print(' ');
14155        } else {
14156            if (adj > -10) pw.print(' ');
14157        }
14158        pw.print(adj);
14159        pw.print(": ");
14160        pw.print(name);
14161        pw.print(" (");
14162        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14163        pw.println(")");
14164    }
14165
14166    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14167            int opti, boolean dumpAll) {
14168        boolean needSep = false;
14169
14170        if (mLruProcesses.size() > 0) {
14171            if (needSep) pw.println();
14172            needSep = true;
14173            pw.println("  OOM levels:");
14174            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14175            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14176            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14177            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14178            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14179            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14180            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14181            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14182            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14183            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14184            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14185            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14186            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14187            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14188
14189            if (needSep) pw.println();
14190            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14191                    pw.print(" total, non-act at ");
14192                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14193                    pw.print(", non-svc at ");
14194                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14195                    pw.println("):");
14196            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14197            needSep = true;
14198        }
14199
14200        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14201
14202        pw.println();
14203        pw.println("  mHomeProcess: " + mHomeProcess);
14204        pw.println("  mPreviousProcess: " + mPreviousProcess);
14205        if (mHeavyWeightProcess != null) {
14206            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14207        }
14208
14209        return true;
14210    }
14211
14212    /**
14213     * There are three ways to call this:
14214     *  - no provider specified: dump all the providers
14215     *  - a flattened component name that matched an existing provider was specified as the
14216     *    first arg: dump that one provider
14217     *  - the first arg isn't the flattened component name of an existing provider:
14218     *    dump all providers whose component contains the first arg as a substring
14219     */
14220    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14221            int opti, boolean dumpAll) {
14222        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14223    }
14224
14225    static class ItemMatcher {
14226        ArrayList<ComponentName> components;
14227        ArrayList<String> strings;
14228        ArrayList<Integer> objects;
14229        boolean all;
14230
14231        ItemMatcher() {
14232            all = true;
14233        }
14234
14235        void build(String name) {
14236            ComponentName componentName = ComponentName.unflattenFromString(name);
14237            if (componentName != null) {
14238                if (components == null) {
14239                    components = new ArrayList<ComponentName>();
14240                }
14241                components.add(componentName);
14242                all = false;
14243            } else {
14244                int objectId = 0;
14245                // Not a '/' separated full component name; maybe an object ID?
14246                try {
14247                    objectId = Integer.parseInt(name, 16);
14248                    if (objects == null) {
14249                        objects = new ArrayList<Integer>();
14250                    }
14251                    objects.add(objectId);
14252                    all = false;
14253                } catch (RuntimeException e) {
14254                    // Not an integer; just do string match.
14255                    if (strings == null) {
14256                        strings = new ArrayList<String>();
14257                    }
14258                    strings.add(name);
14259                    all = false;
14260                }
14261            }
14262        }
14263
14264        int build(String[] args, int opti) {
14265            for (; opti<args.length; opti++) {
14266                String name = args[opti];
14267                if ("--".equals(name)) {
14268                    return opti+1;
14269                }
14270                build(name);
14271            }
14272            return opti;
14273        }
14274
14275        boolean match(Object object, ComponentName comp) {
14276            if (all) {
14277                return true;
14278            }
14279            if (components != null) {
14280                for (int i=0; i<components.size(); i++) {
14281                    if (components.get(i).equals(comp)) {
14282                        return true;
14283                    }
14284                }
14285            }
14286            if (objects != null) {
14287                for (int i=0; i<objects.size(); i++) {
14288                    if (System.identityHashCode(object) == objects.get(i)) {
14289                        return true;
14290                    }
14291                }
14292            }
14293            if (strings != null) {
14294                String flat = comp.flattenToString();
14295                for (int i=0; i<strings.size(); i++) {
14296                    if (flat.contains(strings.get(i))) {
14297                        return true;
14298                    }
14299                }
14300            }
14301            return false;
14302        }
14303    }
14304
14305    /**
14306     * There are three things that cmd can be:
14307     *  - a flattened component name that matches an existing activity
14308     *  - the cmd arg isn't the flattened component name of an existing activity:
14309     *    dump all activity whose component contains the cmd as a substring
14310     *  - A hex number of the ActivityRecord object instance.
14311     */
14312    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14313            int opti, boolean dumpAll) {
14314        ArrayList<ActivityRecord> activities;
14315
14316        synchronized (this) {
14317            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14318        }
14319
14320        if (activities.size() <= 0) {
14321            return false;
14322        }
14323
14324        String[] newArgs = new String[args.length - opti];
14325        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14326
14327        TaskRecord lastTask = null;
14328        boolean needSep = false;
14329        for (int i=activities.size()-1; i>=0; i--) {
14330            ActivityRecord r = activities.get(i);
14331            if (needSep) {
14332                pw.println();
14333            }
14334            needSep = true;
14335            synchronized (this) {
14336                if (lastTask != r.task) {
14337                    lastTask = r.task;
14338                    pw.print("TASK "); pw.print(lastTask.affinity);
14339                            pw.print(" id="); pw.println(lastTask.taskId);
14340                    if (dumpAll) {
14341                        lastTask.dump(pw, "  ");
14342                    }
14343                }
14344            }
14345            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14346        }
14347        return true;
14348    }
14349
14350    /**
14351     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14352     * there is a thread associated with the activity.
14353     */
14354    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14355            final ActivityRecord r, String[] args, boolean dumpAll) {
14356        String innerPrefix = prefix + "  ";
14357        synchronized (this) {
14358            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14359                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14360                    pw.print(" pid=");
14361                    if (r.app != null) pw.println(r.app.pid);
14362                    else pw.println("(not running)");
14363            if (dumpAll) {
14364                r.dump(pw, innerPrefix);
14365            }
14366        }
14367        if (r.app != null && r.app.thread != null) {
14368            // flush anything that is already in the PrintWriter since the thread is going
14369            // to write to the file descriptor directly
14370            pw.flush();
14371            try {
14372                TransferPipe tp = new TransferPipe();
14373                try {
14374                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14375                            r.appToken, innerPrefix, args);
14376                    tp.go(fd);
14377                } finally {
14378                    tp.kill();
14379                }
14380            } catch (IOException e) {
14381                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14382            } catch (RemoteException e) {
14383                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14384            }
14385        }
14386    }
14387
14388    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14389            int opti, boolean dumpAll, String dumpPackage) {
14390        boolean needSep = false;
14391        boolean onlyHistory = false;
14392        boolean printedAnything = false;
14393
14394        if ("history".equals(dumpPackage)) {
14395            if (opti < args.length && "-s".equals(args[opti])) {
14396                dumpAll = false;
14397            }
14398            onlyHistory = true;
14399            dumpPackage = null;
14400        }
14401
14402        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14403        if (!onlyHistory && dumpAll) {
14404            if (mRegisteredReceivers.size() > 0) {
14405                boolean printed = false;
14406                Iterator it = mRegisteredReceivers.values().iterator();
14407                while (it.hasNext()) {
14408                    ReceiverList r = (ReceiverList)it.next();
14409                    if (dumpPackage != null && (r.app == null ||
14410                            !dumpPackage.equals(r.app.info.packageName))) {
14411                        continue;
14412                    }
14413                    if (!printed) {
14414                        pw.println("  Registered Receivers:");
14415                        needSep = true;
14416                        printed = true;
14417                        printedAnything = true;
14418                    }
14419                    pw.print("  * "); pw.println(r);
14420                    r.dump(pw, "    ");
14421                }
14422            }
14423
14424            if (mReceiverResolver.dump(pw, needSep ?
14425                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14426                    "    ", dumpPackage, false, false)) {
14427                needSep = true;
14428                printedAnything = true;
14429            }
14430        }
14431
14432        for (BroadcastQueue q : mBroadcastQueues) {
14433            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14434            printedAnything |= needSep;
14435        }
14436
14437        needSep = true;
14438
14439        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14440            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14441                if (needSep) {
14442                    pw.println();
14443                }
14444                needSep = true;
14445                printedAnything = true;
14446                pw.print("  Sticky broadcasts for user ");
14447                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14448                StringBuilder sb = new StringBuilder(128);
14449                for (Map.Entry<String, ArrayList<Intent>> ent
14450                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14451                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14452                    if (dumpAll) {
14453                        pw.println(":");
14454                        ArrayList<Intent> intents = ent.getValue();
14455                        final int N = intents.size();
14456                        for (int i=0; i<N; i++) {
14457                            sb.setLength(0);
14458                            sb.append("    Intent: ");
14459                            intents.get(i).toShortString(sb, false, true, false, false);
14460                            pw.println(sb.toString());
14461                            Bundle bundle = intents.get(i).getExtras();
14462                            if (bundle != null) {
14463                                pw.print("      ");
14464                                pw.println(bundle.toString());
14465                            }
14466                        }
14467                    } else {
14468                        pw.println("");
14469                    }
14470                }
14471            }
14472        }
14473
14474        if (!onlyHistory && dumpAll) {
14475            pw.println();
14476            for (BroadcastQueue queue : mBroadcastQueues) {
14477                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14478                        + queue.mBroadcastsScheduled);
14479            }
14480            pw.println("  mHandler:");
14481            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14482            needSep = true;
14483            printedAnything = true;
14484        }
14485
14486        if (!printedAnything) {
14487            pw.println("  (nothing)");
14488        }
14489    }
14490
14491    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14492            int opti, boolean dumpAll, String dumpPackage) {
14493        boolean needSep;
14494        boolean printedAnything = false;
14495
14496        ItemMatcher matcher = new ItemMatcher();
14497        matcher.build(args, opti);
14498
14499        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14500
14501        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14502        printedAnything |= needSep;
14503
14504        if (mLaunchingProviders.size() > 0) {
14505            boolean printed = false;
14506            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14507                ContentProviderRecord r = mLaunchingProviders.get(i);
14508                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14509                    continue;
14510                }
14511                if (!printed) {
14512                    if (needSep) pw.println();
14513                    needSep = true;
14514                    pw.println("  Launching content providers:");
14515                    printed = true;
14516                    printedAnything = true;
14517                }
14518                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14519                        pw.println(r);
14520            }
14521        }
14522
14523        if (!printedAnything) {
14524            pw.println("  (nothing)");
14525        }
14526    }
14527
14528    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14529            int opti, boolean dumpAll, String dumpPackage) {
14530        boolean needSep = false;
14531        boolean printedAnything = false;
14532
14533        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14534
14535        if (mGrantedUriPermissions.size() > 0) {
14536            boolean printed = false;
14537            int dumpUid = -2;
14538            if (dumpPackage != null) {
14539                try {
14540                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14541                            MATCH_UNINSTALLED_PACKAGES, 0);
14542                } catch (NameNotFoundException e) {
14543                    dumpUid = -1;
14544                }
14545            }
14546            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14547                int uid = mGrantedUriPermissions.keyAt(i);
14548                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14549                    continue;
14550                }
14551                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14552                if (!printed) {
14553                    if (needSep) pw.println();
14554                    needSep = true;
14555                    pw.println("  Granted Uri Permissions:");
14556                    printed = true;
14557                    printedAnything = true;
14558                }
14559                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14560                for (UriPermission perm : perms.values()) {
14561                    pw.print("    "); pw.println(perm);
14562                    if (dumpAll) {
14563                        perm.dump(pw, "      ");
14564                    }
14565                }
14566            }
14567        }
14568
14569        if (!printedAnything) {
14570            pw.println("  (nothing)");
14571        }
14572    }
14573
14574    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14575            int opti, boolean dumpAll, String dumpPackage) {
14576        boolean printed = false;
14577
14578        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14579
14580        if (mIntentSenderRecords.size() > 0) {
14581            Iterator<WeakReference<PendingIntentRecord>> it
14582                    = mIntentSenderRecords.values().iterator();
14583            while (it.hasNext()) {
14584                WeakReference<PendingIntentRecord> ref = it.next();
14585                PendingIntentRecord rec = ref != null ? ref.get(): null;
14586                if (dumpPackage != null && (rec == null
14587                        || !dumpPackage.equals(rec.key.packageName))) {
14588                    continue;
14589                }
14590                printed = true;
14591                if (rec != null) {
14592                    pw.print("  * "); pw.println(rec);
14593                    if (dumpAll) {
14594                        rec.dump(pw, "    ");
14595                    }
14596                } else {
14597                    pw.print("  * "); pw.println(ref);
14598                }
14599            }
14600        }
14601
14602        if (!printed) {
14603            pw.println("  (nothing)");
14604        }
14605    }
14606
14607    private static final int dumpProcessList(PrintWriter pw,
14608            ActivityManagerService service, List list,
14609            String prefix, String normalLabel, String persistentLabel,
14610            String dumpPackage) {
14611        int numPers = 0;
14612        final int N = list.size()-1;
14613        for (int i=N; i>=0; i--) {
14614            ProcessRecord r = (ProcessRecord)list.get(i);
14615            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14616                continue;
14617            }
14618            pw.println(String.format("%s%s #%2d: %s",
14619                    prefix, (r.persistent ? persistentLabel : normalLabel),
14620                    i, r.toString()));
14621            if (r.persistent) {
14622                numPers++;
14623            }
14624        }
14625        return numPers;
14626    }
14627
14628    private static final boolean dumpProcessOomList(PrintWriter pw,
14629            ActivityManagerService service, List<ProcessRecord> origList,
14630            String prefix, String normalLabel, String persistentLabel,
14631            boolean inclDetails, String dumpPackage) {
14632
14633        ArrayList<Pair<ProcessRecord, Integer>> list
14634                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14635        for (int i=0; i<origList.size(); i++) {
14636            ProcessRecord r = origList.get(i);
14637            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14638                continue;
14639            }
14640            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14641        }
14642
14643        if (list.size() <= 0) {
14644            return false;
14645        }
14646
14647        Comparator<Pair<ProcessRecord, Integer>> comparator
14648                = new Comparator<Pair<ProcessRecord, Integer>>() {
14649            @Override
14650            public int compare(Pair<ProcessRecord, Integer> object1,
14651                    Pair<ProcessRecord, Integer> object2) {
14652                if (object1.first.setAdj != object2.first.setAdj) {
14653                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14654                }
14655                if (object1.first.setProcState != object2.first.setProcState) {
14656                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14657                }
14658                if (object1.second.intValue() != object2.second.intValue()) {
14659                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14660                }
14661                return 0;
14662            }
14663        };
14664
14665        Collections.sort(list, comparator);
14666
14667        final long curRealtime = SystemClock.elapsedRealtime();
14668        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14669        final long curUptime = SystemClock.uptimeMillis();
14670        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14671
14672        for (int i=list.size()-1; i>=0; i--) {
14673            ProcessRecord r = list.get(i).first;
14674            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14675            char schedGroup;
14676            switch (r.setSchedGroup) {
14677                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14678                    schedGroup = 'B';
14679                    break;
14680                case Process.THREAD_GROUP_DEFAULT:
14681                    schedGroup = 'F';
14682                    break;
14683                case Process.THREAD_GROUP_TOP_APP:
14684                    schedGroup = 'T';
14685                    break;
14686                default:
14687                    schedGroup = '?';
14688                    break;
14689            }
14690            char foreground;
14691            if (r.foregroundActivities) {
14692                foreground = 'A';
14693            } else if (r.foregroundServices) {
14694                foreground = 'S';
14695            } else {
14696                foreground = ' ';
14697            }
14698            String procState = ProcessList.makeProcStateString(r.curProcState);
14699            pw.print(prefix);
14700            pw.print(r.persistent ? persistentLabel : normalLabel);
14701            pw.print(" #");
14702            int num = (origList.size()-1)-list.get(i).second;
14703            if (num < 10) pw.print(' ');
14704            pw.print(num);
14705            pw.print(": ");
14706            pw.print(oomAdj);
14707            pw.print(' ');
14708            pw.print(schedGroup);
14709            pw.print('/');
14710            pw.print(foreground);
14711            pw.print('/');
14712            pw.print(procState);
14713            pw.print(" trm:");
14714            if (r.trimMemoryLevel < 10) pw.print(' ');
14715            pw.print(r.trimMemoryLevel);
14716            pw.print(' ');
14717            pw.print(r.toShortString());
14718            pw.print(" (");
14719            pw.print(r.adjType);
14720            pw.println(')');
14721            if (r.adjSource != null || r.adjTarget != null) {
14722                pw.print(prefix);
14723                pw.print("    ");
14724                if (r.adjTarget instanceof ComponentName) {
14725                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14726                } else if (r.adjTarget != null) {
14727                    pw.print(r.adjTarget.toString());
14728                } else {
14729                    pw.print("{null}");
14730                }
14731                pw.print("<=");
14732                if (r.adjSource instanceof ProcessRecord) {
14733                    pw.print("Proc{");
14734                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14735                    pw.println("}");
14736                } else if (r.adjSource != null) {
14737                    pw.println(r.adjSource.toString());
14738                } else {
14739                    pw.println("{null}");
14740                }
14741            }
14742            if (inclDetails) {
14743                pw.print(prefix);
14744                pw.print("    ");
14745                pw.print("oom: max="); pw.print(r.maxAdj);
14746                pw.print(" curRaw="); pw.print(r.curRawAdj);
14747                pw.print(" setRaw="); pw.print(r.setRawAdj);
14748                pw.print(" cur="); pw.print(r.curAdj);
14749                pw.print(" set="); pw.println(r.setAdj);
14750                pw.print(prefix);
14751                pw.print("    ");
14752                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14753                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14754                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14755                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14756                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14757                pw.println();
14758                pw.print(prefix);
14759                pw.print("    ");
14760                pw.print("cached="); pw.print(r.cached);
14761                pw.print(" empty="); pw.print(r.empty);
14762                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14763
14764                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14765                    if (r.lastWakeTime != 0) {
14766                        long wtime;
14767                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14768                        synchronized (stats) {
14769                            wtime = stats.getProcessWakeTime(r.info.uid,
14770                                    r.pid, curRealtime);
14771                        }
14772                        long timeUsed = wtime - r.lastWakeTime;
14773                        pw.print(prefix);
14774                        pw.print("    ");
14775                        pw.print("keep awake over ");
14776                        TimeUtils.formatDuration(realtimeSince, pw);
14777                        pw.print(" used ");
14778                        TimeUtils.formatDuration(timeUsed, pw);
14779                        pw.print(" (");
14780                        pw.print((timeUsed*100)/realtimeSince);
14781                        pw.println("%)");
14782                    }
14783                    if (r.lastCpuTime != 0) {
14784                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14785                        pw.print(prefix);
14786                        pw.print("    ");
14787                        pw.print("run cpu over ");
14788                        TimeUtils.formatDuration(uptimeSince, pw);
14789                        pw.print(" used ");
14790                        TimeUtils.formatDuration(timeUsed, pw);
14791                        pw.print(" (");
14792                        pw.print((timeUsed*100)/uptimeSince);
14793                        pw.println("%)");
14794                    }
14795                }
14796            }
14797        }
14798        return true;
14799    }
14800
14801    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14802            String[] args) {
14803        ArrayList<ProcessRecord> procs;
14804        synchronized (this) {
14805            if (args != null && args.length > start
14806                    && args[start].charAt(0) != '-') {
14807                procs = new ArrayList<ProcessRecord>();
14808                int pid = -1;
14809                try {
14810                    pid = Integer.parseInt(args[start]);
14811                } catch (NumberFormatException e) {
14812                }
14813                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14814                    ProcessRecord proc = mLruProcesses.get(i);
14815                    if (proc.pid == pid) {
14816                        procs.add(proc);
14817                    } else if (allPkgs && proc.pkgList != null
14818                            && proc.pkgList.containsKey(args[start])) {
14819                        procs.add(proc);
14820                    } else if (proc.processName.equals(args[start])) {
14821                        procs.add(proc);
14822                    }
14823                }
14824                if (procs.size() <= 0) {
14825                    return null;
14826                }
14827            } else {
14828                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14829            }
14830        }
14831        return procs;
14832    }
14833
14834    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14835            PrintWriter pw, String[] args) {
14836        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14837        if (procs == null) {
14838            pw.println("No process found for: " + args[0]);
14839            return;
14840        }
14841
14842        long uptime = SystemClock.uptimeMillis();
14843        long realtime = SystemClock.elapsedRealtime();
14844        pw.println("Applications Graphics Acceleration Info:");
14845        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14846
14847        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14848            ProcessRecord r = procs.get(i);
14849            if (r.thread != null) {
14850                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14851                pw.flush();
14852                try {
14853                    TransferPipe tp = new TransferPipe();
14854                    try {
14855                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14856                        tp.go(fd);
14857                    } finally {
14858                        tp.kill();
14859                    }
14860                } catch (IOException e) {
14861                    pw.println("Failure while dumping the app: " + r);
14862                    pw.flush();
14863                } catch (RemoteException e) {
14864                    pw.println("Got a RemoteException while dumping the app " + r);
14865                    pw.flush();
14866                }
14867            }
14868        }
14869    }
14870
14871    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14872        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14873        if (procs == null) {
14874            pw.println("No process found for: " + args[0]);
14875            return;
14876        }
14877
14878        pw.println("Applications Database Info:");
14879
14880        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14881            ProcessRecord r = procs.get(i);
14882            if (r.thread != null) {
14883                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14884                pw.flush();
14885                try {
14886                    TransferPipe tp = new TransferPipe();
14887                    try {
14888                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14889                        tp.go(fd);
14890                    } finally {
14891                        tp.kill();
14892                    }
14893                } catch (IOException e) {
14894                    pw.println("Failure while dumping the app: " + r);
14895                    pw.flush();
14896                } catch (RemoteException e) {
14897                    pw.println("Got a RemoteException while dumping the app " + r);
14898                    pw.flush();
14899                }
14900            }
14901        }
14902    }
14903
14904    final static class MemItem {
14905        final boolean isProc;
14906        final String label;
14907        final String shortLabel;
14908        final long pss;
14909        final long swapPss;
14910        final int id;
14911        final boolean hasActivities;
14912        ArrayList<MemItem> subitems;
14913
14914        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
14915                boolean _hasActivities) {
14916            isProc = true;
14917            label = _label;
14918            shortLabel = _shortLabel;
14919            pss = _pss;
14920            swapPss = _swapPss;
14921            id = _id;
14922            hasActivities = _hasActivities;
14923        }
14924
14925        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
14926            isProc = false;
14927            label = _label;
14928            shortLabel = _shortLabel;
14929            pss = _pss;
14930            swapPss = _swapPss;
14931            id = _id;
14932            hasActivities = false;
14933        }
14934    }
14935
14936    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14937            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
14938        if (sort && !isCompact) {
14939            Collections.sort(items, new Comparator<MemItem>() {
14940                @Override
14941                public int compare(MemItem lhs, MemItem rhs) {
14942                    if (lhs.pss < rhs.pss) {
14943                        return 1;
14944                    } else if (lhs.pss > rhs.pss) {
14945                        return -1;
14946                    }
14947                    return 0;
14948                }
14949            });
14950        }
14951
14952        for (int i=0; i<items.size(); i++) {
14953            MemItem mi = items.get(i);
14954            if (!isCompact) {
14955                if (dumpSwapPss) {
14956                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
14957                            mi.label, stringifyKBSize(mi.swapPss));
14958                } else {
14959                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14960                }
14961            } else if (mi.isProc) {
14962                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14963                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
14964                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
14965                pw.println(mi.hasActivities ? ",a" : ",e");
14966            } else {
14967                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14968                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
14969            }
14970            if (mi.subitems != null) {
14971                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
14972                        true, isCompact, dumpSwapPss);
14973            }
14974        }
14975    }
14976
14977    // These are in KB.
14978    static final long[] DUMP_MEM_BUCKETS = new long[] {
14979        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14980        120*1024, 160*1024, 200*1024,
14981        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14982        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14983    };
14984
14985    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14986            boolean stackLike) {
14987        int start = label.lastIndexOf('.');
14988        if (start >= 0) start++;
14989        else start = 0;
14990        int end = label.length();
14991        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14992            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14993                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14994                out.append(bucket);
14995                out.append(stackLike ? "MB." : "MB ");
14996                out.append(label, start, end);
14997                return;
14998            }
14999        }
15000        out.append(memKB/1024);
15001        out.append(stackLike ? "MB." : "MB ");
15002        out.append(label, start, end);
15003    }
15004
15005    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15006            ProcessList.NATIVE_ADJ,
15007            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15008            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15009            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15010            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15011            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15012            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15013    };
15014    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15015            "Native",
15016            "System", "Persistent", "Persistent Service", "Foreground",
15017            "Visible", "Perceptible",
15018            "Heavy Weight", "Backup",
15019            "A Services", "Home",
15020            "Previous", "B Services", "Cached"
15021    };
15022    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15023            "native",
15024            "sys", "pers", "persvc", "fore",
15025            "vis", "percept",
15026            "heavy", "backup",
15027            "servicea", "home",
15028            "prev", "serviceb", "cached"
15029    };
15030
15031    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15032            long realtime, boolean isCheckinRequest, boolean isCompact) {
15033        if (isCompact) {
15034            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15035        }
15036        if (isCheckinRequest || isCompact) {
15037            // short checkin version
15038            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15039        } else {
15040            pw.println("Applications Memory Usage (in Kilobytes):");
15041            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15042        }
15043    }
15044
15045    private static final int KSM_SHARED = 0;
15046    private static final int KSM_SHARING = 1;
15047    private static final int KSM_UNSHARED = 2;
15048    private static final int KSM_VOLATILE = 3;
15049
15050    private final long[] getKsmInfo() {
15051        long[] longOut = new long[4];
15052        final int[] SINGLE_LONG_FORMAT = new int[] {
15053            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15054        };
15055        long[] longTmp = new long[1];
15056        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15057                SINGLE_LONG_FORMAT, null, longTmp, null);
15058        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15059        longTmp[0] = 0;
15060        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15061                SINGLE_LONG_FORMAT, null, longTmp, null);
15062        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15063        longTmp[0] = 0;
15064        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15065                SINGLE_LONG_FORMAT, null, longTmp, null);
15066        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15067        longTmp[0] = 0;
15068        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15069                SINGLE_LONG_FORMAT, null, longTmp, null);
15070        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15071        return longOut;
15072    }
15073
15074    private static String stringifySize(long size, int order) {
15075        Locale locale = Locale.US;
15076        switch (order) {
15077            case 1:
15078                return String.format(locale, "%,13d", size);
15079            case 1024:
15080                return String.format(locale, "%,9dK", size / 1024);
15081            case 1024 * 1024:
15082                return String.format(locale, "%,5dM", size / 1024 / 1024);
15083            case 1024 * 1024 * 1024:
15084                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15085            default:
15086                throw new IllegalArgumentException("Invalid size order");
15087        }
15088    }
15089
15090    private static String stringifyKBSize(long size) {
15091        return stringifySize(size * 1024, 1024);
15092    }
15093
15094    // Update this version number in case you change the 'compact' format
15095    private static final int MEMINFO_COMPACT_VERSION = 1;
15096
15097    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15098            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15099        boolean dumpDetails = false;
15100        boolean dumpFullDetails = false;
15101        boolean dumpDalvik = false;
15102        boolean dumpSummaryOnly = false;
15103        boolean oomOnly = false;
15104        boolean isCompact = false;
15105        boolean localOnly = false;
15106        boolean packages = false;
15107        boolean isCheckinRequest = false;
15108        boolean dumpSwapPss = false;
15109
15110        int opti = 0;
15111        while (opti < args.length) {
15112            String opt = args[opti];
15113            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15114                break;
15115            }
15116            opti++;
15117            if ("-a".equals(opt)) {
15118                dumpDetails = true;
15119                dumpFullDetails = true;
15120                dumpDalvik = true;
15121                dumpSwapPss = true;
15122            } else if ("-d".equals(opt)) {
15123                dumpDalvik = true;
15124            } else if ("-c".equals(opt)) {
15125                isCompact = true;
15126            } else if ("-s".equals(opt)) {
15127                dumpDetails = true;
15128                dumpSummaryOnly = true;
15129            } else if ("-S".equals(opt)) {
15130                dumpSwapPss = true;
15131            } else if ("--oom".equals(opt)) {
15132                oomOnly = true;
15133            } else if ("--local".equals(opt)) {
15134                localOnly = true;
15135            } else if ("--package".equals(opt)) {
15136                packages = true;
15137            } else if ("--checkin".equals(opt)) {
15138                isCheckinRequest = true;
15139
15140            } else if ("-h".equals(opt)) {
15141                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15142                pw.println("  -a: include all available information for each process.");
15143                pw.println("  -d: include dalvik details.");
15144                pw.println("  -c: dump in a compact machine-parseable representation.");
15145                pw.println("  -s: dump only summary of application memory usage.");
15146                pw.println("  -S: dump also SwapPss.");
15147                pw.println("  --oom: only show processes organized by oom adj.");
15148                pw.println("  --local: only collect details locally, don't call process.");
15149                pw.println("  --package: interpret process arg as package, dumping all");
15150                pw.println("             processes that have loaded that package.");
15151                pw.println("  --checkin: dump data for a checkin");
15152                pw.println("If [process] is specified it can be the name or ");
15153                pw.println("pid of a specific process to dump.");
15154                return;
15155            } else {
15156                pw.println("Unknown argument: " + opt + "; use -h for help");
15157            }
15158        }
15159
15160        long uptime = SystemClock.uptimeMillis();
15161        long realtime = SystemClock.elapsedRealtime();
15162        final long[] tmpLong = new long[1];
15163
15164        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15165        if (procs == null) {
15166            // No Java processes.  Maybe they want to print a native process.
15167            if (args != null && args.length > opti
15168                    && args[opti].charAt(0) != '-') {
15169                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15170                        = new ArrayList<ProcessCpuTracker.Stats>();
15171                updateCpuStatsNow();
15172                int findPid = -1;
15173                try {
15174                    findPid = Integer.parseInt(args[opti]);
15175                } catch (NumberFormatException e) {
15176                }
15177                synchronized (mProcessCpuTracker) {
15178                    final int N = mProcessCpuTracker.countStats();
15179                    for (int i=0; i<N; i++) {
15180                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15181                        if (st.pid == findPid || (st.baseName != null
15182                                && st.baseName.equals(args[opti]))) {
15183                            nativeProcs.add(st);
15184                        }
15185                    }
15186                }
15187                if (nativeProcs.size() > 0) {
15188                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15189                            isCompact);
15190                    Debug.MemoryInfo mi = null;
15191                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15192                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15193                        final int pid = r.pid;
15194                        if (!isCheckinRequest && dumpDetails) {
15195                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15196                        }
15197                        if (mi == null) {
15198                            mi = new Debug.MemoryInfo();
15199                        }
15200                        if (dumpDetails || (!brief && !oomOnly)) {
15201                            Debug.getMemoryInfo(pid, mi);
15202                        } else {
15203                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15204                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15205                        }
15206                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15207                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15208                        if (isCheckinRequest) {
15209                            pw.println();
15210                        }
15211                    }
15212                    return;
15213                }
15214            }
15215            pw.println("No process found for: " + args[opti]);
15216            return;
15217        }
15218
15219        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15220            dumpDetails = true;
15221        }
15222
15223        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15224
15225        String[] innerArgs = new String[args.length-opti];
15226        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15227
15228        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15229        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15230        long nativePss = 0;
15231        long nativeSwapPss = 0;
15232        long dalvikPss = 0;
15233        long dalvikSwapPss = 0;
15234        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15235                EmptyArray.LONG;
15236        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15237                EmptyArray.LONG;
15238        long otherPss = 0;
15239        long otherSwapPss = 0;
15240        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15241        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15242
15243        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15244        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15245        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15246                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15247
15248        long totalPss = 0;
15249        long totalSwapPss = 0;
15250        long cachedPss = 0;
15251        long cachedSwapPss = 0;
15252        boolean hasSwapPss = false;
15253
15254        Debug.MemoryInfo mi = null;
15255        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15256            final ProcessRecord r = procs.get(i);
15257            final IApplicationThread thread;
15258            final int pid;
15259            final int oomAdj;
15260            final boolean hasActivities;
15261            synchronized (this) {
15262                thread = r.thread;
15263                pid = r.pid;
15264                oomAdj = r.getSetAdjWithServices();
15265                hasActivities = r.activities.size() > 0;
15266            }
15267            if (thread != null) {
15268                if (!isCheckinRequest && dumpDetails) {
15269                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15270                }
15271                if (mi == null) {
15272                    mi = new Debug.MemoryInfo();
15273                }
15274                if (dumpDetails || (!brief && !oomOnly)) {
15275                    Debug.getMemoryInfo(pid, mi);
15276                    hasSwapPss = mi.hasSwappedOutPss;
15277                } else {
15278                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15279                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15280                }
15281                if (dumpDetails) {
15282                    if (localOnly) {
15283                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15284                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15285                        if (isCheckinRequest) {
15286                            pw.println();
15287                        }
15288                    } else {
15289                        try {
15290                            pw.flush();
15291                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15292                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15293                        } catch (RemoteException e) {
15294                            if (!isCheckinRequest) {
15295                                pw.println("Got RemoteException!");
15296                                pw.flush();
15297                            }
15298                        }
15299                    }
15300                }
15301
15302                final long myTotalPss = mi.getTotalPss();
15303                final long myTotalUss = mi.getTotalUss();
15304                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15305
15306                synchronized (this) {
15307                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15308                        // Record this for posterity if the process has been stable.
15309                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15310                    }
15311                }
15312
15313                if (!isCheckinRequest && mi != null) {
15314                    totalPss += myTotalPss;
15315                    totalSwapPss += myTotalSwapPss;
15316                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15317                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15318                            myTotalSwapPss, pid, hasActivities);
15319                    procMems.add(pssItem);
15320                    procMemsMap.put(pid, pssItem);
15321
15322                    nativePss += mi.nativePss;
15323                    nativeSwapPss += mi.nativeSwappedOutPss;
15324                    dalvikPss += mi.dalvikPss;
15325                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15326                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15327                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15328                        dalvikSubitemSwapPss[j] +=
15329                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15330                    }
15331                    otherPss += mi.otherPss;
15332                    otherSwapPss += mi.otherSwappedOutPss;
15333                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15334                        long mem = mi.getOtherPss(j);
15335                        miscPss[j] += mem;
15336                        otherPss -= mem;
15337                        mem = mi.getOtherSwappedOutPss(j);
15338                        miscSwapPss[j] += mem;
15339                        otherSwapPss -= mem;
15340                    }
15341
15342                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15343                        cachedPss += myTotalPss;
15344                        cachedSwapPss += myTotalSwapPss;
15345                    }
15346
15347                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15348                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15349                                || oomIndex == (oomPss.length-1)) {
15350                            oomPss[oomIndex] += myTotalPss;
15351                            oomSwapPss[oomIndex] += myTotalSwapPss;
15352                            if (oomProcs[oomIndex] == null) {
15353                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15354                            }
15355                            oomProcs[oomIndex].add(pssItem);
15356                            break;
15357                        }
15358                    }
15359                }
15360            }
15361        }
15362
15363        long nativeProcTotalPss = 0;
15364
15365        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15366            // If we are showing aggregations, also look for native processes to
15367            // include so that our aggregations are more accurate.
15368            updateCpuStatsNow();
15369            mi = null;
15370            synchronized (mProcessCpuTracker) {
15371                final int N = mProcessCpuTracker.countStats();
15372                for (int i=0; i<N; i++) {
15373                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15374                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15375                        if (mi == null) {
15376                            mi = new Debug.MemoryInfo();
15377                        }
15378                        if (!brief && !oomOnly) {
15379                            Debug.getMemoryInfo(st.pid, mi);
15380                        } else {
15381                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15382                            mi.nativePrivateDirty = (int)tmpLong[0];
15383                        }
15384
15385                        final long myTotalPss = mi.getTotalPss();
15386                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15387                        totalPss += myTotalPss;
15388                        nativeProcTotalPss += myTotalPss;
15389
15390                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15391                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15392                        procMems.add(pssItem);
15393
15394                        nativePss += mi.nativePss;
15395                        nativeSwapPss += mi.nativeSwappedOutPss;
15396                        dalvikPss += mi.dalvikPss;
15397                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15398                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15399                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15400                            dalvikSubitemSwapPss[j] +=
15401                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15402                        }
15403                        otherPss += mi.otherPss;
15404                        otherSwapPss += mi.otherSwappedOutPss;
15405                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15406                            long mem = mi.getOtherPss(j);
15407                            miscPss[j] += mem;
15408                            otherPss -= mem;
15409                            mem = mi.getOtherSwappedOutPss(j);
15410                            miscSwapPss[j] += mem;
15411                            otherSwapPss -= mem;
15412                        }
15413                        oomPss[0] += myTotalPss;
15414                        oomSwapPss[0] += myTotalSwapPss;
15415                        if (oomProcs[0] == null) {
15416                            oomProcs[0] = new ArrayList<MemItem>();
15417                        }
15418                        oomProcs[0].add(pssItem);
15419                    }
15420                }
15421            }
15422
15423            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15424
15425            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15426            final MemItem dalvikItem =
15427                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15428            if (dalvikSubitemPss.length > 0) {
15429                dalvikItem.subitems = new ArrayList<MemItem>();
15430                for (int j=0; j<dalvikSubitemPss.length; j++) {
15431                    final String name = Debug.MemoryInfo.getOtherLabel(
15432                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15433                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15434                                    dalvikSubitemSwapPss[j], j));
15435                }
15436            }
15437            catMems.add(dalvikItem);
15438            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15439            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15440                String label = Debug.MemoryInfo.getOtherLabel(j);
15441                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15442            }
15443
15444            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15445            for (int j=0; j<oomPss.length; j++) {
15446                if (oomPss[j] != 0) {
15447                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15448                            : DUMP_MEM_OOM_LABEL[j];
15449                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15450                            DUMP_MEM_OOM_ADJ[j]);
15451                    item.subitems = oomProcs[j];
15452                    oomMems.add(item);
15453                }
15454            }
15455
15456            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15457            if (!brief && !oomOnly && !isCompact) {
15458                pw.println();
15459                pw.println("Total PSS by process:");
15460                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15461                pw.println();
15462            }
15463            if (!isCompact) {
15464                pw.println("Total PSS by OOM adjustment:");
15465            }
15466            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15467            if (!brief && !oomOnly) {
15468                PrintWriter out = categoryPw != null ? categoryPw : pw;
15469                if (!isCompact) {
15470                    out.println();
15471                    out.println("Total PSS by category:");
15472                }
15473                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15474            }
15475            if (!isCompact) {
15476                pw.println();
15477            }
15478            MemInfoReader memInfo = new MemInfoReader();
15479            memInfo.readMemInfo();
15480            if (nativeProcTotalPss > 0) {
15481                synchronized (this) {
15482                    final long cachedKb = memInfo.getCachedSizeKb();
15483                    final long freeKb = memInfo.getFreeSizeKb();
15484                    final long zramKb = memInfo.getZramTotalSizeKb();
15485                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15486                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15487                            kernelKb*1024, nativeProcTotalPss*1024);
15488                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15489                            nativeProcTotalPss);
15490                }
15491            }
15492            if (!brief) {
15493                if (!isCompact) {
15494                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15495                    pw.print(" (status ");
15496                    switch (mLastMemoryLevel) {
15497                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15498                            pw.println("normal)");
15499                            break;
15500                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15501                            pw.println("moderate)");
15502                            break;
15503                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15504                            pw.println("low)");
15505                            break;
15506                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15507                            pw.println("critical)");
15508                            break;
15509                        default:
15510                            pw.print(mLastMemoryLevel);
15511                            pw.println(")");
15512                            break;
15513                    }
15514                    pw.print(" Free RAM: ");
15515                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15516                            + memInfo.getFreeSizeKb()));
15517                    pw.print(" (");
15518                    pw.print(stringifyKBSize(cachedPss));
15519                    pw.print(" cached pss + ");
15520                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15521                    pw.print(" cached kernel + ");
15522                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15523                    pw.println(" free)");
15524                } else {
15525                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15526                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15527                            + memInfo.getFreeSizeKb()); pw.print(",");
15528                    pw.println(totalPss - cachedPss);
15529                }
15530            }
15531            long lostRAM = memInfo.getTotalSizeKb()
15532                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15533                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15534            if (!isCompact) {
15535                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15536                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15537                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15538                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15539                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15540            } else {
15541                pw.print("lostram,"); pw.println(lostRAM);
15542            }
15543            if (!brief) {
15544                if (memInfo.getZramTotalSizeKb() != 0) {
15545                    if (!isCompact) {
15546                        pw.print("     ZRAM: ");
15547                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15548                                pw.print(" physical used for ");
15549                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15550                                        - memInfo.getSwapFreeSizeKb()));
15551                                pw.print(" in swap (");
15552                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15553                                pw.println(" total swap)");
15554                    } else {
15555                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15556                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15557                                pw.println(memInfo.getSwapFreeSizeKb());
15558                    }
15559                }
15560                final long[] ksm = getKsmInfo();
15561                if (!isCompact) {
15562                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15563                            || ksm[KSM_VOLATILE] != 0) {
15564                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15565                                pw.print(" saved from shared ");
15566                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15567                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15568                                pw.print(" unshared; ");
15569                                pw.print(stringifyKBSize(
15570                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15571                    }
15572                    pw.print("   Tuning: ");
15573                    pw.print(ActivityManager.staticGetMemoryClass());
15574                    pw.print(" (large ");
15575                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15576                    pw.print("), oom ");
15577                    pw.print(stringifySize(
15578                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15579                    pw.print(", restore limit ");
15580                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15581                    if (ActivityManager.isLowRamDeviceStatic()) {
15582                        pw.print(" (low-ram)");
15583                    }
15584                    if (ActivityManager.isHighEndGfx()) {
15585                        pw.print(" (high-end-gfx)");
15586                    }
15587                    pw.println();
15588                } else {
15589                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15590                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15591                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15592                    pw.print("tuning,");
15593                    pw.print(ActivityManager.staticGetMemoryClass());
15594                    pw.print(',');
15595                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15596                    pw.print(',');
15597                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15598                    if (ActivityManager.isLowRamDeviceStatic()) {
15599                        pw.print(",low-ram");
15600                    }
15601                    if (ActivityManager.isHighEndGfx()) {
15602                        pw.print(",high-end-gfx");
15603                    }
15604                    pw.println();
15605                }
15606            }
15607        }
15608    }
15609
15610    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15611            long memtrack, String name) {
15612        sb.append("  ");
15613        sb.append(ProcessList.makeOomAdjString(oomAdj));
15614        sb.append(' ');
15615        sb.append(ProcessList.makeProcStateString(procState));
15616        sb.append(' ');
15617        ProcessList.appendRamKb(sb, pss);
15618        sb.append(": ");
15619        sb.append(name);
15620        if (memtrack > 0) {
15621            sb.append(" (");
15622            sb.append(stringifyKBSize(memtrack));
15623            sb.append(" memtrack)");
15624        }
15625    }
15626
15627    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15628        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15629        sb.append(" (pid ");
15630        sb.append(mi.pid);
15631        sb.append(") ");
15632        sb.append(mi.adjType);
15633        sb.append('\n');
15634        if (mi.adjReason != null) {
15635            sb.append("                      ");
15636            sb.append(mi.adjReason);
15637            sb.append('\n');
15638        }
15639    }
15640
15641    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15642        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15643        for (int i=0, N=memInfos.size(); i<N; i++) {
15644            ProcessMemInfo mi = memInfos.get(i);
15645            infoMap.put(mi.pid, mi);
15646        }
15647        updateCpuStatsNow();
15648        long[] memtrackTmp = new long[1];
15649        synchronized (mProcessCpuTracker) {
15650            final int N = mProcessCpuTracker.countStats();
15651            for (int i=0; i<N; i++) {
15652                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15653                if (st.vsize > 0) {
15654                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15655                    if (pss > 0) {
15656                        if (infoMap.indexOfKey(st.pid) < 0) {
15657                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15658                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15659                            mi.pss = pss;
15660                            mi.memtrack = memtrackTmp[0];
15661                            memInfos.add(mi);
15662                        }
15663                    }
15664                }
15665            }
15666        }
15667
15668        long totalPss = 0;
15669        long totalMemtrack = 0;
15670        for (int i=0, N=memInfos.size(); i<N; i++) {
15671            ProcessMemInfo mi = memInfos.get(i);
15672            if (mi.pss == 0) {
15673                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15674                mi.memtrack = memtrackTmp[0];
15675            }
15676            totalPss += mi.pss;
15677            totalMemtrack += mi.memtrack;
15678        }
15679        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15680            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15681                if (lhs.oomAdj != rhs.oomAdj) {
15682                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15683                }
15684                if (lhs.pss != rhs.pss) {
15685                    return lhs.pss < rhs.pss ? 1 : -1;
15686                }
15687                return 0;
15688            }
15689        });
15690
15691        StringBuilder tag = new StringBuilder(128);
15692        StringBuilder stack = new StringBuilder(128);
15693        tag.append("Low on memory -- ");
15694        appendMemBucket(tag, totalPss, "total", false);
15695        appendMemBucket(stack, totalPss, "total", true);
15696
15697        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15698        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15699        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15700
15701        boolean firstLine = true;
15702        int lastOomAdj = Integer.MIN_VALUE;
15703        long extraNativeRam = 0;
15704        long extraNativeMemtrack = 0;
15705        long cachedPss = 0;
15706        for (int i=0, N=memInfos.size(); i<N; i++) {
15707            ProcessMemInfo mi = memInfos.get(i);
15708
15709            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15710                cachedPss += mi.pss;
15711            }
15712
15713            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15714                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15715                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15716                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15717                if (lastOomAdj != mi.oomAdj) {
15718                    lastOomAdj = mi.oomAdj;
15719                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15720                        tag.append(" / ");
15721                    }
15722                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15723                        if (firstLine) {
15724                            stack.append(":");
15725                            firstLine = false;
15726                        }
15727                        stack.append("\n\t at ");
15728                    } else {
15729                        stack.append("$");
15730                    }
15731                } else {
15732                    tag.append(" ");
15733                    stack.append("$");
15734                }
15735                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15736                    appendMemBucket(tag, mi.pss, mi.name, false);
15737                }
15738                appendMemBucket(stack, mi.pss, mi.name, true);
15739                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15740                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15741                    stack.append("(");
15742                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15743                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15744                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15745                            stack.append(":");
15746                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15747                        }
15748                    }
15749                    stack.append(")");
15750                }
15751            }
15752
15753            appendMemInfo(fullNativeBuilder, mi);
15754            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15755                // The short form only has native processes that are >= 512K.
15756                if (mi.pss >= 512) {
15757                    appendMemInfo(shortNativeBuilder, mi);
15758                } else {
15759                    extraNativeRam += mi.pss;
15760                    extraNativeMemtrack += mi.memtrack;
15761                }
15762            } else {
15763                // Short form has all other details, but if we have collected RAM
15764                // from smaller native processes let's dump a summary of that.
15765                if (extraNativeRam > 0) {
15766                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15767                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15768                    shortNativeBuilder.append('\n');
15769                    extraNativeRam = 0;
15770                }
15771                appendMemInfo(fullJavaBuilder, mi);
15772            }
15773        }
15774
15775        fullJavaBuilder.append("           ");
15776        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15777        fullJavaBuilder.append(": TOTAL");
15778        if (totalMemtrack > 0) {
15779            fullJavaBuilder.append(" (");
15780            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15781            fullJavaBuilder.append(" memtrack)");
15782        } else {
15783        }
15784        fullJavaBuilder.append("\n");
15785
15786        MemInfoReader memInfo = new MemInfoReader();
15787        memInfo.readMemInfo();
15788        final long[] infos = memInfo.getRawInfo();
15789
15790        StringBuilder memInfoBuilder = new StringBuilder(1024);
15791        Debug.getMemInfo(infos);
15792        memInfoBuilder.append("  MemInfo: ");
15793        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15794        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15795        memInfoBuilder.append(stringifyKBSize(
15796                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15797        memInfoBuilder.append(stringifyKBSize(
15798                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15799        memInfoBuilder.append(stringifyKBSize(
15800                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15801        memInfoBuilder.append("           ");
15802        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15803        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15804        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15805        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15806        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15807            memInfoBuilder.append("  ZRAM: ");
15808            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15809            memInfoBuilder.append(" RAM, ");
15810            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15811            memInfoBuilder.append(" swap total, ");
15812            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15813            memInfoBuilder.append(" swap free\n");
15814        }
15815        final long[] ksm = getKsmInfo();
15816        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15817                || ksm[KSM_VOLATILE] != 0) {
15818            memInfoBuilder.append("  KSM: ");
15819            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15820            memInfoBuilder.append(" saved from shared ");
15821            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15822            memInfoBuilder.append("\n       ");
15823            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15824            memInfoBuilder.append(" unshared; ");
15825            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15826            memInfoBuilder.append(" volatile\n");
15827        }
15828        memInfoBuilder.append("  Free RAM: ");
15829        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15830                + memInfo.getFreeSizeKb()));
15831        memInfoBuilder.append("\n");
15832        memInfoBuilder.append("  Used RAM: ");
15833        memInfoBuilder.append(stringifyKBSize(
15834                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15835        memInfoBuilder.append("\n");
15836        memInfoBuilder.append("  Lost RAM: ");
15837        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15838                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15839                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15840        memInfoBuilder.append("\n");
15841        Slog.i(TAG, "Low on memory:");
15842        Slog.i(TAG, shortNativeBuilder.toString());
15843        Slog.i(TAG, fullJavaBuilder.toString());
15844        Slog.i(TAG, memInfoBuilder.toString());
15845
15846        StringBuilder dropBuilder = new StringBuilder(1024);
15847        /*
15848        StringWriter oomSw = new StringWriter();
15849        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15850        StringWriter catSw = new StringWriter();
15851        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15852        String[] emptyArgs = new String[] { };
15853        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15854        oomPw.flush();
15855        String oomString = oomSw.toString();
15856        */
15857        dropBuilder.append("Low on memory:");
15858        dropBuilder.append(stack);
15859        dropBuilder.append('\n');
15860        dropBuilder.append(fullNativeBuilder);
15861        dropBuilder.append(fullJavaBuilder);
15862        dropBuilder.append('\n');
15863        dropBuilder.append(memInfoBuilder);
15864        dropBuilder.append('\n');
15865        /*
15866        dropBuilder.append(oomString);
15867        dropBuilder.append('\n');
15868        */
15869        StringWriter catSw = new StringWriter();
15870        synchronized (ActivityManagerService.this) {
15871            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15872            String[] emptyArgs = new String[] { };
15873            catPw.println();
15874            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15875            catPw.println();
15876            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15877                    false, false, null);
15878            catPw.println();
15879            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15880            catPw.flush();
15881        }
15882        dropBuilder.append(catSw.toString());
15883        addErrorToDropBox("lowmem", null, "system_server", null,
15884                null, tag.toString(), dropBuilder.toString(), null, null);
15885        //Slog.i(TAG, "Sent to dropbox:");
15886        //Slog.i(TAG, dropBuilder.toString());
15887        synchronized (ActivityManagerService.this) {
15888            long now = SystemClock.uptimeMillis();
15889            if (mLastMemUsageReportTime < now) {
15890                mLastMemUsageReportTime = now;
15891            }
15892        }
15893    }
15894
15895    /**
15896     * Searches array of arguments for the specified string
15897     * @param args array of argument strings
15898     * @param value value to search for
15899     * @return true if the value is contained in the array
15900     */
15901    private static boolean scanArgs(String[] args, String value) {
15902        if (args != null) {
15903            for (String arg : args) {
15904                if (value.equals(arg)) {
15905                    return true;
15906                }
15907            }
15908        }
15909        return false;
15910    }
15911
15912    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15913            ContentProviderRecord cpr, boolean always) {
15914        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15915
15916        if (!inLaunching || always) {
15917            synchronized (cpr) {
15918                cpr.launchingApp = null;
15919                cpr.notifyAll();
15920            }
15921            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15922            String names[] = cpr.info.authority.split(";");
15923            for (int j = 0; j < names.length; j++) {
15924                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15925            }
15926        }
15927
15928        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15929            ContentProviderConnection conn = cpr.connections.get(i);
15930            if (conn.waiting) {
15931                // If this connection is waiting for the provider, then we don't
15932                // need to mess with its process unless we are always removing
15933                // or for some reason the provider is not currently launching.
15934                if (inLaunching && !always) {
15935                    continue;
15936                }
15937            }
15938            ProcessRecord capp = conn.client;
15939            conn.dead = true;
15940            if (conn.stableCount > 0) {
15941                if (!capp.persistent && capp.thread != null
15942                        && capp.pid != 0
15943                        && capp.pid != MY_PID) {
15944                    capp.kill("depends on provider "
15945                            + cpr.name.flattenToShortString()
15946                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15947                }
15948            } else if (capp.thread != null && conn.provider.provider != null) {
15949                try {
15950                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15951                } catch (RemoteException e) {
15952                }
15953                // In the protocol here, we don't expect the client to correctly
15954                // clean up this connection, we'll just remove it.
15955                cpr.connections.remove(i);
15956                if (conn.client.conProviders.remove(conn)) {
15957                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15958                }
15959            }
15960        }
15961
15962        if (inLaunching && always) {
15963            mLaunchingProviders.remove(cpr);
15964        }
15965        return inLaunching;
15966    }
15967
15968    /**
15969     * Main code for cleaning up a process when it has gone away.  This is
15970     * called both as a result of the process dying, or directly when stopping
15971     * a process when running in single process mode.
15972     *
15973     * @return Returns true if the given process has been restarted, so the
15974     * app that was passed in must remain on the process lists.
15975     */
15976    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15977            boolean restarting, boolean allowRestart, int index) {
15978        if (index >= 0) {
15979            removeLruProcessLocked(app);
15980            ProcessList.remove(app.pid);
15981        }
15982
15983        mProcessesToGc.remove(app);
15984        mPendingPssProcesses.remove(app);
15985
15986        // Dismiss any open dialogs.
15987        if (app.crashDialog != null && !app.forceCrashReport) {
15988            app.crashDialog.dismiss();
15989            app.crashDialog = null;
15990        }
15991        if (app.anrDialog != null) {
15992            app.anrDialog.dismiss();
15993            app.anrDialog = null;
15994        }
15995        if (app.waitDialog != null) {
15996            app.waitDialog.dismiss();
15997            app.waitDialog = null;
15998        }
15999
16000        app.crashing = false;
16001        app.notResponding = false;
16002
16003        app.resetPackageList(mProcessStats);
16004        app.unlinkDeathRecipient();
16005        app.makeInactive(mProcessStats);
16006        app.waitingToKill = null;
16007        app.forcingToForeground = null;
16008        updateProcessForegroundLocked(app, false, false);
16009        app.foregroundActivities = false;
16010        app.hasShownUi = false;
16011        app.treatLikeActivity = false;
16012        app.hasAboveClient = false;
16013        app.hasClientActivities = false;
16014
16015        mServices.killServicesLocked(app, allowRestart);
16016
16017        boolean restart = false;
16018
16019        // Remove published content providers.
16020        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16021            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16022            final boolean always = app.bad || !allowRestart;
16023            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16024            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16025                // We left the provider in the launching list, need to
16026                // restart it.
16027                restart = true;
16028            }
16029
16030            cpr.provider = null;
16031            cpr.proc = null;
16032        }
16033        app.pubProviders.clear();
16034
16035        // Take care of any launching providers waiting for this process.
16036        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16037            restart = true;
16038        }
16039
16040        // Unregister from connected content providers.
16041        if (!app.conProviders.isEmpty()) {
16042            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16043                ContentProviderConnection conn = app.conProviders.get(i);
16044                conn.provider.connections.remove(conn);
16045                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16046                        conn.provider.name);
16047            }
16048            app.conProviders.clear();
16049        }
16050
16051        // At this point there may be remaining entries in mLaunchingProviders
16052        // where we were the only one waiting, so they are no longer of use.
16053        // Look for these and clean up if found.
16054        // XXX Commented out for now.  Trying to figure out a way to reproduce
16055        // the actual situation to identify what is actually going on.
16056        if (false) {
16057            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16058                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16059                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16060                    synchronized (cpr) {
16061                        cpr.launchingApp = null;
16062                        cpr.notifyAll();
16063                    }
16064                }
16065            }
16066        }
16067
16068        skipCurrentReceiverLocked(app);
16069
16070        // Unregister any receivers.
16071        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16072            removeReceiverLocked(app.receivers.valueAt(i));
16073        }
16074        app.receivers.clear();
16075
16076        // If the app is undergoing backup, tell the backup manager about it
16077        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16078            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16079                    + mBackupTarget.appInfo + " died during backup");
16080            try {
16081                IBackupManager bm = IBackupManager.Stub.asInterface(
16082                        ServiceManager.getService(Context.BACKUP_SERVICE));
16083                bm.agentDisconnected(app.info.packageName);
16084            } catch (RemoteException e) {
16085                // can't happen; backup manager is local
16086            }
16087        }
16088
16089        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16090            ProcessChangeItem item = mPendingProcessChanges.get(i);
16091            if (item.pid == app.pid) {
16092                mPendingProcessChanges.remove(i);
16093                mAvailProcessChanges.add(item);
16094            }
16095        }
16096        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16097                null).sendToTarget();
16098
16099        // If the caller is restarting this app, then leave it in its
16100        // current lists and let the caller take care of it.
16101        if (restarting) {
16102            return false;
16103        }
16104
16105        if (!app.persistent || app.isolated) {
16106            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16107                    "Removing non-persistent process during cleanup: " + app);
16108            removeProcessNameLocked(app.processName, app.uid);
16109            if (mHeavyWeightProcess == app) {
16110                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16111                        mHeavyWeightProcess.userId, 0));
16112                mHeavyWeightProcess = null;
16113            }
16114        } else if (!app.removed) {
16115            // This app is persistent, so we need to keep its record around.
16116            // If it is not already on the pending app list, add it there
16117            // and start a new process for it.
16118            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16119                mPersistentStartingProcesses.add(app);
16120                restart = true;
16121            }
16122        }
16123        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16124                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16125        mProcessesOnHold.remove(app);
16126
16127        if (app == mHomeProcess) {
16128            mHomeProcess = null;
16129        }
16130        if (app == mPreviousProcess) {
16131            mPreviousProcess = null;
16132        }
16133
16134        if (restart && !app.isolated) {
16135            // We have components that still need to be running in the
16136            // process, so re-launch it.
16137            if (index < 0) {
16138                ProcessList.remove(app.pid);
16139            }
16140            addProcessNameLocked(app);
16141            startProcessLocked(app, "restart", app.processName);
16142            return true;
16143        } else if (app.pid > 0 && app.pid != MY_PID) {
16144            // Goodbye!
16145            boolean removed;
16146            synchronized (mPidsSelfLocked) {
16147                mPidsSelfLocked.remove(app.pid);
16148                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16149            }
16150            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16151            if (app.isolated) {
16152                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16153            }
16154            app.setPid(0);
16155        }
16156        return false;
16157    }
16158
16159    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16160        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16161            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16162            if (cpr.launchingApp == app) {
16163                return true;
16164            }
16165        }
16166        return false;
16167    }
16168
16169    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16170        // Look through the content providers we are waiting to have launched,
16171        // and if any run in this process then either schedule a restart of
16172        // the process or kill the client waiting for it if this process has
16173        // gone bad.
16174        boolean restart = false;
16175        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16176            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16177            if (cpr.launchingApp == app) {
16178                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16179                    restart = true;
16180                } else {
16181                    removeDyingProviderLocked(app, cpr, true);
16182                }
16183            }
16184        }
16185        return restart;
16186    }
16187
16188    // =========================================================
16189    // SERVICES
16190    // =========================================================
16191
16192    @Override
16193    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16194            int flags) {
16195        enforceNotIsolatedCaller("getServices");
16196        synchronized (this) {
16197            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16198        }
16199    }
16200
16201    @Override
16202    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16203        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16204        synchronized (this) {
16205            return mServices.getRunningServiceControlPanelLocked(name);
16206        }
16207    }
16208
16209    @Override
16210    public ComponentName startService(IApplicationThread caller, Intent service,
16211            String resolvedType, String callingPackage, int userId)
16212            throws TransactionTooLargeException {
16213        enforceNotIsolatedCaller("startService");
16214        // Refuse possible leaked file descriptors
16215        if (service != null && service.hasFileDescriptors() == true) {
16216            throw new IllegalArgumentException("File descriptors passed in Intent");
16217        }
16218
16219        if (callingPackage == null) {
16220            throw new IllegalArgumentException("callingPackage cannot be null");
16221        }
16222
16223        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16224                "startService: " + service + " type=" + resolvedType);
16225        synchronized(this) {
16226            final int callingPid = Binder.getCallingPid();
16227            final int callingUid = Binder.getCallingUid();
16228            final long origId = Binder.clearCallingIdentity();
16229            ComponentName res = mServices.startServiceLocked(caller, service,
16230                    resolvedType, callingPid, callingUid, callingPackage, userId);
16231            Binder.restoreCallingIdentity(origId);
16232            return res;
16233        }
16234    }
16235
16236    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16237            String callingPackage, int userId)
16238            throws TransactionTooLargeException {
16239        synchronized(this) {
16240            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16241                    "startServiceInPackage: " + service + " type=" + resolvedType);
16242            final long origId = Binder.clearCallingIdentity();
16243            ComponentName res = mServices.startServiceLocked(null, service,
16244                    resolvedType, -1, uid, callingPackage, userId);
16245            Binder.restoreCallingIdentity(origId);
16246            return res;
16247        }
16248    }
16249
16250    @Override
16251    public int stopService(IApplicationThread caller, Intent service,
16252            String resolvedType, int userId) {
16253        enforceNotIsolatedCaller("stopService");
16254        // Refuse possible leaked file descriptors
16255        if (service != null && service.hasFileDescriptors() == true) {
16256            throw new IllegalArgumentException("File descriptors passed in Intent");
16257        }
16258
16259        synchronized(this) {
16260            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16261        }
16262    }
16263
16264    @Override
16265    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16266        enforceNotIsolatedCaller("peekService");
16267        // Refuse possible leaked file descriptors
16268        if (service != null && service.hasFileDescriptors() == true) {
16269            throw new IllegalArgumentException("File descriptors passed in Intent");
16270        }
16271
16272        if (callingPackage == null) {
16273            throw new IllegalArgumentException("callingPackage cannot be null");
16274        }
16275
16276        synchronized(this) {
16277            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16278        }
16279    }
16280
16281    @Override
16282    public boolean stopServiceToken(ComponentName className, IBinder token,
16283            int startId) {
16284        synchronized(this) {
16285            return mServices.stopServiceTokenLocked(className, token, startId);
16286        }
16287    }
16288
16289    @Override
16290    public void setServiceForeground(ComponentName className, IBinder token,
16291            int id, Notification notification, boolean removeNotification) {
16292        synchronized(this) {
16293            mServices.setServiceForegroundLocked(className, token, id, notification,
16294                    removeNotification);
16295        }
16296    }
16297
16298    @Override
16299    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16300            boolean requireFull, String name, String callerPackage) {
16301        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16302                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16303    }
16304
16305    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16306            String className, int flags) {
16307        boolean result = false;
16308        // For apps that don't have pre-defined UIDs, check for permission
16309        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16310            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16311                if (ActivityManager.checkUidPermission(
16312                        INTERACT_ACROSS_USERS,
16313                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16314                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16315                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16316                            + " requests FLAG_SINGLE_USER, but app does not hold "
16317                            + INTERACT_ACROSS_USERS;
16318                    Slog.w(TAG, msg);
16319                    throw new SecurityException(msg);
16320                }
16321                // Permission passed
16322                result = true;
16323            }
16324        } else if ("system".equals(componentProcessName)) {
16325            result = true;
16326        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16327            // Phone app and persistent apps are allowed to export singleuser providers.
16328            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16329                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16330        }
16331        if (DEBUG_MU) Slog.v(TAG_MU,
16332                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16333                + Integer.toHexString(flags) + ") = " + result);
16334        return result;
16335    }
16336
16337    /**
16338     * Checks to see if the caller is in the same app as the singleton
16339     * component, or the component is in a special app. It allows special apps
16340     * to export singleton components but prevents exporting singleton
16341     * components for regular apps.
16342     */
16343    boolean isValidSingletonCall(int callingUid, int componentUid) {
16344        int componentAppId = UserHandle.getAppId(componentUid);
16345        return UserHandle.isSameApp(callingUid, componentUid)
16346                || componentAppId == Process.SYSTEM_UID
16347                || componentAppId == Process.PHONE_UID
16348                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16349                        == PackageManager.PERMISSION_GRANTED;
16350    }
16351
16352    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16353            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16354            int userId) throws TransactionTooLargeException {
16355        enforceNotIsolatedCaller("bindService");
16356
16357        // Refuse possible leaked file descriptors
16358        if (service != null && service.hasFileDescriptors() == true) {
16359            throw new IllegalArgumentException("File descriptors passed in Intent");
16360        }
16361
16362        if (callingPackage == null) {
16363            throw new IllegalArgumentException("callingPackage cannot be null");
16364        }
16365
16366        synchronized(this) {
16367            return mServices.bindServiceLocked(caller, token, service,
16368                    resolvedType, connection, flags, callingPackage, userId);
16369        }
16370    }
16371
16372    public boolean unbindService(IServiceConnection connection) {
16373        synchronized (this) {
16374            return mServices.unbindServiceLocked(connection);
16375        }
16376    }
16377
16378    public void publishService(IBinder token, Intent intent, IBinder service) {
16379        // Refuse possible leaked file descriptors
16380        if (intent != null && intent.hasFileDescriptors() == true) {
16381            throw new IllegalArgumentException("File descriptors passed in Intent");
16382        }
16383
16384        synchronized(this) {
16385            if (!(token instanceof ServiceRecord)) {
16386                throw new IllegalArgumentException("Invalid service token");
16387            }
16388            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16389        }
16390    }
16391
16392    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16393        // Refuse possible leaked file descriptors
16394        if (intent != null && intent.hasFileDescriptors() == true) {
16395            throw new IllegalArgumentException("File descriptors passed in Intent");
16396        }
16397
16398        synchronized(this) {
16399            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16400        }
16401    }
16402
16403    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16404        synchronized(this) {
16405            if (!(token instanceof ServiceRecord)) {
16406                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16407                throw new IllegalArgumentException("Invalid service token");
16408            }
16409            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16410        }
16411    }
16412
16413    // =========================================================
16414    // BACKUP AND RESTORE
16415    // =========================================================
16416
16417    // Cause the target app to be launched if necessary and its backup agent
16418    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16419    // activity manager to announce its creation.
16420    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16421        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16422                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16423        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16424
16425        synchronized(this) {
16426            // !!! TODO: currently no check here that we're already bound
16427            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16428            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16429            synchronized (stats) {
16430                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16431            }
16432
16433            // Backup agent is now in use, its package can't be stopped.
16434            try {
16435                AppGlobals.getPackageManager().setPackageStoppedState(
16436                        app.packageName, false, UserHandle.getUserId(app.uid));
16437            } catch (RemoteException e) {
16438            } catch (IllegalArgumentException e) {
16439                Slog.w(TAG, "Failed trying to unstop package "
16440                        + app.packageName + ": " + e);
16441            }
16442
16443            BackupRecord r = new BackupRecord(ss, app, backupMode);
16444            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16445                    ? new ComponentName(app.packageName, app.backupAgentName)
16446                    : new ComponentName("android", "FullBackupAgent");
16447            // startProcessLocked() returns existing proc's record if it's already running
16448            ProcessRecord proc = startProcessLocked(app.processName, app,
16449                    false, 0, "backup", hostingName, false, false, false);
16450            if (proc == null) {
16451                Slog.e(TAG, "Unable to start backup agent process " + r);
16452                return false;
16453            }
16454
16455            r.app = proc;
16456            mBackupTarget = r;
16457            mBackupAppName = app.packageName;
16458
16459            // Try not to kill the process during backup
16460            updateOomAdjLocked(proc);
16461
16462            // If the process is already attached, schedule the creation of the backup agent now.
16463            // If it is not yet live, this will be done when it attaches to the framework.
16464            if (proc.thread != null) {
16465                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16466                try {
16467                    proc.thread.scheduleCreateBackupAgent(app,
16468                            compatibilityInfoForPackageLocked(app), backupMode);
16469                } catch (RemoteException e) {
16470                    // Will time out on the backup manager side
16471                }
16472            } else {
16473                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16474            }
16475            // Invariants: at this point, the target app process exists and the application
16476            // is either already running or in the process of coming up.  mBackupTarget and
16477            // mBackupAppName describe the app, so that when it binds back to the AM we
16478            // know that it's scheduled for a backup-agent operation.
16479        }
16480
16481        return true;
16482    }
16483
16484    @Override
16485    public void clearPendingBackup() {
16486        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16487        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16488
16489        synchronized (this) {
16490            mBackupTarget = null;
16491            mBackupAppName = null;
16492        }
16493    }
16494
16495    // A backup agent has just come up
16496    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16497        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16498                + " = " + agent);
16499
16500        synchronized(this) {
16501            if (!agentPackageName.equals(mBackupAppName)) {
16502                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16503                return;
16504            }
16505        }
16506
16507        long oldIdent = Binder.clearCallingIdentity();
16508        try {
16509            IBackupManager bm = IBackupManager.Stub.asInterface(
16510                    ServiceManager.getService(Context.BACKUP_SERVICE));
16511            bm.agentConnected(agentPackageName, agent);
16512        } catch (RemoteException e) {
16513            // can't happen; the backup manager service is local
16514        } catch (Exception e) {
16515            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16516            e.printStackTrace();
16517        } finally {
16518            Binder.restoreCallingIdentity(oldIdent);
16519        }
16520    }
16521
16522    // done with this agent
16523    public void unbindBackupAgent(ApplicationInfo appInfo) {
16524        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16525        if (appInfo == null) {
16526            Slog.w(TAG, "unbind backup agent for null app");
16527            return;
16528        }
16529
16530        synchronized(this) {
16531            try {
16532                if (mBackupAppName == null) {
16533                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16534                    return;
16535                }
16536
16537                if (!mBackupAppName.equals(appInfo.packageName)) {
16538                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16539                    return;
16540                }
16541
16542                // Not backing this app up any more; reset its OOM adjustment
16543                final ProcessRecord proc = mBackupTarget.app;
16544                updateOomAdjLocked(proc);
16545
16546                // If the app crashed during backup, 'thread' will be null here
16547                if (proc.thread != null) {
16548                    try {
16549                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16550                                compatibilityInfoForPackageLocked(appInfo));
16551                    } catch (Exception e) {
16552                        Slog.e(TAG, "Exception when unbinding backup agent:");
16553                        e.printStackTrace();
16554                    }
16555                }
16556            } finally {
16557                mBackupTarget = null;
16558                mBackupAppName = null;
16559            }
16560        }
16561    }
16562    // =========================================================
16563    // BROADCASTS
16564    // =========================================================
16565
16566    boolean isPendingBroadcastProcessLocked(int pid) {
16567        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16568                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16569    }
16570
16571    void skipPendingBroadcastLocked(int pid) {
16572            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16573            for (BroadcastQueue queue : mBroadcastQueues) {
16574                queue.skipPendingBroadcastLocked(pid);
16575            }
16576    }
16577
16578    // The app just attached; send any pending broadcasts that it should receive
16579    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16580        boolean didSomething = false;
16581        for (BroadcastQueue queue : mBroadcastQueues) {
16582            didSomething |= queue.sendPendingBroadcastsLocked(app);
16583        }
16584        return didSomething;
16585    }
16586
16587    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16588            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16589        enforceNotIsolatedCaller("registerReceiver");
16590        ArrayList<Intent> stickyIntents = null;
16591        ProcessRecord callerApp = null;
16592        int callingUid;
16593        int callingPid;
16594        synchronized(this) {
16595            if (caller != null) {
16596                callerApp = getRecordForAppLocked(caller);
16597                if (callerApp == null) {
16598                    throw new SecurityException(
16599                            "Unable to find app for caller " + caller
16600                            + " (pid=" + Binder.getCallingPid()
16601                            + ") when registering receiver " + receiver);
16602                }
16603                if (callerApp.info.uid != Process.SYSTEM_UID &&
16604                        !callerApp.pkgList.containsKey(callerPackage) &&
16605                        !"android".equals(callerPackage)) {
16606                    throw new SecurityException("Given caller package " + callerPackage
16607                            + " is not running in process " + callerApp);
16608                }
16609                callingUid = callerApp.info.uid;
16610                callingPid = callerApp.pid;
16611            } else {
16612                callerPackage = null;
16613                callingUid = Binder.getCallingUid();
16614                callingPid = Binder.getCallingPid();
16615            }
16616
16617            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16618                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16619
16620            Iterator<String> actions = filter.actionsIterator();
16621            if (actions == null) {
16622                ArrayList<String> noAction = new ArrayList<String>(1);
16623                noAction.add(null);
16624                actions = noAction.iterator();
16625            }
16626
16627            // Collect stickies of users
16628            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16629            while (actions.hasNext()) {
16630                String action = actions.next();
16631                for (int id : userIds) {
16632                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16633                    if (stickies != null) {
16634                        ArrayList<Intent> intents = stickies.get(action);
16635                        if (intents != null) {
16636                            if (stickyIntents == null) {
16637                                stickyIntents = new ArrayList<Intent>();
16638                            }
16639                            stickyIntents.addAll(intents);
16640                        }
16641                    }
16642                }
16643            }
16644        }
16645
16646        ArrayList<Intent> allSticky = null;
16647        if (stickyIntents != null) {
16648            final ContentResolver resolver = mContext.getContentResolver();
16649            // Look for any matching sticky broadcasts...
16650            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16651                Intent intent = stickyIntents.get(i);
16652                // If intent has scheme "content", it will need to acccess
16653                // provider that needs to lock mProviderMap in ActivityThread
16654                // and also it may need to wait application response, so we
16655                // cannot lock ActivityManagerService here.
16656                if (filter.match(resolver, intent, true, TAG) >= 0) {
16657                    if (allSticky == null) {
16658                        allSticky = new ArrayList<Intent>();
16659                    }
16660                    allSticky.add(intent);
16661                }
16662            }
16663        }
16664
16665        // The first sticky in the list is returned directly back to the client.
16666        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16667        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16668        if (receiver == null) {
16669            return sticky;
16670        }
16671
16672        synchronized (this) {
16673            if (callerApp != null && (callerApp.thread == null
16674                    || callerApp.thread.asBinder() != caller.asBinder())) {
16675                // Original caller already died
16676                return null;
16677            }
16678            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16679            if (rl == null) {
16680                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16681                        userId, receiver);
16682                if (rl.app != null) {
16683                    rl.app.receivers.add(rl);
16684                } else {
16685                    try {
16686                        receiver.asBinder().linkToDeath(rl, 0);
16687                    } catch (RemoteException e) {
16688                        return sticky;
16689                    }
16690                    rl.linkedToDeath = true;
16691                }
16692                mRegisteredReceivers.put(receiver.asBinder(), rl);
16693            } else if (rl.uid != callingUid) {
16694                throw new IllegalArgumentException(
16695                        "Receiver requested to register for uid " + callingUid
16696                        + " was previously registered for uid " + rl.uid);
16697            } else if (rl.pid != callingPid) {
16698                throw new IllegalArgumentException(
16699                        "Receiver requested to register for pid " + callingPid
16700                        + " was previously registered for pid " + rl.pid);
16701            } else if (rl.userId != userId) {
16702                throw new IllegalArgumentException(
16703                        "Receiver requested to register for user " + userId
16704                        + " was previously registered for user " + rl.userId);
16705            }
16706            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16707                    permission, callingUid, userId);
16708            rl.add(bf);
16709            if (!bf.debugCheck()) {
16710                Slog.w(TAG, "==> For Dynamic broadcast");
16711            }
16712            mReceiverResolver.addFilter(bf);
16713
16714            // Enqueue broadcasts for all existing stickies that match
16715            // this filter.
16716            if (allSticky != null) {
16717                ArrayList receivers = new ArrayList();
16718                receivers.add(bf);
16719
16720                final int stickyCount = allSticky.size();
16721                for (int i = 0; i < stickyCount; i++) {
16722                    Intent intent = allSticky.get(i);
16723                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16724                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16725                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16726                            null, 0, null, null, false, true, true, -1);
16727                    queue.enqueueParallelBroadcastLocked(r);
16728                    queue.scheduleBroadcastsLocked();
16729                }
16730            }
16731
16732            return sticky;
16733        }
16734    }
16735
16736    public void unregisterReceiver(IIntentReceiver receiver) {
16737        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16738
16739        final long origId = Binder.clearCallingIdentity();
16740        try {
16741            boolean doTrim = false;
16742
16743            synchronized(this) {
16744                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16745                if (rl != null) {
16746                    final BroadcastRecord r = rl.curBroadcast;
16747                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16748                        final boolean doNext = r.queue.finishReceiverLocked(
16749                                r, r.resultCode, r.resultData, r.resultExtras,
16750                                r.resultAbort, false);
16751                        if (doNext) {
16752                            doTrim = true;
16753                            r.queue.processNextBroadcast(false);
16754                        }
16755                    }
16756
16757                    if (rl.app != null) {
16758                        rl.app.receivers.remove(rl);
16759                    }
16760                    removeReceiverLocked(rl);
16761                    if (rl.linkedToDeath) {
16762                        rl.linkedToDeath = false;
16763                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16764                    }
16765                }
16766            }
16767
16768            // If we actually concluded any broadcasts, we might now be able
16769            // to trim the recipients' apps from our working set
16770            if (doTrim) {
16771                trimApplications();
16772                return;
16773            }
16774
16775        } finally {
16776            Binder.restoreCallingIdentity(origId);
16777        }
16778    }
16779
16780    void removeReceiverLocked(ReceiverList rl) {
16781        mRegisteredReceivers.remove(rl.receiver.asBinder());
16782        for (int i = rl.size() - 1; i >= 0; i--) {
16783            mReceiverResolver.removeFilter(rl.get(i));
16784        }
16785    }
16786
16787    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16788        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16789            ProcessRecord r = mLruProcesses.get(i);
16790            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16791                try {
16792                    r.thread.dispatchPackageBroadcast(cmd, packages);
16793                } catch (RemoteException ex) {
16794                }
16795            }
16796        }
16797    }
16798
16799    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16800            int callingUid, int[] users) {
16801        // TODO: come back and remove this assumption to triage all broadcasts
16802        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16803
16804        List<ResolveInfo> receivers = null;
16805        try {
16806            HashSet<ComponentName> singleUserReceivers = null;
16807            boolean scannedFirstReceivers = false;
16808            for (int user : users) {
16809                // Skip users that have Shell restrictions, with exception of always permitted
16810                // Shell broadcasts
16811                if (callingUid == Process.SHELL_UID
16812                        && mUserController.hasUserRestriction(
16813                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16814                        && !isPermittedShellBroadcast(intent)) {
16815                    continue;
16816                }
16817                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16818                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16819                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16820                    // If this is not the system user, we need to check for
16821                    // any receivers that should be filtered out.
16822                    for (int i=0; i<newReceivers.size(); i++) {
16823                        ResolveInfo ri = newReceivers.get(i);
16824                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16825                            newReceivers.remove(i);
16826                            i--;
16827                        }
16828                    }
16829                }
16830                if (newReceivers != null && newReceivers.size() == 0) {
16831                    newReceivers = null;
16832                }
16833                if (receivers == null) {
16834                    receivers = newReceivers;
16835                } else if (newReceivers != null) {
16836                    // We need to concatenate the additional receivers
16837                    // found with what we have do far.  This would be easy,
16838                    // but we also need to de-dup any receivers that are
16839                    // singleUser.
16840                    if (!scannedFirstReceivers) {
16841                        // Collect any single user receivers we had already retrieved.
16842                        scannedFirstReceivers = true;
16843                        for (int i=0; i<receivers.size(); i++) {
16844                            ResolveInfo ri = receivers.get(i);
16845                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16846                                ComponentName cn = new ComponentName(
16847                                        ri.activityInfo.packageName, ri.activityInfo.name);
16848                                if (singleUserReceivers == null) {
16849                                    singleUserReceivers = new HashSet<ComponentName>();
16850                                }
16851                                singleUserReceivers.add(cn);
16852                            }
16853                        }
16854                    }
16855                    // Add the new results to the existing results, tracking
16856                    // and de-dupping single user receivers.
16857                    for (int i=0; i<newReceivers.size(); i++) {
16858                        ResolveInfo ri = newReceivers.get(i);
16859                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16860                            ComponentName cn = new ComponentName(
16861                                    ri.activityInfo.packageName, ri.activityInfo.name);
16862                            if (singleUserReceivers == null) {
16863                                singleUserReceivers = new HashSet<ComponentName>();
16864                            }
16865                            if (!singleUserReceivers.contains(cn)) {
16866                                singleUserReceivers.add(cn);
16867                                receivers.add(ri);
16868                            }
16869                        } else {
16870                            receivers.add(ri);
16871                        }
16872                    }
16873                }
16874            }
16875        } catch (RemoteException ex) {
16876            // pm is in same process, this will never happen.
16877        }
16878        return receivers;
16879    }
16880
16881    private boolean isPermittedShellBroadcast(Intent intent) {
16882        // remote bugreport should always be allowed to be taken
16883        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
16884    }
16885
16886    final int broadcastIntentLocked(ProcessRecord callerApp,
16887            String callerPackage, Intent intent, String resolvedType,
16888            IIntentReceiver resultTo, int resultCode, String resultData,
16889            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16890            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16891        intent = new Intent(intent);
16892
16893        // By default broadcasts do not go to stopped apps.
16894        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16895
16896        // If we have not finished booting, don't allow this to launch new processes.
16897        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16898            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16899        }
16900
16901        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16902                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16903                + " ordered=" + ordered + " userid=" + userId);
16904        if ((resultTo != null) && !ordered) {
16905            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16906        }
16907
16908        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16909                ALLOW_NON_FULL, "broadcast", callerPackage);
16910
16911        // Make sure that the user who is receiving this broadcast is running.
16912        // If not, we will just skip it. Make an exception for shutdown broadcasts
16913        // and upgrade steps.
16914
16915        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16916            if ((callingUid != Process.SYSTEM_UID
16917                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16918                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16919                Slog.w(TAG, "Skipping broadcast of " + intent
16920                        + ": user " + userId + " is stopped");
16921                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16922            }
16923        }
16924
16925        BroadcastOptions brOptions = null;
16926        if (bOptions != null) {
16927            brOptions = new BroadcastOptions(bOptions);
16928            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16929                // See if the caller is allowed to do this.  Note we are checking against
16930                // the actual real caller (not whoever provided the operation as say a
16931                // PendingIntent), because that who is actually supplied the arguments.
16932                if (checkComponentPermission(
16933                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16934                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16935                        != PackageManager.PERMISSION_GRANTED) {
16936                    String msg = "Permission Denial: " + intent.getAction()
16937                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16938                            + ", uid=" + callingUid + ")"
16939                            + " requires "
16940                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16941                    Slog.w(TAG, msg);
16942                    throw new SecurityException(msg);
16943                }
16944            }
16945        }
16946
16947        // Verify that protected broadcasts are only being sent by system code,
16948        // and that system code is only sending protected broadcasts.
16949        final String action = intent.getAction();
16950        final boolean isProtectedBroadcast;
16951        try {
16952            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
16953        } catch (RemoteException e) {
16954            Slog.w(TAG, "Remote exception", e);
16955            return ActivityManager.BROADCAST_SUCCESS;
16956        }
16957
16958        final boolean isCallerSystem;
16959        switch (UserHandle.getAppId(callingUid)) {
16960            case Process.ROOT_UID:
16961            case Process.SYSTEM_UID:
16962            case Process.PHONE_UID:
16963            case Process.BLUETOOTH_UID:
16964            case Process.NFC_UID:
16965                isCallerSystem = true;
16966                break;
16967            default:
16968                isCallerSystem = (callerApp != null) && callerApp.persistent;
16969                break;
16970        }
16971
16972        if (isCallerSystem) {
16973            if (isProtectedBroadcast
16974                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
16975                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
16976                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
16977                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
16978                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
16979                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
16980                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
16981                // Broadcast is either protected, or it's a public action that
16982                // we've relaxed, so it's fine for system internals to send.
16983            } else {
16984                // The vast majority of broadcasts sent from system internals
16985                // should be protected to avoid security holes, so yell loudly
16986                // to ensure we examine these cases.
16987                Log.wtf(TAG, "Sending non-protected broadcast " + action
16988                        + " from system", new Throwable());
16989            }
16990
16991        } else {
16992            if (isProtectedBroadcast) {
16993                String msg = "Permission Denial: not allowed to send broadcast "
16994                        + action + " from pid="
16995                        + callingPid + ", uid=" + callingUid;
16996                Slog.w(TAG, msg);
16997                throw new SecurityException(msg);
16998
16999            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17000                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17001                // Special case for compatibility: we don't want apps to send this,
17002                // but historically it has not been protected and apps may be using it
17003                // to poke their own app widget.  So, instead of making it protected,
17004                // just limit it to the caller.
17005                if (callerApp == null) {
17006                    String msg = "Permission Denial: not allowed to send broadcast "
17007                            + action + " from unknown caller.";
17008                    Slog.w(TAG, msg);
17009                    throw new SecurityException(msg);
17010                } else if (intent.getComponent() != null) {
17011                    // They are good enough to send to an explicit component...  verify
17012                    // it is being sent to the calling app.
17013                    if (!intent.getComponent().getPackageName().equals(
17014                            callerApp.info.packageName)) {
17015                        String msg = "Permission Denial: not allowed to send broadcast "
17016                                + action + " to "
17017                                + intent.getComponent().getPackageName() + " from "
17018                                + callerApp.info.packageName;
17019                        Slog.w(TAG, msg);
17020                        throw new SecurityException(msg);
17021                    }
17022                } else {
17023                    // Limit broadcast to their own package.
17024                    intent.setPackage(callerApp.info.packageName);
17025                }
17026            }
17027        }
17028
17029        if (action != null) {
17030            switch (action) {
17031                case Intent.ACTION_UID_REMOVED:
17032                case Intent.ACTION_PACKAGE_REMOVED:
17033                case Intent.ACTION_PACKAGE_CHANGED:
17034                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17035                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17036                case Intent.ACTION_PACKAGES_SUSPENDED:
17037                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17038                    // Handle special intents: if this broadcast is from the package
17039                    // manager about a package being removed, we need to remove all of
17040                    // its activities from the history stack.
17041                    if (checkComponentPermission(
17042                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17043                            callingPid, callingUid, -1, true)
17044                            != PackageManager.PERMISSION_GRANTED) {
17045                        String msg = "Permission Denial: " + intent.getAction()
17046                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17047                                + ", uid=" + callingUid + ")"
17048                                + " requires "
17049                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17050                        Slog.w(TAG, msg);
17051                        throw new SecurityException(msg);
17052                    }
17053                    switch (action) {
17054                        case Intent.ACTION_UID_REMOVED:
17055                            final Bundle intentExtras = intent.getExtras();
17056                            final int uid = intentExtras != null
17057                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17058                            if (uid >= 0) {
17059                                mBatteryStatsService.removeUid(uid);
17060                                mAppOpsService.uidRemoved(uid);
17061                            }
17062                            break;
17063                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17064                            // If resources are unavailable just force stop all those packages
17065                            // and flush the attribute cache as well.
17066                            String list[] =
17067                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17068                            if (list != null && list.length > 0) {
17069                                for (int i = 0; i < list.length; i++) {
17070                                    forceStopPackageLocked(list[i], -1, false, true, true,
17071                                            false, false, userId, "storage unmount");
17072                                }
17073                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17074                                sendPackageBroadcastLocked(
17075                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17076                                        userId);
17077                            }
17078                            break;
17079                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17080                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17081                            break;
17082                        case Intent.ACTION_PACKAGE_REMOVED:
17083                        case Intent.ACTION_PACKAGE_CHANGED:
17084                            Uri data = intent.getData();
17085                            String ssp;
17086                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17087                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17088                                boolean fullUninstall = removed &&
17089                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17090                                final boolean killProcess =
17091                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17092                                if (killProcess) {
17093                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17094                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17095                                            false, true, true, false, fullUninstall, userId,
17096                                            removed ? "pkg removed" : "pkg changed");
17097                                }
17098                                if (removed) {
17099                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17100                                            new String[] {ssp}, userId);
17101                                    if (fullUninstall) {
17102                                        mAppOpsService.packageRemoved(
17103                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17104
17105                                        // Remove all permissions granted from/to this package
17106                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17107
17108                                        removeTasksByPackageNameLocked(ssp, userId);
17109                                        mBatteryStatsService.notePackageUninstalled(ssp);
17110                                    }
17111                                } else {
17112                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17113                                            intent.getStringArrayExtra(
17114                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17115                                }
17116                            }
17117                            break;
17118                        case Intent.ACTION_PACKAGES_SUSPENDED:
17119                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17120                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17121                                    intent.getAction());
17122                            final String[] packageNames = intent.getStringArrayExtra(
17123                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17124                            final int userHandle = intent.getIntExtra(
17125                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17126
17127                            synchronized(ActivityManagerService.this) {
17128                                mRecentTasks.onPackagesSuspendedChanged(
17129                                        packageNames, suspended, userHandle);
17130                            }
17131                            break;
17132                    }
17133                    break;
17134                case Intent.ACTION_PACKAGE_ADDED:
17135                    // Special case for adding a package: by default turn on compatibility mode.
17136                    Uri data = intent.getData();
17137                    String ssp;
17138                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17139                        final boolean replacing =
17140                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17141                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17142
17143                        try {
17144                            ApplicationInfo ai = AppGlobals.getPackageManager().
17145                                    getApplicationInfo(ssp, 0, 0);
17146                            mBatteryStatsService.notePackageInstalled(ssp,
17147                                    ai != null ? ai.versionCode : 0);
17148                        } catch (RemoteException e) {
17149                        }
17150                    }
17151                    break;
17152                case Intent.ACTION_TIMEZONE_CHANGED:
17153                    // If this is the time zone changed action, queue up a message that will reset
17154                    // the timezone of all currently running processes. This message will get
17155                    // queued up before the broadcast happens.
17156                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17157                    break;
17158                case Intent.ACTION_TIME_CHANGED:
17159                    // If the user set the time, let all running processes know.
17160                    final int is24Hour =
17161                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17162                                    : 0;
17163                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17164                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17165                    synchronized (stats) {
17166                        stats.noteCurrentTimeChangedLocked();
17167                    }
17168                    break;
17169                case Intent.ACTION_CLEAR_DNS_CACHE:
17170                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17171                    break;
17172                case Proxy.PROXY_CHANGE_ACTION:
17173                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17174                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17175                    break;
17176            }
17177        }
17178
17179        // Add to the sticky list if requested.
17180        if (sticky) {
17181            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17182                    callingPid, callingUid)
17183                    != PackageManager.PERMISSION_GRANTED) {
17184                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17185                        + callingPid + ", uid=" + callingUid
17186                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17187                Slog.w(TAG, msg);
17188                throw new SecurityException(msg);
17189            }
17190            if (requiredPermissions != null && requiredPermissions.length > 0) {
17191                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17192                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17193                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17194            }
17195            if (intent.getComponent() != null) {
17196                throw new SecurityException(
17197                        "Sticky broadcasts can't target a specific component");
17198            }
17199            // We use userId directly here, since the "all" target is maintained
17200            // as a separate set of sticky broadcasts.
17201            if (userId != UserHandle.USER_ALL) {
17202                // But first, if this is not a broadcast to all users, then
17203                // make sure it doesn't conflict with an existing broadcast to
17204                // all users.
17205                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17206                        UserHandle.USER_ALL);
17207                if (stickies != null) {
17208                    ArrayList<Intent> list = stickies.get(intent.getAction());
17209                    if (list != null) {
17210                        int N = list.size();
17211                        int i;
17212                        for (i=0; i<N; i++) {
17213                            if (intent.filterEquals(list.get(i))) {
17214                                throw new IllegalArgumentException(
17215                                        "Sticky broadcast " + intent + " for user "
17216                                        + userId + " conflicts with existing global broadcast");
17217                            }
17218                        }
17219                    }
17220                }
17221            }
17222            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17223            if (stickies == null) {
17224                stickies = new ArrayMap<>();
17225                mStickyBroadcasts.put(userId, stickies);
17226            }
17227            ArrayList<Intent> list = stickies.get(intent.getAction());
17228            if (list == null) {
17229                list = new ArrayList<>();
17230                stickies.put(intent.getAction(), list);
17231            }
17232            final int stickiesCount = list.size();
17233            int i;
17234            for (i = 0; i < stickiesCount; i++) {
17235                if (intent.filterEquals(list.get(i))) {
17236                    // This sticky already exists, replace it.
17237                    list.set(i, new Intent(intent));
17238                    break;
17239                }
17240            }
17241            if (i >= stickiesCount) {
17242                list.add(new Intent(intent));
17243            }
17244        }
17245
17246        int[] users;
17247        if (userId == UserHandle.USER_ALL) {
17248            // Caller wants broadcast to go to all started users.
17249            users = mUserController.getStartedUserArrayLocked();
17250        } else {
17251            // Caller wants broadcast to go to one specific user.
17252            users = new int[] {userId};
17253        }
17254
17255        // Figure out who all will receive this broadcast.
17256        List receivers = null;
17257        List<BroadcastFilter> registeredReceivers = null;
17258        // Need to resolve the intent to interested receivers...
17259        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17260                 == 0) {
17261            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17262        }
17263        if (intent.getComponent() == null) {
17264            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17265                // Query one target user at a time, excluding shell-restricted users
17266                for (int i = 0; i < users.length; i++) {
17267                    if (mUserController.hasUserRestriction(
17268                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17269                        continue;
17270                    }
17271                    List<BroadcastFilter> registeredReceiversForUser =
17272                            mReceiverResolver.queryIntent(intent,
17273                                    resolvedType, false, users[i]);
17274                    if (registeredReceivers == null) {
17275                        registeredReceivers = registeredReceiversForUser;
17276                    } else if (registeredReceiversForUser != null) {
17277                        registeredReceivers.addAll(registeredReceiversForUser);
17278                    }
17279                }
17280            } else {
17281                registeredReceivers = mReceiverResolver.queryIntent(intent,
17282                        resolvedType, false, userId);
17283            }
17284        }
17285
17286        final boolean replacePending =
17287                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17288
17289        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17290                + " replacePending=" + replacePending);
17291
17292        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17293        if (!ordered && NR > 0) {
17294            // If we are not serializing this broadcast, then send the
17295            // registered receivers separately so they don't wait for the
17296            // components to be launched.
17297            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17298            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17299                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17300                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17301                    resultExtras, ordered, sticky, false, userId);
17302            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17303            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17304            if (!replaced) {
17305                queue.enqueueParallelBroadcastLocked(r);
17306                queue.scheduleBroadcastsLocked();
17307            }
17308            registeredReceivers = null;
17309            NR = 0;
17310        }
17311
17312        // Merge into one list.
17313        int ir = 0;
17314        if (receivers != null) {
17315            // A special case for PACKAGE_ADDED: do not allow the package
17316            // being added to see this broadcast.  This prevents them from
17317            // using this as a back door to get run as soon as they are
17318            // installed.  Maybe in the future we want to have a special install
17319            // broadcast or such for apps, but we'd like to deliberately make
17320            // this decision.
17321            String skipPackages[] = null;
17322            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17323                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17324                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17325                Uri data = intent.getData();
17326                if (data != null) {
17327                    String pkgName = data.getSchemeSpecificPart();
17328                    if (pkgName != null) {
17329                        skipPackages = new String[] { pkgName };
17330                    }
17331                }
17332            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17333                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17334            }
17335            if (skipPackages != null && (skipPackages.length > 0)) {
17336                for (String skipPackage : skipPackages) {
17337                    if (skipPackage != null) {
17338                        int NT = receivers.size();
17339                        for (int it=0; it<NT; it++) {
17340                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17341                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17342                                receivers.remove(it);
17343                                it--;
17344                                NT--;
17345                            }
17346                        }
17347                    }
17348                }
17349            }
17350
17351            int NT = receivers != null ? receivers.size() : 0;
17352            int it = 0;
17353            ResolveInfo curt = null;
17354            BroadcastFilter curr = null;
17355            while (it < NT && ir < NR) {
17356                if (curt == null) {
17357                    curt = (ResolveInfo)receivers.get(it);
17358                }
17359                if (curr == null) {
17360                    curr = registeredReceivers.get(ir);
17361                }
17362                if (curr.getPriority() >= curt.priority) {
17363                    // Insert this broadcast record into the final list.
17364                    receivers.add(it, curr);
17365                    ir++;
17366                    curr = null;
17367                    it++;
17368                    NT++;
17369                } else {
17370                    // Skip to the next ResolveInfo in the final list.
17371                    it++;
17372                    curt = null;
17373                }
17374            }
17375        }
17376        while (ir < NR) {
17377            if (receivers == null) {
17378                receivers = new ArrayList();
17379            }
17380            receivers.add(registeredReceivers.get(ir));
17381            ir++;
17382        }
17383
17384        if ((receivers != null && receivers.size() > 0)
17385                || resultTo != null) {
17386            BroadcastQueue queue = broadcastQueueForIntent(intent);
17387            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17388                    callerPackage, callingPid, callingUid, resolvedType,
17389                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17390                    resultData, resultExtras, ordered, sticky, false, userId);
17391
17392            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17393                    + ": prev had " + queue.mOrderedBroadcasts.size());
17394            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17395                    "Enqueueing broadcast " + r.intent.getAction());
17396
17397            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17398            if (!replaced) {
17399                queue.enqueueOrderedBroadcastLocked(r);
17400                queue.scheduleBroadcastsLocked();
17401            }
17402        }
17403
17404        return ActivityManager.BROADCAST_SUCCESS;
17405    }
17406
17407    final Intent verifyBroadcastLocked(Intent intent) {
17408        // Refuse possible leaked file descriptors
17409        if (intent != null && intent.hasFileDescriptors() == true) {
17410            throw new IllegalArgumentException("File descriptors passed in Intent");
17411        }
17412
17413        int flags = intent.getFlags();
17414
17415        if (!mProcessesReady) {
17416            // if the caller really truly claims to know what they're doing, go
17417            // ahead and allow the broadcast without launching any receivers
17418            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17419                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17420            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17421                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17422                        + " before boot completion");
17423                throw new IllegalStateException("Cannot broadcast before boot completed");
17424            }
17425        }
17426
17427        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17428            throw new IllegalArgumentException(
17429                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17430        }
17431
17432        return intent;
17433    }
17434
17435    public final int broadcastIntent(IApplicationThread caller,
17436            Intent intent, String resolvedType, IIntentReceiver resultTo,
17437            int resultCode, String resultData, Bundle resultExtras,
17438            String[] requiredPermissions, int appOp, Bundle bOptions,
17439            boolean serialized, boolean sticky, int userId) {
17440        enforceNotIsolatedCaller("broadcastIntent");
17441        synchronized(this) {
17442            intent = verifyBroadcastLocked(intent);
17443
17444            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17445            final int callingPid = Binder.getCallingPid();
17446            final int callingUid = Binder.getCallingUid();
17447            final long origId = Binder.clearCallingIdentity();
17448            int res = broadcastIntentLocked(callerApp,
17449                    callerApp != null ? callerApp.info.packageName : null,
17450                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17451                    requiredPermissions, appOp, null, serialized, sticky,
17452                    callingPid, callingUid, userId);
17453            Binder.restoreCallingIdentity(origId);
17454            return res;
17455        }
17456    }
17457
17458
17459    int broadcastIntentInPackage(String packageName, int uid,
17460            Intent intent, String resolvedType, IIntentReceiver resultTo,
17461            int resultCode, String resultData, Bundle resultExtras,
17462            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17463            int userId) {
17464        synchronized(this) {
17465            intent = verifyBroadcastLocked(intent);
17466
17467            final long origId = Binder.clearCallingIdentity();
17468            String[] requiredPermissions = requiredPermission == null ? null
17469                    : new String[] {requiredPermission};
17470            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17471                    resultTo, resultCode, resultData, resultExtras,
17472                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17473                    sticky, -1, uid, userId);
17474            Binder.restoreCallingIdentity(origId);
17475            return res;
17476        }
17477    }
17478
17479    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17480        // Refuse possible leaked file descriptors
17481        if (intent != null && intent.hasFileDescriptors() == true) {
17482            throw new IllegalArgumentException("File descriptors passed in Intent");
17483        }
17484
17485        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17486                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17487
17488        synchronized(this) {
17489            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17490                    != PackageManager.PERMISSION_GRANTED) {
17491                String msg = "Permission Denial: unbroadcastIntent() from pid="
17492                        + Binder.getCallingPid()
17493                        + ", uid=" + Binder.getCallingUid()
17494                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17495                Slog.w(TAG, msg);
17496                throw new SecurityException(msg);
17497            }
17498            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17499            if (stickies != null) {
17500                ArrayList<Intent> list = stickies.get(intent.getAction());
17501                if (list != null) {
17502                    int N = list.size();
17503                    int i;
17504                    for (i=0; i<N; i++) {
17505                        if (intent.filterEquals(list.get(i))) {
17506                            list.remove(i);
17507                            break;
17508                        }
17509                    }
17510                    if (list.size() <= 0) {
17511                        stickies.remove(intent.getAction());
17512                    }
17513                }
17514                if (stickies.size() <= 0) {
17515                    mStickyBroadcasts.remove(userId);
17516                }
17517            }
17518        }
17519    }
17520
17521    void backgroundServicesFinishedLocked(int userId) {
17522        for (BroadcastQueue queue : mBroadcastQueues) {
17523            queue.backgroundServicesFinishedLocked(userId);
17524        }
17525    }
17526
17527    public void finishReceiver(IBinder who, int resultCode, String resultData,
17528            Bundle resultExtras, boolean resultAbort, int flags) {
17529        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17530
17531        // Refuse possible leaked file descriptors
17532        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17533            throw new IllegalArgumentException("File descriptors passed in Bundle");
17534        }
17535
17536        final long origId = Binder.clearCallingIdentity();
17537        try {
17538            boolean doNext = false;
17539            BroadcastRecord r;
17540
17541            synchronized(this) {
17542                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17543                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17544                r = queue.getMatchingOrderedReceiver(who);
17545                if (r != null) {
17546                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17547                        resultData, resultExtras, resultAbort, true);
17548                }
17549            }
17550
17551            if (doNext) {
17552                r.queue.processNextBroadcast(false);
17553            }
17554            trimApplications();
17555        } finally {
17556            Binder.restoreCallingIdentity(origId);
17557        }
17558    }
17559
17560    // =========================================================
17561    // INSTRUMENTATION
17562    // =========================================================
17563
17564    public boolean startInstrumentation(ComponentName className,
17565            String profileFile, int flags, Bundle arguments,
17566            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17567            int userId, String abiOverride) {
17568        enforceNotIsolatedCaller("startInstrumentation");
17569        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17570                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17571        // Refuse possible leaked file descriptors
17572        if (arguments != null && arguments.hasFileDescriptors()) {
17573            throw new IllegalArgumentException("File descriptors passed in Bundle");
17574        }
17575
17576        synchronized(this) {
17577            InstrumentationInfo ii = null;
17578            ApplicationInfo ai = null;
17579            try {
17580                ii = mContext.getPackageManager().getInstrumentationInfo(
17581                    className, STOCK_PM_FLAGS);
17582                ai = AppGlobals.getPackageManager().getApplicationInfo(
17583                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17584            } catch (PackageManager.NameNotFoundException e) {
17585            } catch (RemoteException e) {
17586            }
17587            if (ii == null) {
17588                reportStartInstrumentationFailure(watcher, className,
17589                        "Unable to find instrumentation info for: " + className);
17590                return false;
17591            }
17592            if (ai == null) {
17593                reportStartInstrumentationFailure(watcher, className,
17594                        "Unable to find instrumentation target package: " + ii.targetPackage);
17595                return false;
17596            }
17597            if (!ai.hasCode()) {
17598                reportStartInstrumentationFailure(watcher, className,
17599                        "Instrumentation target has no code: " + ii.targetPackage);
17600                return false;
17601            }
17602
17603            int match = mContext.getPackageManager().checkSignatures(
17604                    ii.targetPackage, ii.packageName);
17605            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17606                String msg = "Permission Denial: starting instrumentation "
17607                        + className + " from pid="
17608                        + Binder.getCallingPid()
17609                        + ", uid=" + Binder.getCallingPid()
17610                        + " not allowed because package " + ii.packageName
17611                        + " does not have a signature matching the target "
17612                        + ii.targetPackage;
17613                reportStartInstrumentationFailure(watcher, className, msg);
17614                throw new SecurityException(msg);
17615            }
17616
17617            final long origId = Binder.clearCallingIdentity();
17618            // Instrumentation can kill and relaunch even persistent processes
17619            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17620                    "start instr");
17621            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17622            app.instrumentationClass = className;
17623            app.instrumentationInfo = ai;
17624            app.instrumentationProfileFile = profileFile;
17625            app.instrumentationArguments = arguments;
17626            app.instrumentationWatcher = watcher;
17627            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17628            app.instrumentationResultClass = className;
17629            Binder.restoreCallingIdentity(origId);
17630        }
17631
17632        return true;
17633    }
17634
17635    /**
17636     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17637     * error to the logs, but if somebody is watching, send the report there too.  This enables
17638     * the "am" command to report errors with more information.
17639     *
17640     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17641     * @param cn The component name of the instrumentation.
17642     * @param report The error report.
17643     */
17644    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17645            ComponentName cn, String report) {
17646        Slog.w(TAG, report);
17647        try {
17648            if (watcher != null) {
17649                Bundle results = new Bundle();
17650                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17651                results.putString("Error", report);
17652                watcher.instrumentationStatus(cn, -1, results);
17653            }
17654        } catch (RemoteException e) {
17655            Slog.w(TAG, e);
17656        }
17657    }
17658
17659    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17660        if (app.instrumentationWatcher != null) {
17661            try {
17662                // NOTE:  IInstrumentationWatcher *must* be oneway here
17663                app.instrumentationWatcher.instrumentationFinished(
17664                    app.instrumentationClass,
17665                    resultCode,
17666                    results);
17667            } catch (RemoteException e) {
17668            }
17669        }
17670
17671        // Can't call out of the system process with a lock held, so post a message.
17672        if (app.instrumentationUiAutomationConnection != null) {
17673            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17674                    app.instrumentationUiAutomationConnection).sendToTarget();
17675        }
17676
17677        app.instrumentationWatcher = null;
17678        app.instrumentationUiAutomationConnection = null;
17679        app.instrumentationClass = null;
17680        app.instrumentationInfo = null;
17681        app.instrumentationProfileFile = null;
17682        app.instrumentationArguments = null;
17683
17684        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17685                "finished inst");
17686    }
17687
17688    public void finishInstrumentation(IApplicationThread target,
17689            int resultCode, Bundle results) {
17690        int userId = UserHandle.getCallingUserId();
17691        // Refuse possible leaked file descriptors
17692        if (results != null && results.hasFileDescriptors()) {
17693            throw new IllegalArgumentException("File descriptors passed in Intent");
17694        }
17695
17696        synchronized(this) {
17697            ProcessRecord app = getRecordForAppLocked(target);
17698            if (app == null) {
17699                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17700                return;
17701            }
17702            final long origId = Binder.clearCallingIdentity();
17703            finishInstrumentationLocked(app, resultCode, results);
17704            Binder.restoreCallingIdentity(origId);
17705        }
17706    }
17707
17708    // =========================================================
17709    // CONFIGURATION
17710    // =========================================================
17711
17712    public ConfigurationInfo getDeviceConfigurationInfo() {
17713        ConfigurationInfo config = new ConfigurationInfo();
17714        synchronized (this) {
17715            config.reqTouchScreen = mConfiguration.touchscreen;
17716            config.reqKeyboardType = mConfiguration.keyboard;
17717            config.reqNavigation = mConfiguration.navigation;
17718            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17719                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17720                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17721            }
17722            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17723                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17724                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17725            }
17726            config.reqGlEsVersion = GL_ES_VERSION;
17727        }
17728        return config;
17729    }
17730
17731    ActivityStack getFocusedStack() {
17732        return mStackSupervisor.getFocusedStack();
17733    }
17734
17735    @Override
17736    public int getFocusedStackId() throws RemoteException {
17737        ActivityStack focusedStack = getFocusedStack();
17738        if (focusedStack != null) {
17739            return focusedStack.getStackId();
17740        }
17741        return -1;
17742    }
17743
17744    public Configuration getConfiguration() {
17745        Configuration ci;
17746        synchronized(this) {
17747            ci = new Configuration(mConfiguration);
17748            ci.userSetLocale = false;
17749        }
17750        return ci;
17751    }
17752
17753    @Override
17754    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17755        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17756        synchronized (this) {
17757            mSuppressResizeConfigChanges = suppress;
17758        }
17759    }
17760
17761    @Override
17762    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17764        if (fromStackId == HOME_STACK_ID) {
17765            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17766        }
17767        synchronized (this) {
17768            final long origId = Binder.clearCallingIdentity();
17769            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17770            if (stack != null) {
17771                if (fromStackId == DOCKED_STACK_ID) {
17772
17773                    // We are moving all tasks from the docked stack to the fullscreen stack, which
17774                    // is dismissing the docked stack, so resize all other stacks to fullscreen here
17775                    // already so we don't end up with resize trashing.
17776                    for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17777                        if (StackId.isResizeableByDockedStack(i)) {
17778                            ActivityStack otherStack = mStackSupervisor.getStack(i);
17779                            if (otherStack != null) {
17780                                mStackSupervisor.resizeStackLocked(i,
17781                                        null, null, null, PRESERVE_WINDOWS,
17782                                        true /* allowResizeInDockedMode */);
17783                            }
17784                        }
17785                    }
17786                }
17787                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17788                final int size = tasks.size();
17789                if (onTop) {
17790                    for (int i = 0; i < size; i++) {
17791                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17792                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
17793                                "moveTasksToFullscreenStack", ANIMATE);
17794                    }
17795                } else {
17796                    for (int i = size - 1; i >= 0; i--) {
17797                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17798                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
17799                    }
17800                }
17801            }
17802            Binder.restoreCallingIdentity(origId);
17803        }
17804    }
17805
17806    @Override
17807    public void updatePersistentConfiguration(Configuration values) {
17808        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17809                "updateConfiguration()");
17810        enforceWriteSettingsPermission("updateConfiguration()");
17811        if (values == null) {
17812            throw new NullPointerException("Configuration must not be null");
17813        }
17814
17815        int userId = UserHandle.getCallingUserId();
17816
17817        synchronized(this) {
17818            final long origId = Binder.clearCallingIdentity();
17819            updateConfigurationLocked(values, null, false, true, userId);
17820            Binder.restoreCallingIdentity(origId);
17821        }
17822    }
17823
17824    private void updateFontScaleIfNeeded() {
17825        final int currentUserId;
17826        synchronized(this) {
17827            currentUserId = mUserController.getCurrentUserIdLocked();
17828        }
17829        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17830                FONT_SCALE, 1.0f, currentUserId);
17831        if (mConfiguration.fontScale != scaleFactor) {
17832            final Configuration configuration = mWindowManager.computeNewConfiguration();
17833            configuration.fontScale = scaleFactor;
17834            updatePersistentConfiguration(configuration);
17835        }
17836    }
17837
17838    private void enforceWriteSettingsPermission(String func) {
17839        int uid = Binder.getCallingUid();
17840        if (uid == Process.ROOT_UID) {
17841            return;
17842        }
17843
17844        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17845                Settings.getPackageNameForUid(mContext, uid), false)) {
17846            return;
17847        }
17848
17849        String msg = "Permission Denial: " + func + " from pid="
17850                + Binder.getCallingPid()
17851                + ", uid=" + uid
17852                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17853        Slog.w(TAG, msg);
17854        throw new SecurityException(msg);
17855    }
17856
17857    public void updateConfiguration(Configuration values) {
17858        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17859                "updateConfiguration()");
17860
17861        synchronized(this) {
17862            if (values == null && mWindowManager != null) {
17863                // sentinel: fetch the current configuration from the window manager
17864                values = mWindowManager.computeNewConfiguration();
17865            }
17866
17867            if (mWindowManager != null) {
17868                mProcessList.applyDisplaySize(mWindowManager);
17869            }
17870
17871            final long origId = Binder.clearCallingIdentity();
17872            if (values != null) {
17873                Settings.System.clearConfiguration(values);
17874            }
17875            updateConfigurationLocked(values, null, false);
17876            Binder.restoreCallingIdentity(origId);
17877        }
17878    }
17879
17880    void updateUserConfigurationLocked() {
17881        Configuration configuration = new Configuration(mConfiguration);
17882        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17883                mUserController.getCurrentUserIdLocked());
17884        updateConfigurationLocked(configuration, null, false);
17885    }
17886
17887    boolean updateConfigurationLocked(Configuration values,
17888            ActivityRecord starting, boolean initLocale) {
17889        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17890        return updateConfigurationLocked(values, starting, initLocale, false,
17891                UserHandle.USER_NULL);
17892    }
17893
17894    // To cache the list of supported system locales
17895    private String[] mSupportedSystemLocales = null;
17896
17897    /**
17898     * Do either or both things: (1) change the current configuration, and (2)
17899     * make sure the given activity is running with the (now) current
17900     * configuration.  Returns true if the activity has been left running, or
17901     * false if <var>starting</var> is being destroyed to match the new
17902     * configuration.
17903     *
17904     * @param userId is only used when persistent parameter is set to true to persist configuration
17905     *               for that particular user
17906     */
17907    private boolean updateConfigurationLocked(Configuration values,
17908            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17909        int changes = 0;
17910
17911        if (values != null) {
17912            Configuration newConfig = new Configuration(mConfiguration);
17913            changes = newConfig.updateFrom(values);
17914            if (changes != 0) {
17915                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17916                        "Updating configuration to: " + values);
17917
17918                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17919
17920                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17921                    final Locale locale;
17922                    if (values.getLocales().size() == 1) {
17923                        // This is an optimization to avoid the JNI call when the result of
17924                        // getFirstMatch() does not depend on the supported locales.
17925                        locale = values.getLocales().get(0);
17926                    } else {
17927                        if (mSupportedSystemLocales == null) {
17928                            mSupportedSystemLocales =
17929                                    Resources.getSystem().getAssets().getLocales();
17930                        }
17931                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
17932                    }
17933                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17934                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17935                            locale));
17936                }
17937
17938                mConfigurationSeq++;
17939                if (mConfigurationSeq <= 0) {
17940                    mConfigurationSeq = 1;
17941                }
17942                newConfig.seq = mConfigurationSeq;
17943                mConfiguration = newConfig;
17944                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17945                mUsageStatsService.reportConfigurationChange(newConfig,
17946                        mUserController.getCurrentUserIdLocked());
17947                //mUsageStatsService.noteStartConfig(newConfig);
17948
17949                final Configuration configCopy = new Configuration(mConfiguration);
17950
17951                // TODO: If our config changes, should we auto dismiss any currently
17952                // showing dialogs?
17953                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
17954
17955                AttributeCache ac = AttributeCache.instance();
17956                if (ac != null) {
17957                    ac.updateConfiguration(configCopy);
17958                }
17959
17960                // Make sure all resources in our process are updated
17961                // right now, so that anyone who is going to retrieve
17962                // resource values after we return will be sure to get
17963                // the new ones.  This is especially important during
17964                // boot, where the first config change needs to guarantee
17965                // all resources have that config before following boot
17966                // code is executed.
17967                mSystemThread.applyConfigurationToResources(configCopy);
17968
17969                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17970                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17971                    msg.obj = new Configuration(configCopy);
17972                    msg.arg1 = userId;
17973                    mHandler.sendMessage(msg);
17974                }
17975
17976                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
17977                if (isDensityChange) {
17978                    killAllBackgroundProcesses(Build.VERSION_CODES.N);
17979                }
17980
17981                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17982                    ProcessRecord app = mLruProcesses.get(i);
17983                    try {
17984                        if (app.thread != null) {
17985                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17986                                    + app.processName + " new config " + mConfiguration);
17987                            app.thread.scheduleConfigurationChanged(configCopy);
17988                        }
17989                    } catch (Exception e) {
17990                    }
17991                }
17992                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17993                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17994                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17995                        | Intent.FLAG_RECEIVER_FOREGROUND);
17996                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17997                        null, AppOpsManager.OP_NONE, null, false, false,
17998                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17999                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18000                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18001                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18002                    if (!mProcessesReady) {
18003                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18004                    }
18005                    broadcastIntentLocked(null, null, intent,
18006                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18007                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18008                }
18009            }
18010        }
18011
18012        boolean kept = true;
18013        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18014        // mainStack is null during startup.
18015        if (mainStack != null) {
18016            if (changes != 0 && starting == null) {
18017                // If the configuration changed, and the caller is not already
18018                // in the process of starting an activity, then find the top
18019                // activity to check if its configuration needs to change.
18020                starting = mainStack.topRunningActivityLocked();
18021            }
18022
18023            if (starting != null) {
18024                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18025                // And we need to make sure at this point that all other activities
18026                // are made visible with the correct configuration.
18027                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18028                        !PRESERVE_WINDOWS);
18029            }
18030        }
18031
18032        if (values != null && mWindowManager != null) {
18033            mWindowManager.setNewConfiguration(mConfiguration);
18034        }
18035
18036        return kept;
18037    }
18038
18039    /**
18040     * Decide based on the configuration whether we should shouw the ANR,
18041     * crash, etc dialogs.  The idea is that if there is no affordnace to
18042     * press the on-screen buttons, we shouldn't show the dialog.
18043     *
18044     * A thought: SystemUI might also want to get told about this, the Power
18045     * dialog / global actions also might want different behaviors.
18046     */
18047    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18048        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18049                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18050                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18051        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18052                                    == Configuration.UI_MODE_TYPE_CAR);
18053        return inputMethodExists && uiIsNotCarType && !inVrMode;
18054    }
18055
18056    @Override
18057    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18058        synchronized (this) {
18059            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18060            if (srec != null) {
18061                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18062            }
18063        }
18064        return false;
18065    }
18066
18067    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18068            Intent resultData) {
18069
18070        synchronized (this) {
18071            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18072            if (r != null) {
18073                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18074            }
18075            return false;
18076        }
18077    }
18078
18079    public int getLaunchedFromUid(IBinder activityToken) {
18080        ActivityRecord srec;
18081        synchronized (this) {
18082            srec = ActivityRecord.forTokenLocked(activityToken);
18083        }
18084        if (srec == null) {
18085            return -1;
18086        }
18087        return srec.launchedFromUid;
18088    }
18089
18090    public String getLaunchedFromPackage(IBinder activityToken) {
18091        ActivityRecord srec;
18092        synchronized (this) {
18093            srec = ActivityRecord.forTokenLocked(activityToken);
18094        }
18095        if (srec == null) {
18096            return null;
18097        }
18098        return srec.launchedFromPackage;
18099    }
18100
18101    // =========================================================
18102    // LIFETIME MANAGEMENT
18103    // =========================================================
18104
18105    // Returns which broadcast queue the app is the current [or imminent] receiver
18106    // on, or 'null' if the app is not an active broadcast recipient.
18107    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18108        BroadcastRecord r = app.curReceiver;
18109        if (r != null) {
18110            return r.queue;
18111        }
18112
18113        // It's not the current receiver, but it might be starting up to become one
18114        synchronized (this) {
18115            for (BroadcastQueue queue : mBroadcastQueues) {
18116                r = queue.mPendingBroadcast;
18117                if (r != null && r.curApp == app) {
18118                    // found it; report which queue it's in
18119                    return queue;
18120                }
18121            }
18122        }
18123
18124        return null;
18125    }
18126
18127    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18128            ComponentName targetComponent, String targetProcess) {
18129        if (!mTrackingAssociations) {
18130            return null;
18131        }
18132        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18133                = mAssociations.get(targetUid);
18134        if (components == null) {
18135            components = new ArrayMap<>();
18136            mAssociations.put(targetUid, components);
18137        }
18138        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18139        if (sourceUids == null) {
18140            sourceUids = new SparseArray<>();
18141            components.put(targetComponent, sourceUids);
18142        }
18143        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18144        if (sourceProcesses == null) {
18145            sourceProcesses = new ArrayMap<>();
18146            sourceUids.put(sourceUid, sourceProcesses);
18147        }
18148        Association ass = sourceProcesses.get(sourceProcess);
18149        if (ass == null) {
18150            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18151                    targetProcess);
18152            sourceProcesses.put(sourceProcess, ass);
18153        }
18154        ass.mCount++;
18155        ass.mNesting++;
18156        if (ass.mNesting == 1) {
18157            ass.mStartTime = SystemClock.uptimeMillis();
18158        }
18159        return ass;
18160    }
18161
18162    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18163            ComponentName targetComponent) {
18164        if (!mTrackingAssociations) {
18165            return;
18166        }
18167        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18168                = mAssociations.get(targetUid);
18169        if (components == null) {
18170            return;
18171        }
18172        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18173        if (sourceUids == null) {
18174            return;
18175        }
18176        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18177        if (sourceProcesses == null) {
18178            return;
18179        }
18180        Association ass = sourceProcesses.get(sourceProcess);
18181        if (ass == null || ass.mNesting <= 0) {
18182            return;
18183        }
18184        ass.mNesting--;
18185        if (ass.mNesting == 0) {
18186            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18187        }
18188    }
18189
18190    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18191            boolean doingAll, long now) {
18192        if (mAdjSeq == app.adjSeq) {
18193            // This adjustment has already been computed.
18194            return app.curRawAdj;
18195        }
18196
18197        if (app.thread == null) {
18198            app.adjSeq = mAdjSeq;
18199            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18200            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18201            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18202        }
18203
18204        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18205        app.adjSource = null;
18206        app.adjTarget = null;
18207        app.empty = false;
18208        app.cached = false;
18209
18210        final int activitiesSize = app.activities.size();
18211
18212        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18213            // The max adjustment doesn't allow this app to be anything
18214            // below foreground, so it is not worth doing work for it.
18215            app.adjType = "fixed";
18216            app.adjSeq = mAdjSeq;
18217            app.curRawAdj = app.maxAdj;
18218            app.foregroundActivities = false;
18219            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18220            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18221            // System processes can do UI, and when they do we want to have
18222            // them trim their memory after the user leaves the UI.  To
18223            // facilitate this, here we need to determine whether or not it
18224            // is currently showing UI.
18225            app.systemNoUi = true;
18226            if (app == TOP_APP) {
18227                app.systemNoUi = false;
18228            } else if (activitiesSize > 0) {
18229                for (int j = 0; j < activitiesSize; j++) {
18230                    final ActivityRecord r = app.activities.get(j);
18231                    if (r.visible) {
18232                        app.systemNoUi = false;
18233                    }
18234                }
18235            }
18236            if (!app.systemNoUi) {
18237                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18238            }
18239            return (app.curAdj=app.maxAdj);
18240        }
18241
18242        app.systemNoUi = false;
18243
18244        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18245
18246        // Determine the importance of the process, starting with most
18247        // important to least, and assign an appropriate OOM adjustment.
18248        int adj;
18249        int schedGroup;
18250        int procState;
18251        boolean foregroundActivities = false;
18252        BroadcastQueue queue;
18253        if (app == TOP_APP) {
18254            // The last app on the list is the foreground app.
18255            adj = ProcessList.FOREGROUND_APP_ADJ;
18256            schedGroup = Process.THREAD_GROUP_TOP_APP;
18257            app.adjType = "top-activity";
18258            foregroundActivities = true;
18259            procState = PROCESS_STATE_CUR_TOP;
18260        } else if (app.instrumentationClass != null) {
18261            // Don't want to kill running instrumentation.
18262            adj = ProcessList.FOREGROUND_APP_ADJ;
18263            schedGroup = Process.THREAD_GROUP_DEFAULT;
18264            app.adjType = "instrumentation";
18265            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18266        } else if ((queue = isReceivingBroadcast(app)) != null) {
18267            // An app that is currently receiving a broadcast also
18268            // counts as being in the foreground for OOM killer purposes.
18269            // It's placed in a sched group based on the nature of the
18270            // broadcast as reflected by which queue it's active in.
18271            adj = ProcessList.FOREGROUND_APP_ADJ;
18272            schedGroup = (queue == mFgBroadcastQueue)
18273                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18274            app.adjType = "broadcast";
18275            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18276        } else if (app.executingServices.size() > 0) {
18277            // An app that is currently executing a service callback also
18278            // counts as being in the foreground.
18279            adj = ProcessList.FOREGROUND_APP_ADJ;
18280            schedGroup = app.execServicesFg ?
18281                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18282            app.adjType = "exec-service";
18283            procState = ActivityManager.PROCESS_STATE_SERVICE;
18284            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18285        } else {
18286            // As far as we know the process is empty.  We may change our mind later.
18287            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18288            // At this point we don't actually know the adjustment.  Use the cached adj
18289            // value that the caller wants us to.
18290            adj = cachedAdj;
18291            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18292            app.cached = true;
18293            app.empty = true;
18294            app.adjType = "cch-empty";
18295        }
18296
18297        // Examine all activities if not already foreground.
18298        if (!foregroundActivities && activitiesSize > 0) {
18299            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18300            for (int j = 0; j < activitiesSize; j++) {
18301                final ActivityRecord r = app.activities.get(j);
18302                if (r.app != app) {
18303                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18304                            + app + "?!? Using " + r.app + " instead.");
18305                    continue;
18306                }
18307                if (r.visible) {
18308                    // App has a visible activity; only upgrade adjustment.
18309                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18310                        adj = ProcessList.VISIBLE_APP_ADJ;
18311                        app.adjType = "visible";
18312                    }
18313                    if (procState > PROCESS_STATE_CUR_TOP) {
18314                        procState = PROCESS_STATE_CUR_TOP;
18315                    }
18316                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18317                    app.cached = false;
18318                    app.empty = false;
18319                    foregroundActivities = true;
18320                    if (r.task != null && minLayer > 0) {
18321                        final int layer = r.task.mLayerRank;
18322                        if (layer >= 0 && minLayer > layer) {
18323                            minLayer = layer;
18324                        }
18325                    }
18326                    break;
18327                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18328                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18329                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18330                        app.adjType = "pausing";
18331                    }
18332                    if (procState > PROCESS_STATE_CUR_TOP) {
18333                        procState = PROCESS_STATE_CUR_TOP;
18334                    }
18335                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18336                    app.cached = false;
18337                    app.empty = false;
18338                    foregroundActivities = true;
18339                } else if (r.state == ActivityState.STOPPING) {
18340                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18341                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18342                        app.adjType = "stopping";
18343                    }
18344                    // For the process state, we will at this point consider the
18345                    // process to be cached.  It will be cached either as an activity
18346                    // or empty depending on whether the activity is finishing.  We do
18347                    // this so that we can treat the process as cached for purposes of
18348                    // memory trimming (determing current memory level, trim command to
18349                    // send to process) since there can be an arbitrary number of stopping
18350                    // processes and they should soon all go into the cached state.
18351                    if (!r.finishing) {
18352                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18353                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18354                        }
18355                    }
18356                    app.cached = false;
18357                    app.empty = false;
18358                    foregroundActivities = true;
18359                } else {
18360                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18361                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18362                        app.adjType = "cch-act";
18363                    }
18364                }
18365            }
18366            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18367                adj += minLayer;
18368            }
18369        }
18370
18371        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18372                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18373            if (app.foregroundServices) {
18374                // The user is aware of this app, so make it visible.
18375                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18376                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18377                app.cached = false;
18378                app.adjType = "fg-service";
18379                schedGroup = Process.THREAD_GROUP_DEFAULT;
18380            } else if (app.forcingToForeground != null) {
18381                // The user is aware of this app, so make it visible.
18382                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18383                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18384                app.cached = false;
18385                app.adjType = "force-fg";
18386                app.adjSource = app.forcingToForeground;
18387                schedGroup = Process.THREAD_GROUP_DEFAULT;
18388            }
18389        }
18390
18391        if (app == mHeavyWeightProcess) {
18392            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18393                // We don't want to kill the current heavy-weight process.
18394                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18395                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18396                app.cached = false;
18397                app.adjType = "heavy";
18398            }
18399            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18400                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18401            }
18402        }
18403
18404        if (app == mHomeProcess) {
18405            if (adj > ProcessList.HOME_APP_ADJ) {
18406                // This process is hosting what we currently consider to be the
18407                // home app, so we don't want to let it go into the background.
18408                adj = ProcessList.HOME_APP_ADJ;
18409                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18410                app.cached = false;
18411                app.adjType = "home";
18412            }
18413            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18414                procState = ActivityManager.PROCESS_STATE_HOME;
18415            }
18416        }
18417
18418        if (app == mPreviousProcess && app.activities.size() > 0) {
18419            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18420                // This was the previous process that showed UI to the user.
18421                // We want to try to keep it around more aggressively, to give
18422                // a good experience around switching between two apps.
18423                adj = ProcessList.PREVIOUS_APP_ADJ;
18424                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18425                app.cached = false;
18426                app.adjType = "previous";
18427            }
18428            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18429                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18430            }
18431        }
18432
18433        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18434                + " reason=" + app.adjType);
18435
18436        // By default, we use the computed adjustment.  It may be changed if
18437        // there are applications dependent on our services or providers, but
18438        // this gives us a baseline and makes sure we don't get into an
18439        // infinite recursion.
18440        app.adjSeq = mAdjSeq;
18441        app.curRawAdj = adj;
18442        app.hasStartedServices = false;
18443
18444        if (mBackupTarget != null && app == mBackupTarget.app) {
18445            // If possible we want to avoid killing apps while they're being backed up
18446            if (adj > ProcessList.BACKUP_APP_ADJ) {
18447                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18448                adj = ProcessList.BACKUP_APP_ADJ;
18449                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18450                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18451                }
18452                app.adjType = "backup";
18453                app.cached = false;
18454            }
18455            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18456                procState = ActivityManager.PROCESS_STATE_BACKUP;
18457            }
18458        }
18459
18460        boolean mayBeTop = false;
18461
18462        for (int is = app.services.size()-1;
18463                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18464                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18465                        || procState > ActivityManager.PROCESS_STATE_TOP);
18466                is--) {
18467            ServiceRecord s = app.services.valueAt(is);
18468            if (s.startRequested) {
18469                app.hasStartedServices = true;
18470                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18471                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18472                }
18473                if (app.hasShownUi && app != mHomeProcess) {
18474                    // If this process has shown some UI, let it immediately
18475                    // go to the LRU list because it may be pretty heavy with
18476                    // UI stuff.  We'll tag it with a label just to help
18477                    // debug and understand what is going on.
18478                    if (adj > ProcessList.SERVICE_ADJ) {
18479                        app.adjType = "cch-started-ui-services";
18480                    }
18481                } else {
18482                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18483                        // This service has seen some activity within
18484                        // recent memory, so we will keep its process ahead
18485                        // of the background processes.
18486                        if (adj > ProcessList.SERVICE_ADJ) {
18487                            adj = ProcessList.SERVICE_ADJ;
18488                            app.adjType = "started-services";
18489                            app.cached = false;
18490                        }
18491                    }
18492                    // If we have let the service slide into the background
18493                    // state, still have some text describing what it is doing
18494                    // even though the service no longer has an impact.
18495                    if (adj > ProcessList.SERVICE_ADJ) {
18496                        app.adjType = "cch-started-services";
18497                    }
18498                }
18499            }
18500            for (int conni = s.connections.size()-1;
18501                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18502                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18503                            || procState > ActivityManager.PROCESS_STATE_TOP);
18504                    conni--) {
18505                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18506                for (int i = 0;
18507                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18508                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18509                                || procState > ActivityManager.PROCESS_STATE_TOP);
18510                        i++) {
18511                    // XXX should compute this based on the max of
18512                    // all connected clients.
18513                    ConnectionRecord cr = clist.get(i);
18514                    if (cr.binding.client == app) {
18515                        // Binding to ourself is not interesting.
18516                        continue;
18517                    }
18518                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18519                        ProcessRecord client = cr.binding.client;
18520                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18521                                TOP_APP, doingAll, now);
18522                        int clientProcState = client.curProcState;
18523                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18524                            // If the other app is cached for any reason, for purposes here
18525                            // we are going to consider it empty.  The specific cached state
18526                            // doesn't propagate except under certain conditions.
18527                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18528                        }
18529                        String adjType = null;
18530                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18531                            // Not doing bind OOM management, so treat
18532                            // this guy more like a started service.
18533                            if (app.hasShownUi && app != mHomeProcess) {
18534                                // If this process has shown some UI, let it immediately
18535                                // go to the LRU list because it may be pretty heavy with
18536                                // UI stuff.  We'll tag it with a label just to help
18537                                // debug and understand what is going on.
18538                                if (adj > clientAdj) {
18539                                    adjType = "cch-bound-ui-services";
18540                                }
18541                                app.cached = false;
18542                                clientAdj = adj;
18543                                clientProcState = procState;
18544                            } else {
18545                                if (now >= (s.lastActivity
18546                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18547                                    // This service has not seen activity within
18548                                    // recent memory, so allow it to drop to the
18549                                    // LRU list if there is no other reason to keep
18550                                    // it around.  We'll also tag it with a label just
18551                                    // to help debug and undertand what is going on.
18552                                    if (adj > clientAdj) {
18553                                        adjType = "cch-bound-services";
18554                                    }
18555                                    clientAdj = adj;
18556                                }
18557                            }
18558                        }
18559                        if (adj > clientAdj) {
18560                            // If this process has recently shown UI, and
18561                            // the process that is binding to it is less
18562                            // important than being visible, then we don't
18563                            // care about the binding as much as we care
18564                            // about letting this process get into the LRU
18565                            // list to be killed and restarted if needed for
18566                            // memory.
18567                            if (app.hasShownUi && app != mHomeProcess
18568                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18569                                adjType = "cch-bound-ui-services";
18570                            } else {
18571                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18572                                        |Context.BIND_IMPORTANT)) != 0) {
18573                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18574                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18575                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18576                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18577                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18578                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18579                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18580                                    adj = clientAdj;
18581                                } else {
18582                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18583                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18584                                    }
18585                                }
18586                                if (!client.cached) {
18587                                    app.cached = false;
18588                                }
18589                                adjType = "service";
18590                            }
18591                        }
18592                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18593                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18594                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18595                            }
18596                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18597                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18598                                    // Special handling of clients who are in the top state.
18599                                    // We *may* want to consider this process to be in the
18600                                    // top state as well, but only if there is not another
18601                                    // reason for it to be running.  Being on the top is a
18602                                    // special state, meaning you are specifically running
18603                                    // for the current top app.  If the process is already
18604                                    // running in the background for some other reason, it
18605                                    // is more important to continue considering it to be
18606                                    // in the background state.
18607                                    mayBeTop = true;
18608                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18609                                } else {
18610                                    // Special handling for above-top states (persistent
18611                                    // processes).  These should not bring the current process
18612                                    // into the top state, since they are not on top.  Instead
18613                                    // give them the best state after that.
18614                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18615                                        clientProcState =
18616                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18617                                    } else if (mWakefulness
18618                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18619                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18620                                                    != 0) {
18621                                        clientProcState =
18622                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18623                                    } else {
18624                                        clientProcState =
18625                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18626                                    }
18627                                }
18628                            }
18629                        } else {
18630                            if (clientProcState <
18631                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18632                                clientProcState =
18633                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18634                            }
18635                        }
18636                        if (procState > clientProcState) {
18637                            procState = clientProcState;
18638                        }
18639                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18640                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18641                            app.pendingUiClean = true;
18642                        }
18643                        if (adjType != null) {
18644                            app.adjType = adjType;
18645                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18646                                    .REASON_SERVICE_IN_USE;
18647                            app.adjSource = cr.binding.client;
18648                            app.adjSourceProcState = clientProcState;
18649                            app.adjTarget = s.name;
18650                        }
18651                    }
18652                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18653                        app.treatLikeActivity = true;
18654                    }
18655                    final ActivityRecord a = cr.activity;
18656                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18657                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18658                                (a.visible || a.state == ActivityState.RESUMED
18659                                 || a.state == ActivityState.PAUSING)) {
18660                            adj = ProcessList.FOREGROUND_APP_ADJ;
18661                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18662                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18663                            }
18664                            app.cached = false;
18665                            app.adjType = "service";
18666                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18667                                    .REASON_SERVICE_IN_USE;
18668                            app.adjSource = a;
18669                            app.adjSourceProcState = procState;
18670                            app.adjTarget = s.name;
18671                        }
18672                    }
18673                }
18674            }
18675        }
18676
18677        for (int provi = app.pubProviders.size()-1;
18678                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18679                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18680                        || procState > ActivityManager.PROCESS_STATE_TOP);
18681                provi--) {
18682            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18683            for (int i = cpr.connections.size()-1;
18684                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18685                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18686                            || procState > ActivityManager.PROCESS_STATE_TOP);
18687                    i--) {
18688                ContentProviderConnection conn = cpr.connections.get(i);
18689                ProcessRecord client = conn.client;
18690                if (client == app) {
18691                    // Being our own client is not interesting.
18692                    continue;
18693                }
18694                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18695                int clientProcState = client.curProcState;
18696                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18697                    // If the other app is cached for any reason, for purposes here
18698                    // we are going to consider it empty.
18699                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18700                }
18701                if (adj > clientAdj) {
18702                    if (app.hasShownUi && app != mHomeProcess
18703                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18704                        app.adjType = "cch-ui-provider";
18705                    } else {
18706                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18707                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18708                        app.adjType = "provider";
18709                    }
18710                    app.cached &= client.cached;
18711                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18712                            .REASON_PROVIDER_IN_USE;
18713                    app.adjSource = client;
18714                    app.adjSourceProcState = clientProcState;
18715                    app.adjTarget = cpr.name;
18716                }
18717                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18718                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18719                        // Special handling of clients who are in the top state.
18720                        // We *may* want to consider this process to be in the
18721                        // top state as well, but only if there is not another
18722                        // reason for it to be running.  Being on the top is a
18723                        // special state, meaning you are specifically running
18724                        // for the current top app.  If the process is already
18725                        // running in the background for some other reason, it
18726                        // is more important to continue considering it to be
18727                        // in the background state.
18728                        mayBeTop = true;
18729                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18730                    } else {
18731                        // Special handling for above-top states (persistent
18732                        // processes).  These should not bring the current process
18733                        // into the top state, since they are not on top.  Instead
18734                        // give them the best state after that.
18735                        clientProcState =
18736                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18737                    }
18738                }
18739                if (procState > clientProcState) {
18740                    procState = clientProcState;
18741                }
18742                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18743                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18744                }
18745            }
18746            // If the provider has external (non-framework) process
18747            // dependencies, ensure that its adjustment is at least
18748            // FOREGROUND_APP_ADJ.
18749            if (cpr.hasExternalProcessHandles()) {
18750                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18751                    adj = ProcessList.FOREGROUND_APP_ADJ;
18752                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18753                    app.cached = false;
18754                    app.adjType = "provider";
18755                    app.adjTarget = cpr.name;
18756                }
18757                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18758                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18759                }
18760            }
18761        }
18762
18763        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18764            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18765                adj = ProcessList.PREVIOUS_APP_ADJ;
18766                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18767                app.cached = false;
18768                app.adjType = "provider";
18769            }
18770            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18771                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18772            }
18773        }
18774
18775        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18776            // A client of one of our services or providers is in the top state.  We
18777            // *may* want to be in the top state, but not if we are already running in
18778            // the background for some other reason.  For the decision here, we are going
18779            // to pick out a few specific states that we want to remain in when a client
18780            // is top (states that tend to be longer-term) and otherwise allow it to go
18781            // to the top state.
18782            switch (procState) {
18783                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18784                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18785                case ActivityManager.PROCESS_STATE_SERVICE:
18786                    // These all are longer-term states, so pull them up to the top
18787                    // of the background states, but not all the way to the top state.
18788                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18789                    break;
18790                default:
18791                    // Otherwise, top is a better choice, so take it.
18792                    procState = ActivityManager.PROCESS_STATE_TOP;
18793                    break;
18794            }
18795        }
18796
18797        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18798            if (app.hasClientActivities) {
18799                // This is a cached process, but with client activities.  Mark it so.
18800                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18801                app.adjType = "cch-client-act";
18802            } else if (app.treatLikeActivity) {
18803                // This is a cached process, but somebody wants us to treat it like it has
18804                // an activity, okay!
18805                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18806                app.adjType = "cch-as-act";
18807            }
18808        }
18809
18810        if (adj == ProcessList.SERVICE_ADJ) {
18811            if (doingAll) {
18812                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18813                mNewNumServiceProcs++;
18814                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18815                if (!app.serviceb) {
18816                    // This service isn't far enough down on the LRU list to
18817                    // normally be a B service, but if we are low on RAM and it
18818                    // is large we want to force it down since we would prefer to
18819                    // keep launcher over it.
18820                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18821                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18822                        app.serviceHighRam = true;
18823                        app.serviceb = true;
18824                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18825                    } else {
18826                        mNewNumAServiceProcs++;
18827                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18828                    }
18829                } else {
18830                    app.serviceHighRam = false;
18831                }
18832            }
18833            if (app.serviceb) {
18834                adj = ProcessList.SERVICE_B_ADJ;
18835            }
18836        }
18837
18838        app.curRawAdj = adj;
18839
18840        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18841        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18842        if (adj > app.maxAdj) {
18843            adj = app.maxAdj;
18844            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18845                schedGroup = Process.THREAD_GROUP_DEFAULT;
18846            }
18847        }
18848
18849        // Do final modification to adj.  Everything we do between here and applying
18850        // the final setAdj must be done in this function, because we will also use
18851        // it when computing the final cached adj later.  Note that we don't need to
18852        // worry about this for max adj above, since max adj will always be used to
18853        // keep it out of the cached vaues.
18854        app.curAdj = app.modifyRawOomAdj(adj);
18855        app.curSchedGroup = schedGroup;
18856        app.curProcState = procState;
18857        app.foregroundActivities = foregroundActivities;
18858
18859        return app.curRawAdj;
18860    }
18861
18862    /**
18863     * Record new PSS sample for a process.
18864     */
18865    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
18866            long now) {
18867        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
18868                swapPss * 1024);
18869        proc.lastPssTime = now;
18870        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18871        if (DEBUG_PSS) Slog.d(TAG_PSS,
18872                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18873                + " state=" + ProcessList.makeProcStateString(procState));
18874        if (proc.initialIdlePss == 0) {
18875            proc.initialIdlePss = pss;
18876        }
18877        proc.lastPss = pss;
18878        proc.lastSwapPss = swapPss;
18879        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18880            proc.lastCachedPss = pss;
18881            proc.lastCachedSwapPss = swapPss;
18882        }
18883
18884        final SparseArray<Pair<Long, String>> watchUids
18885                = mMemWatchProcesses.getMap().get(proc.processName);
18886        Long check = null;
18887        if (watchUids != null) {
18888            Pair<Long, String> val = watchUids.get(proc.uid);
18889            if (val == null) {
18890                val = watchUids.get(0);
18891            }
18892            if (val != null) {
18893                check = val.first;
18894            }
18895        }
18896        if (check != null) {
18897            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18898                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18899                if (!isDebuggable) {
18900                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18901                        isDebuggable = true;
18902                    }
18903                }
18904                if (isDebuggable) {
18905                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18906                    final ProcessRecord myProc = proc;
18907                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18908                    mMemWatchDumpProcName = proc.processName;
18909                    mMemWatchDumpFile = heapdumpFile.toString();
18910                    mMemWatchDumpPid = proc.pid;
18911                    mMemWatchDumpUid = proc.uid;
18912                    BackgroundThread.getHandler().post(new Runnable() {
18913                        @Override
18914                        public void run() {
18915                            revokeUriPermission(ActivityThread.currentActivityThread()
18916                                            .getApplicationThread(),
18917                                    DumpHeapActivity.JAVA_URI,
18918                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18919                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18920                                    UserHandle.myUserId());
18921                            ParcelFileDescriptor fd = null;
18922                            try {
18923                                heapdumpFile.delete();
18924                                fd = ParcelFileDescriptor.open(heapdumpFile,
18925                                        ParcelFileDescriptor.MODE_CREATE |
18926                                                ParcelFileDescriptor.MODE_TRUNCATE |
18927                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18928                                                ParcelFileDescriptor.MODE_APPEND);
18929                                IApplicationThread thread = myProc.thread;
18930                                if (thread != null) {
18931                                    try {
18932                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18933                                                "Requesting dump heap from "
18934                                                + myProc + " to " + heapdumpFile);
18935                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18936                                    } catch (RemoteException e) {
18937                                    }
18938                                }
18939                            } catch (FileNotFoundException e) {
18940                                e.printStackTrace();
18941                            } finally {
18942                                if (fd != null) {
18943                                    try {
18944                                        fd.close();
18945                                    } catch (IOException e) {
18946                                    }
18947                                }
18948                            }
18949                        }
18950                    });
18951                } else {
18952                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18953                            + ", but debugging not enabled");
18954                }
18955            }
18956        }
18957    }
18958
18959    /**
18960     * Schedule PSS collection of a process.
18961     */
18962    void requestPssLocked(ProcessRecord proc, int procState) {
18963        if (mPendingPssProcesses.contains(proc)) {
18964            return;
18965        }
18966        if (mPendingPssProcesses.size() == 0) {
18967            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18968        }
18969        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18970        proc.pssProcState = procState;
18971        mPendingPssProcesses.add(proc);
18972    }
18973
18974    /**
18975     * Schedule PSS collection of all processes.
18976     */
18977    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18978        if (!always) {
18979            if (now < (mLastFullPssTime +
18980                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18981                return;
18982            }
18983        }
18984        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18985        mLastFullPssTime = now;
18986        mFullPssPending = true;
18987        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18988        mPendingPssProcesses.clear();
18989        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18990            ProcessRecord app = mLruProcesses.get(i);
18991            if (app.thread == null
18992                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18993                continue;
18994            }
18995            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18996                app.pssProcState = app.setProcState;
18997                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18998                        mTestPssMode, isSleeping(), now);
18999                mPendingPssProcesses.add(app);
19000            }
19001        }
19002        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19003    }
19004
19005    public void setTestPssMode(boolean enabled) {
19006        synchronized (this) {
19007            mTestPssMode = enabled;
19008            if (enabled) {
19009                // Whenever we enable the mode, we want to take a snapshot all of current
19010                // process mem use.
19011                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19012            }
19013        }
19014    }
19015
19016    /**
19017     * Ask a given process to GC right now.
19018     */
19019    final void performAppGcLocked(ProcessRecord app) {
19020        try {
19021            app.lastRequestedGc = SystemClock.uptimeMillis();
19022            if (app.thread != null) {
19023                if (app.reportLowMemory) {
19024                    app.reportLowMemory = false;
19025                    app.thread.scheduleLowMemory();
19026                } else {
19027                    app.thread.processInBackground();
19028                }
19029            }
19030        } catch (Exception e) {
19031            // whatever.
19032        }
19033    }
19034
19035    /**
19036     * Returns true if things are idle enough to perform GCs.
19037     */
19038    private final boolean canGcNowLocked() {
19039        boolean processingBroadcasts = false;
19040        for (BroadcastQueue q : mBroadcastQueues) {
19041            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19042                processingBroadcasts = true;
19043            }
19044        }
19045        return !processingBroadcasts
19046                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19047    }
19048
19049    /**
19050     * Perform GCs on all processes that are waiting for it, but only
19051     * if things are idle.
19052     */
19053    final void performAppGcsLocked() {
19054        final int N = mProcessesToGc.size();
19055        if (N <= 0) {
19056            return;
19057        }
19058        if (canGcNowLocked()) {
19059            while (mProcessesToGc.size() > 0) {
19060                ProcessRecord proc = mProcessesToGc.remove(0);
19061                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19062                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19063                            <= SystemClock.uptimeMillis()) {
19064                        // To avoid spamming the system, we will GC processes one
19065                        // at a time, waiting a few seconds between each.
19066                        performAppGcLocked(proc);
19067                        scheduleAppGcsLocked();
19068                        return;
19069                    } else {
19070                        // It hasn't been long enough since we last GCed this
19071                        // process...  put it in the list to wait for its time.
19072                        addProcessToGcListLocked(proc);
19073                        break;
19074                    }
19075                }
19076            }
19077
19078            scheduleAppGcsLocked();
19079        }
19080    }
19081
19082    /**
19083     * If all looks good, perform GCs on all processes waiting for them.
19084     */
19085    final void performAppGcsIfAppropriateLocked() {
19086        if (canGcNowLocked()) {
19087            performAppGcsLocked();
19088            return;
19089        }
19090        // Still not idle, wait some more.
19091        scheduleAppGcsLocked();
19092    }
19093
19094    /**
19095     * Schedule the execution of all pending app GCs.
19096     */
19097    final void scheduleAppGcsLocked() {
19098        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19099
19100        if (mProcessesToGc.size() > 0) {
19101            // Schedule a GC for the time to the next process.
19102            ProcessRecord proc = mProcessesToGc.get(0);
19103            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19104
19105            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19106            long now = SystemClock.uptimeMillis();
19107            if (when < (now+GC_TIMEOUT)) {
19108                when = now + GC_TIMEOUT;
19109            }
19110            mHandler.sendMessageAtTime(msg, when);
19111        }
19112    }
19113
19114    /**
19115     * Add a process to the array of processes waiting to be GCed.  Keeps the
19116     * list in sorted order by the last GC time.  The process can't already be
19117     * on the list.
19118     */
19119    final void addProcessToGcListLocked(ProcessRecord proc) {
19120        boolean added = false;
19121        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19122            if (mProcessesToGc.get(i).lastRequestedGc <
19123                    proc.lastRequestedGc) {
19124                added = true;
19125                mProcessesToGc.add(i+1, proc);
19126                break;
19127            }
19128        }
19129        if (!added) {
19130            mProcessesToGc.add(0, proc);
19131        }
19132    }
19133
19134    /**
19135     * Set up to ask a process to GC itself.  This will either do it
19136     * immediately, or put it on the list of processes to gc the next
19137     * time things are idle.
19138     */
19139    final void scheduleAppGcLocked(ProcessRecord app) {
19140        long now = SystemClock.uptimeMillis();
19141        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19142            return;
19143        }
19144        if (!mProcessesToGc.contains(app)) {
19145            addProcessToGcListLocked(app);
19146            scheduleAppGcsLocked();
19147        }
19148    }
19149
19150    final void checkExcessivePowerUsageLocked(boolean doKills) {
19151        updateCpuStatsNow();
19152
19153        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19154        boolean doWakeKills = doKills;
19155        boolean doCpuKills = doKills;
19156        if (mLastPowerCheckRealtime == 0) {
19157            doWakeKills = false;
19158        }
19159        if (mLastPowerCheckUptime == 0) {
19160            doCpuKills = false;
19161        }
19162        if (stats.isScreenOn()) {
19163            doWakeKills = false;
19164        }
19165        final long curRealtime = SystemClock.elapsedRealtime();
19166        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19167        final long curUptime = SystemClock.uptimeMillis();
19168        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19169        mLastPowerCheckRealtime = curRealtime;
19170        mLastPowerCheckUptime = curUptime;
19171        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19172            doWakeKills = false;
19173        }
19174        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19175            doCpuKills = false;
19176        }
19177        int i = mLruProcesses.size();
19178        while (i > 0) {
19179            i--;
19180            ProcessRecord app = mLruProcesses.get(i);
19181            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19182                long wtime;
19183                synchronized (stats) {
19184                    wtime = stats.getProcessWakeTime(app.info.uid,
19185                            app.pid, curRealtime);
19186                }
19187                long wtimeUsed = wtime - app.lastWakeTime;
19188                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19189                if (DEBUG_POWER) {
19190                    StringBuilder sb = new StringBuilder(128);
19191                    sb.append("Wake for ");
19192                    app.toShortString(sb);
19193                    sb.append(": over ");
19194                    TimeUtils.formatDuration(realtimeSince, sb);
19195                    sb.append(" used ");
19196                    TimeUtils.formatDuration(wtimeUsed, sb);
19197                    sb.append(" (");
19198                    sb.append((wtimeUsed*100)/realtimeSince);
19199                    sb.append("%)");
19200                    Slog.i(TAG_POWER, sb.toString());
19201                    sb.setLength(0);
19202                    sb.append("CPU for ");
19203                    app.toShortString(sb);
19204                    sb.append(": over ");
19205                    TimeUtils.formatDuration(uptimeSince, sb);
19206                    sb.append(" used ");
19207                    TimeUtils.formatDuration(cputimeUsed, sb);
19208                    sb.append(" (");
19209                    sb.append((cputimeUsed*100)/uptimeSince);
19210                    sb.append("%)");
19211                    Slog.i(TAG_POWER, sb.toString());
19212                }
19213                // If a process has held a wake lock for more
19214                // than 50% of the time during this period,
19215                // that sounds bad.  Kill!
19216                if (doWakeKills && realtimeSince > 0
19217                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19218                    synchronized (stats) {
19219                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19220                                realtimeSince, wtimeUsed);
19221                    }
19222                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19223                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19224                } else if (doCpuKills && uptimeSince > 0
19225                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19226                    synchronized (stats) {
19227                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19228                                uptimeSince, cputimeUsed);
19229                    }
19230                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19231                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19232                } else {
19233                    app.lastWakeTime = wtime;
19234                    app.lastCpuTime = app.curCpuTime;
19235                }
19236            }
19237        }
19238    }
19239
19240    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19241            long nowElapsed) {
19242        boolean success = true;
19243
19244        if (app.curRawAdj != app.setRawAdj) {
19245            app.setRawAdj = app.curRawAdj;
19246        }
19247
19248        int changes = 0;
19249
19250        if (app.curAdj != app.setAdj) {
19251            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19252            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19253                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19254                    + app.adjType);
19255            app.setAdj = app.curAdj;
19256        }
19257
19258        if (app.setSchedGroup != app.curSchedGroup) {
19259            app.setSchedGroup = app.curSchedGroup;
19260            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19261                    "Setting process group of " + app.processName
19262                    + " to " + app.curSchedGroup);
19263            if (app.waitingToKill != null && app.curReceiver == null
19264                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19265                app.kill(app.waitingToKill, true);
19266                success = false;
19267            } else {
19268                if (true) {
19269                    long oldId = Binder.clearCallingIdentity();
19270                    try {
19271                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19272                    } catch (Exception e) {
19273                        Slog.w(TAG, "Failed setting process group of " + app.pid
19274                                + " to " + app.curSchedGroup);
19275                        e.printStackTrace();
19276                    } finally {
19277                        Binder.restoreCallingIdentity(oldId);
19278                    }
19279                } else {
19280                    if (app.thread != null) {
19281                        try {
19282                            app.thread.setSchedulingGroup(app.curSchedGroup);
19283                        } catch (RemoteException e) {
19284                        }
19285                    }
19286                }
19287            }
19288        }
19289        if (app.repForegroundActivities != app.foregroundActivities) {
19290            app.repForegroundActivities = app.foregroundActivities;
19291            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19292        }
19293        if (app.repProcState != app.curProcState) {
19294            app.repProcState = app.curProcState;
19295            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19296            if (app.thread != null) {
19297                try {
19298                    if (false) {
19299                        //RuntimeException h = new RuntimeException("here");
19300                        Slog.i(TAG, "Sending new process state " + app.repProcState
19301                                + " to " + app /*, h*/);
19302                    }
19303                    app.thread.setProcessState(app.repProcState);
19304                } catch (RemoteException e) {
19305                }
19306            }
19307        }
19308        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19309                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19310            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19311                // Experimental code to more aggressively collect pss while
19312                // running test...  the problem is that this tends to collect
19313                // the data right when a process is transitioning between process
19314                // states, which well tend to give noisy data.
19315                long start = SystemClock.uptimeMillis();
19316                long pss = Debug.getPss(app.pid, mTmpLong, null);
19317                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19318                mPendingPssProcesses.remove(app);
19319                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19320                        + " to " + app.curProcState + ": "
19321                        + (SystemClock.uptimeMillis()-start) + "ms");
19322            }
19323            app.lastStateTime = now;
19324            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19325                    mTestPssMode, isSleeping(), now);
19326            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19327                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19328                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19329                    + (app.nextPssTime-now) + ": " + app);
19330        } else {
19331            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19332                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19333                    mTestPssMode)))) {
19334                requestPssLocked(app, app.setProcState);
19335                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19336                        mTestPssMode, isSleeping(), now);
19337            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19338                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19339        }
19340        if (app.setProcState != app.curProcState) {
19341            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19342                    "Proc state change of " + app.processName
19343                            + " to " + app.curProcState);
19344            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19345            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19346            if (setImportant && !curImportant) {
19347                // This app is no longer something we consider important enough to allow to
19348                // use arbitrary amounts of battery power.  Note
19349                // its current wake lock time to later know to kill it if
19350                // it is not behaving well.
19351                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19352                synchronized (stats) {
19353                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19354                            app.pid, nowElapsed);
19355                }
19356                app.lastCpuTime = app.curCpuTime;
19357
19358            }
19359            // Inform UsageStats of important process state change
19360            // Must be called before updating setProcState
19361            maybeUpdateUsageStatsLocked(app, nowElapsed);
19362
19363            app.setProcState = app.curProcState;
19364            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19365                app.notCachedSinceIdle = false;
19366            }
19367            if (!doingAll) {
19368                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19369            } else {
19370                app.procStateChanged = true;
19371            }
19372        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19373                > USAGE_STATS_INTERACTION_INTERVAL) {
19374            // For apps that sit around for a long time in the interactive state, we need
19375            // to report this at least once a day so they don't go idle.
19376            maybeUpdateUsageStatsLocked(app, nowElapsed);
19377        }
19378
19379        if (changes != 0) {
19380            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19381                    "Changes in " + app + ": " + changes);
19382            int i = mPendingProcessChanges.size()-1;
19383            ProcessChangeItem item = null;
19384            while (i >= 0) {
19385                item = mPendingProcessChanges.get(i);
19386                if (item.pid == app.pid) {
19387                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19388                            "Re-using existing item: " + item);
19389                    break;
19390                }
19391                i--;
19392            }
19393            if (i < 0) {
19394                // No existing item in pending changes; need a new one.
19395                final int NA = mAvailProcessChanges.size();
19396                if (NA > 0) {
19397                    item = mAvailProcessChanges.remove(NA-1);
19398                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19399                            "Retrieving available item: " + item);
19400                } else {
19401                    item = new ProcessChangeItem();
19402                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19403                            "Allocating new item: " + item);
19404                }
19405                item.changes = 0;
19406                item.pid = app.pid;
19407                item.uid = app.info.uid;
19408                if (mPendingProcessChanges.size() == 0) {
19409                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19410                            "*** Enqueueing dispatch processes changed!");
19411                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19412                }
19413                mPendingProcessChanges.add(item);
19414            }
19415            item.changes |= changes;
19416            item.processState = app.repProcState;
19417            item.foregroundActivities = app.repForegroundActivities;
19418            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19419                    "Item " + Integer.toHexString(System.identityHashCode(item))
19420                    + " " + app.toShortString() + ": changes=" + item.changes
19421                    + " procState=" + item.processState
19422                    + " foreground=" + item.foregroundActivities
19423                    + " type=" + app.adjType + " source=" + app.adjSource
19424                    + " target=" + app.adjTarget);
19425        }
19426
19427        return success;
19428    }
19429
19430    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19431        final UidRecord.ChangeItem pendingChange;
19432        if (uidRec == null || uidRec.pendingChange == null) {
19433            if (mPendingUidChanges.size() == 0) {
19434                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19435                        "*** Enqueueing dispatch uid changed!");
19436                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19437            }
19438            final int NA = mAvailUidChanges.size();
19439            if (NA > 0) {
19440                pendingChange = mAvailUidChanges.remove(NA-1);
19441                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19442                        "Retrieving available item: " + pendingChange);
19443            } else {
19444                pendingChange = new UidRecord.ChangeItem();
19445                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19446                        "Allocating new item: " + pendingChange);
19447            }
19448            if (uidRec != null) {
19449                uidRec.pendingChange = pendingChange;
19450                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19451                    // If this uid is going away, and we haven't yet reported it is gone,
19452                    // then do so now.
19453                    change = UidRecord.CHANGE_GONE_IDLE;
19454                }
19455            } else if (uid < 0) {
19456                throw new IllegalArgumentException("No UidRecord or uid");
19457            }
19458            pendingChange.uidRecord = uidRec;
19459            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19460            mPendingUidChanges.add(pendingChange);
19461        } else {
19462            pendingChange = uidRec.pendingChange;
19463            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19464                change = UidRecord.CHANGE_GONE_IDLE;
19465            }
19466        }
19467        pendingChange.change = change;
19468        pendingChange.processState = uidRec != null
19469                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19470    }
19471
19472    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19473            String authority) {
19474        if (app == null) return;
19475        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19476            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19477            if (userState == null) return;
19478            final long now = SystemClock.elapsedRealtime();
19479            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19480            if (lastReported == null || lastReported < now - 60 * 1000L) {
19481                mUsageStatsService.reportContentProviderUsage(
19482                        authority, providerPkgName, app.userId);
19483                userState.mProviderLastReportedFg.put(authority, now);
19484            }
19485        }
19486    }
19487
19488    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19489        if (DEBUG_USAGE_STATS) {
19490            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19491                    + "] state changes: old = " + app.setProcState + ", new = "
19492                    + app.curProcState);
19493        }
19494        if (mUsageStatsService == null) {
19495            return;
19496        }
19497        boolean isInteraction;
19498        // To avoid some abuse patterns, we are going to be careful about what we consider
19499        // to be an app interaction.  Being the top activity doesn't count while the display
19500        // is sleeping, nor do short foreground services.
19501        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19502            isInteraction = true;
19503            app.fgInteractionTime = 0;
19504        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19505            if (app.fgInteractionTime == 0) {
19506                app.fgInteractionTime = nowElapsed;
19507                isInteraction = false;
19508            } else {
19509                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19510            }
19511        } else {
19512            isInteraction = app.curProcState
19513                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19514            app.fgInteractionTime = 0;
19515        }
19516        if (isInteraction && (!app.reportedInteraction
19517                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19518            app.interactionEventTime = nowElapsed;
19519            String[] packages = app.getPackageList();
19520            if (packages != null) {
19521                for (int i = 0; i < packages.length; i++) {
19522                    mUsageStatsService.reportEvent(packages[i], app.userId,
19523                            UsageEvents.Event.SYSTEM_INTERACTION);
19524                }
19525            }
19526        }
19527        app.reportedInteraction = isInteraction;
19528        if (!isInteraction) {
19529            app.interactionEventTime = 0;
19530        }
19531    }
19532
19533    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19534        if (proc.thread != null) {
19535            if (proc.baseProcessTracker != null) {
19536                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19537            }
19538        }
19539    }
19540
19541    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19542            ProcessRecord TOP_APP, boolean doingAll, long now) {
19543        if (app.thread == null) {
19544            return false;
19545        }
19546
19547        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19548
19549        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19550    }
19551
19552    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19553            boolean oomAdj) {
19554        if (isForeground != proc.foregroundServices) {
19555            proc.foregroundServices = isForeground;
19556            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19557                    proc.info.uid);
19558            if (isForeground) {
19559                if (curProcs == null) {
19560                    curProcs = new ArrayList<ProcessRecord>();
19561                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19562                }
19563                if (!curProcs.contains(proc)) {
19564                    curProcs.add(proc);
19565                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19566                            proc.info.packageName, proc.info.uid);
19567                }
19568            } else {
19569                if (curProcs != null) {
19570                    if (curProcs.remove(proc)) {
19571                        mBatteryStatsService.noteEvent(
19572                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19573                                proc.info.packageName, proc.info.uid);
19574                        if (curProcs.size() <= 0) {
19575                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19576                        }
19577                    }
19578                }
19579            }
19580            if (oomAdj) {
19581                updateOomAdjLocked();
19582            }
19583        }
19584    }
19585
19586    private final ActivityRecord resumedAppLocked() {
19587        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19588        String pkg;
19589        int uid;
19590        if (act != null) {
19591            pkg = act.packageName;
19592            uid = act.info.applicationInfo.uid;
19593        } else {
19594            pkg = null;
19595            uid = -1;
19596        }
19597        // Has the UID or resumed package name changed?
19598        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19599                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19600            if (mCurResumedPackage != null) {
19601                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19602                        mCurResumedPackage, mCurResumedUid);
19603            }
19604            mCurResumedPackage = pkg;
19605            mCurResumedUid = uid;
19606            if (mCurResumedPackage != null) {
19607                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19608                        mCurResumedPackage, mCurResumedUid);
19609            }
19610        }
19611        return act;
19612    }
19613
19614    final boolean updateOomAdjLocked(ProcessRecord app) {
19615        final ActivityRecord TOP_ACT = resumedAppLocked();
19616        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19617        final boolean wasCached = app.cached;
19618
19619        mAdjSeq++;
19620
19621        // This is the desired cached adjusment we want to tell it to use.
19622        // If our app is currently cached, we know it, and that is it.  Otherwise,
19623        // we don't know it yet, and it needs to now be cached we will then
19624        // need to do a complete oom adj.
19625        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19626                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19627        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19628                SystemClock.uptimeMillis());
19629        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19630            // Changed to/from cached state, so apps after it in the LRU
19631            // list may also be changed.
19632            updateOomAdjLocked();
19633        }
19634        return success;
19635    }
19636
19637    final void updateOomAdjLocked() {
19638        final ActivityRecord TOP_ACT = resumedAppLocked();
19639        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19640        final long now = SystemClock.uptimeMillis();
19641        final long nowElapsed = SystemClock.elapsedRealtime();
19642        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19643        final int N = mLruProcesses.size();
19644
19645        if (false) {
19646            RuntimeException e = new RuntimeException();
19647            e.fillInStackTrace();
19648            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19649        }
19650
19651        // Reset state in all uid records.
19652        for (int i=mActiveUids.size()-1; i>=0; i--) {
19653            final UidRecord uidRec = mActiveUids.valueAt(i);
19654            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19655                    "Starting update of " + uidRec);
19656            uidRec.reset();
19657        }
19658
19659        mStackSupervisor.rankTaskLayersIfNeeded();
19660
19661        mAdjSeq++;
19662        mNewNumServiceProcs = 0;
19663        mNewNumAServiceProcs = 0;
19664
19665        final int emptyProcessLimit;
19666        final int cachedProcessLimit;
19667        if (mProcessLimit <= 0) {
19668            emptyProcessLimit = cachedProcessLimit = 0;
19669        } else if (mProcessLimit == 1) {
19670            emptyProcessLimit = 1;
19671            cachedProcessLimit = 0;
19672        } else {
19673            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19674            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19675        }
19676
19677        // Let's determine how many processes we have running vs.
19678        // how many slots we have for background processes; we may want
19679        // to put multiple processes in a slot of there are enough of
19680        // them.
19681        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19682                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19683        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19684        if (numEmptyProcs > cachedProcessLimit) {
19685            // If there are more empty processes than our limit on cached
19686            // processes, then use the cached process limit for the factor.
19687            // This ensures that the really old empty processes get pushed
19688            // down to the bottom, so if we are running low on memory we will
19689            // have a better chance at keeping around more cached processes
19690            // instead of a gazillion empty processes.
19691            numEmptyProcs = cachedProcessLimit;
19692        }
19693        int emptyFactor = numEmptyProcs/numSlots;
19694        if (emptyFactor < 1) emptyFactor = 1;
19695        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19696        if (cachedFactor < 1) cachedFactor = 1;
19697        int stepCached = 0;
19698        int stepEmpty = 0;
19699        int numCached = 0;
19700        int numEmpty = 0;
19701        int numTrimming = 0;
19702
19703        mNumNonCachedProcs = 0;
19704        mNumCachedHiddenProcs = 0;
19705
19706        // First update the OOM adjustment for each of the
19707        // application processes based on their current state.
19708        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19709        int nextCachedAdj = curCachedAdj+1;
19710        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19711        int nextEmptyAdj = curEmptyAdj+2;
19712        for (int i=N-1; i>=0; i--) {
19713            ProcessRecord app = mLruProcesses.get(i);
19714            if (!app.killedByAm && app.thread != null) {
19715                app.procStateChanged = false;
19716                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19717
19718                // If we haven't yet assigned the final cached adj
19719                // to the process, do that now.
19720                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19721                    switch (app.curProcState) {
19722                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19723                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19724                            // This process is a cached process holding activities...
19725                            // assign it the next cached value for that type, and then
19726                            // step that cached level.
19727                            app.curRawAdj = curCachedAdj;
19728                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19729                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19730                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19731                                    + ")");
19732                            if (curCachedAdj != nextCachedAdj) {
19733                                stepCached++;
19734                                if (stepCached >= cachedFactor) {
19735                                    stepCached = 0;
19736                                    curCachedAdj = nextCachedAdj;
19737                                    nextCachedAdj += 2;
19738                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19739                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19740                                    }
19741                                }
19742                            }
19743                            break;
19744                        default:
19745                            // For everything else, assign next empty cached process
19746                            // level and bump that up.  Note that this means that
19747                            // long-running services that have dropped down to the
19748                            // cached level will be treated as empty (since their process
19749                            // state is still as a service), which is what we want.
19750                            app.curRawAdj = curEmptyAdj;
19751                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19752                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19753                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19754                                    + ")");
19755                            if (curEmptyAdj != nextEmptyAdj) {
19756                                stepEmpty++;
19757                                if (stepEmpty >= emptyFactor) {
19758                                    stepEmpty = 0;
19759                                    curEmptyAdj = nextEmptyAdj;
19760                                    nextEmptyAdj += 2;
19761                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19762                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19763                                    }
19764                                }
19765                            }
19766                            break;
19767                    }
19768                }
19769
19770                applyOomAdjLocked(app, true, now, nowElapsed);
19771
19772                // Count the number of process types.
19773                switch (app.curProcState) {
19774                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19775                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19776                        mNumCachedHiddenProcs++;
19777                        numCached++;
19778                        if (numCached > cachedProcessLimit) {
19779                            app.kill("cached #" + numCached, true);
19780                        }
19781                        break;
19782                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19783                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19784                                && app.lastActivityTime < oldTime) {
19785                            app.kill("empty for "
19786                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19787                                    / 1000) + "s", true);
19788                        } else {
19789                            numEmpty++;
19790                            if (numEmpty > emptyProcessLimit) {
19791                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19792                            }
19793                        }
19794                        break;
19795                    default:
19796                        mNumNonCachedProcs++;
19797                        break;
19798                }
19799
19800                if (app.isolated && app.services.size() <= 0) {
19801                    // If this is an isolated process, and there are no
19802                    // services running in it, then the process is no longer
19803                    // needed.  We agressively kill these because we can by
19804                    // definition not re-use the same process again, and it is
19805                    // good to avoid having whatever code was running in them
19806                    // left sitting around after no longer needed.
19807                    app.kill("isolated not needed", true);
19808                } else {
19809                    // Keeping this process, update its uid.
19810                    final UidRecord uidRec = app.uidRecord;
19811                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19812                        uidRec.curProcState = app.curProcState;
19813                    }
19814                }
19815
19816                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19817                        && !app.killedByAm) {
19818                    numTrimming++;
19819                }
19820            }
19821        }
19822
19823        mNumServiceProcs = mNewNumServiceProcs;
19824
19825        // Now determine the memory trimming level of background processes.
19826        // Unfortunately we need to start at the back of the list to do this
19827        // properly.  We only do this if the number of background apps we
19828        // are managing to keep around is less than half the maximum we desire;
19829        // if we are keeping a good number around, we'll let them use whatever
19830        // memory they want.
19831        final int numCachedAndEmpty = numCached + numEmpty;
19832        int memFactor;
19833        if (numCached <= ProcessList.TRIM_CACHED_APPS
19834                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19835            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19836                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19837            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19838                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19839            } else {
19840                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19841            }
19842        } else {
19843            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19844        }
19845        // We always allow the memory level to go up (better).  We only allow it to go
19846        // down if we are in a state where that is allowed, *and* the total number of processes
19847        // has gone down since last time.
19848        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19849                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19850                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19851        if (memFactor > mLastMemoryLevel) {
19852            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19853                memFactor = mLastMemoryLevel;
19854                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19855            }
19856        }
19857        mLastMemoryLevel = memFactor;
19858        mLastNumProcesses = mLruProcesses.size();
19859        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19860        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19861        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19862            if (mLowRamStartTime == 0) {
19863                mLowRamStartTime = now;
19864            }
19865            int step = 0;
19866            int fgTrimLevel;
19867            switch (memFactor) {
19868                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19869                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19870                    break;
19871                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19872                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19873                    break;
19874                default:
19875                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19876                    break;
19877            }
19878            int factor = numTrimming/3;
19879            int minFactor = 2;
19880            if (mHomeProcess != null) minFactor++;
19881            if (mPreviousProcess != null) minFactor++;
19882            if (factor < minFactor) factor = minFactor;
19883            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19884            for (int i=N-1; i>=0; i--) {
19885                ProcessRecord app = mLruProcesses.get(i);
19886                if (allChanged || app.procStateChanged) {
19887                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19888                    app.procStateChanged = false;
19889                }
19890                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19891                        && !app.killedByAm) {
19892                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19893                        try {
19894                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19895                                    "Trimming memory of " + app.processName + " to " + curLevel);
19896                            app.thread.scheduleTrimMemory(curLevel);
19897                        } catch (RemoteException e) {
19898                        }
19899                        if (false) {
19900                            // For now we won't do this; our memory trimming seems
19901                            // to be good enough at this point that destroying
19902                            // activities causes more harm than good.
19903                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19904                                    && app != mHomeProcess && app != mPreviousProcess) {
19905                                // Need to do this on its own message because the stack may not
19906                                // be in a consistent state at this point.
19907                                // For these apps we will also finish their activities
19908                                // to help them free memory.
19909                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19910                            }
19911                        }
19912                    }
19913                    app.trimMemoryLevel = curLevel;
19914                    step++;
19915                    if (step >= factor) {
19916                        step = 0;
19917                        switch (curLevel) {
19918                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19919                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19920                                break;
19921                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19922                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19923                                break;
19924                        }
19925                    }
19926                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19927                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19928                            && app.thread != null) {
19929                        try {
19930                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19931                                    "Trimming memory of heavy-weight " + app.processName
19932                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19933                            app.thread.scheduleTrimMemory(
19934                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19935                        } catch (RemoteException e) {
19936                        }
19937                    }
19938                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19939                } else {
19940                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19941                            || app.systemNoUi) && app.pendingUiClean) {
19942                        // If this application is now in the background and it
19943                        // had done UI, then give it the special trim level to
19944                        // have it free UI resources.
19945                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19946                        if (app.trimMemoryLevel < level && app.thread != null) {
19947                            try {
19948                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19949                                        "Trimming memory of bg-ui " + app.processName
19950                                        + " to " + level);
19951                                app.thread.scheduleTrimMemory(level);
19952                            } catch (RemoteException e) {
19953                            }
19954                        }
19955                        app.pendingUiClean = false;
19956                    }
19957                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19958                        try {
19959                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19960                                    "Trimming memory of fg " + app.processName
19961                                    + " to " + fgTrimLevel);
19962                            app.thread.scheduleTrimMemory(fgTrimLevel);
19963                        } catch (RemoteException e) {
19964                        }
19965                    }
19966                    app.trimMemoryLevel = fgTrimLevel;
19967                }
19968            }
19969        } else {
19970            if (mLowRamStartTime != 0) {
19971                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19972                mLowRamStartTime = 0;
19973            }
19974            for (int i=N-1; i>=0; i--) {
19975                ProcessRecord app = mLruProcesses.get(i);
19976                if (allChanged || app.procStateChanged) {
19977                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19978                    app.procStateChanged = false;
19979                }
19980                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19981                        || app.systemNoUi) && app.pendingUiClean) {
19982                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19983                            && app.thread != null) {
19984                        try {
19985                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19986                                    "Trimming memory of ui hidden " + app.processName
19987                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19988                            app.thread.scheduleTrimMemory(
19989                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19990                        } catch (RemoteException e) {
19991                        }
19992                    }
19993                    app.pendingUiClean = false;
19994                }
19995                app.trimMemoryLevel = 0;
19996            }
19997        }
19998
19999        if (mAlwaysFinishActivities) {
20000            // Need to do this on its own message because the stack may not
20001            // be in a consistent state at this point.
20002            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20003        }
20004
20005        if (allChanged) {
20006            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20007        }
20008
20009        // Update from any uid changes.
20010        for (int i=mActiveUids.size()-1; i>=0; i--) {
20011            final UidRecord uidRec = mActiveUids.valueAt(i);
20012            int uidChange = UidRecord.CHANGE_PROCSTATE;
20013            if (uidRec.setProcState != uidRec.curProcState) {
20014                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20015                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20016                        + " to " + uidRec.curProcState);
20017                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20018                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20019                        uidRec.lastBackgroundTime = nowElapsed;
20020                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20021                            // Note: the background settle time is in elapsed realtime, while
20022                            // the handler time base is uptime.  All this means is that we may
20023                            // stop background uids later than we had intended, but that only
20024                            // happens because the device was sleeping so we are okay anyway.
20025                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20026                        }
20027                    }
20028                } else {
20029                    if (uidRec.idle) {
20030                        uidChange = UidRecord.CHANGE_ACTIVE;
20031                        uidRec.idle = false;
20032                    }
20033                    uidRec.lastBackgroundTime = 0;
20034                }
20035                uidRec.setProcState = uidRec.curProcState;
20036                enqueueUidChangeLocked(uidRec, -1, uidChange);
20037                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20038            }
20039        }
20040
20041        if (mProcessStats.shouldWriteNowLocked(now)) {
20042            mHandler.post(new Runnable() {
20043                @Override public void run() {
20044                    synchronized (ActivityManagerService.this) {
20045                        mProcessStats.writeStateAsyncLocked();
20046                    }
20047                }
20048            });
20049        }
20050
20051        if (DEBUG_OOM_ADJ) {
20052            final long duration = SystemClock.uptimeMillis() - now;
20053            if (false) {
20054                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20055                        new RuntimeException("here").fillInStackTrace());
20056            } else {
20057                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20058            }
20059        }
20060    }
20061
20062    final void idleUids() {
20063        synchronized (this) {
20064            final long nowElapsed = SystemClock.elapsedRealtime();
20065            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20066            long nextTime = 0;
20067            for (int i=mActiveUids.size()-1; i>=0; i--) {
20068                final UidRecord uidRec = mActiveUids.valueAt(i);
20069                final long bgTime = uidRec.lastBackgroundTime;
20070                if (bgTime > 0 && !uidRec.idle) {
20071                    if (bgTime <= maxBgTime) {
20072                        uidRec.idle = true;
20073                        doStopUidLocked(uidRec.uid, uidRec);
20074                    } else {
20075                        if (nextTime == 0 || nextTime > bgTime) {
20076                            nextTime = bgTime;
20077                        }
20078                    }
20079                }
20080            }
20081            if (nextTime > 0) {
20082                mHandler.removeMessages(IDLE_UIDS_MSG);
20083                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20084                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20085            }
20086        }
20087    }
20088
20089    final void runInBackgroundDisabled(int uid) {
20090        synchronized (this) {
20091            UidRecord uidRec = mActiveUids.get(uid);
20092            if (uidRec != null) {
20093                // This uid is actually running...  should it be considered background now?
20094                if (uidRec.idle) {
20095                    doStopUidLocked(uidRec.uid, uidRec);
20096                }
20097            } else {
20098                // This uid isn't actually running...  still send a report about it being "stopped".
20099                doStopUidLocked(uid, null);
20100            }
20101        }
20102    }
20103
20104    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20105        mServices.stopInBackgroundLocked(uid);
20106        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20107    }
20108
20109    final void trimApplications() {
20110        synchronized (this) {
20111            int i;
20112
20113            // First remove any unused application processes whose package
20114            // has been removed.
20115            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20116                final ProcessRecord app = mRemovedProcesses.get(i);
20117                if (app.activities.size() == 0
20118                        && app.curReceiver == null && app.services.size() == 0) {
20119                    Slog.i(
20120                        TAG, "Exiting empty application process "
20121                        + app.processName + " ("
20122                        + (app.thread != null ? app.thread.asBinder() : null)
20123                        + ")\n");
20124                    if (app.pid > 0 && app.pid != MY_PID) {
20125                        app.kill("empty", false);
20126                    } else {
20127                        try {
20128                            app.thread.scheduleExit();
20129                        } catch (Exception e) {
20130                            // Ignore exceptions.
20131                        }
20132                    }
20133                    cleanUpApplicationRecordLocked(app, false, true, -1);
20134                    mRemovedProcesses.remove(i);
20135
20136                    if (app.persistent) {
20137                        addAppLocked(app.info, false, null /* ABI override */);
20138                    }
20139                }
20140            }
20141
20142            // Now update the oom adj for all processes.
20143            updateOomAdjLocked();
20144        }
20145    }
20146
20147    /** This method sends the specified signal to each of the persistent apps */
20148    public void signalPersistentProcesses(int sig) throws RemoteException {
20149        if (sig != Process.SIGNAL_USR1) {
20150            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20151        }
20152
20153        synchronized (this) {
20154            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20155                    != PackageManager.PERMISSION_GRANTED) {
20156                throw new SecurityException("Requires permission "
20157                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20158            }
20159
20160            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20161                ProcessRecord r = mLruProcesses.get(i);
20162                if (r.thread != null && r.persistent) {
20163                    Process.sendSignal(r.pid, sig);
20164                }
20165            }
20166        }
20167    }
20168
20169    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20170        if (proc == null || proc == mProfileProc) {
20171            proc = mProfileProc;
20172            profileType = mProfileType;
20173            clearProfilerLocked();
20174        }
20175        if (proc == null) {
20176            return;
20177        }
20178        try {
20179            proc.thread.profilerControl(false, null, profileType);
20180        } catch (RemoteException e) {
20181            throw new IllegalStateException("Process disappeared");
20182        }
20183    }
20184
20185    private void clearProfilerLocked() {
20186        if (mProfileFd != null) {
20187            try {
20188                mProfileFd.close();
20189            } catch (IOException e) {
20190            }
20191        }
20192        mProfileApp = null;
20193        mProfileProc = null;
20194        mProfileFile = null;
20195        mProfileType = 0;
20196        mAutoStopProfiler = false;
20197        mSamplingInterval = 0;
20198    }
20199
20200    public boolean profileControl(String process, int userId, boolean start,
20201            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20202
20203        try {
20204            synchronized (this) {
20205                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20206                // its own permission.
20207                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20208                        != PackageManager.PERMISSION_GRANTED) {
20209                    throw new SecurityException("Requires permission "
20210                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20211                }
20212
20213                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20214                    throw new IllegalArgumentException("null profile info or fd");
20215                }
20216
20217                ProcessRecord proc = null;
20218                if (process != null) {
20219                    proc = findProcessLocked(process, userId, "profileControl");
20220                }
20221
20222                if (start && (proc == null || proc.thread == null)) {
20223                    throw new IllegalArgumentException("Unknown process: " + process);
20224                }
20225
20226                if (start) {
20227                    stopProfilerLocked(null, 0);
20228                    setProfileApp(proc.info, proc.processName, profilerInfo);
20229                    mProfileProc = proc;
20230                    mProfileType = profileType;
20231                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20232                    try {
20233                        fd = fd.dup();
20234                    } catch (IOException e) {
20235                        fd = null;
20236                    }
20237                    profilerInfo.profileFd = fd;
20238                    proc.thread.profilerControl(start, profilerInfo, profileType);
20239                    fd = null;
20240                    mProfileFd = null;
20241                } else {
20242                    stopProfilerLocked(proc, profileType);
20243                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20244                        try {
20245                            profilerInfo.profileFd.close();
20246                        } catch (IOException e) {
20247                        }
20248                    }
20249                }
20250
20251                return true;
20252            }
20253        } catch (RemoteException e) {
20254            throw new IllegalStateException("Process disappeared");
20255        } finally {
20256            if (profilerInfo != null && profilerInfo.profileFd != null) {
20257                try {
20258                    profilerInfo.profileFd.close();
20259                } catch (IOException e) {
20260                }
20261            }
20262        }
20263    }
20264
20265    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20266        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20267                userId, true, ALLOW_FULL_ONLY, callName, null);
20268        ProcessRecord proc = null;
20269        try {
20270            int pid = Integer.parseInt(process);
20271            synchronized (mPidsSelfLocked) {
20272                proc = mPidsSelfLocked.get(pid);
20273            }
20274        } catch (NumberFormatException e) {
20275        }
20276
20277        if (proc == null) {
20278            ArrayMap<String, SparseArray<ProcessRecord>> all
20279                    = mProcessNames.getMap();
20280            SparseArray<ProcessRecord> procs = all.get(process);
20281            if (procs != null && procs.size() > 0) {
20282                proc = procs.valueAt(0);
20283                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20284                    for (int i=1; i<procs.size(); i++) {
20285                        ProcessRecord thisProc = procs.valueAt(i);
20286                        if (thisProc.userId == userId) {
20287                            proc = thisProc;
20288                            break;
20289                        }
20290                    }
20291                }
20292            }
20293        }
20294
20295        return proc;
20296    }
20297
20298    public boolean dumpHeap(String process, int userId, boolean managed,
20299            String path, ParcelFileDescriptor fd) throws RemoteException {
20300
20301        try {
20302            synchronized (this) {
20303                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20304                // its own permission (same as profileControl).
20305                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20306                        != PackageManager.PERMISSION_GRANTED) {
20307                    throw new SecurityException("Requires permission "
20308                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20309                }
20310
20311                if (fd == null) {
20312                    throw new IllegalArgumentException("null fd");
20313                }
20314
20315                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20316                if (proc == null || proc.thread == null) {
20317                    throw new IllegalArgumentException("Unknown process: " + process);
20318                }
20319
20320                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20321                if (!isDebuggable) {
20322                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20323                        throw new SecurityException("Process not debuggable: " + proc);
20324                    }
20325                }
20326
20327                proc.thread.dumpHeap(managed, path, fd);
20328                fd = null;
20329                return true;
20330            }
20331        } catch (RemoteException e) {
20332            throw new IllegalStateException("Process disappeared");
20333        } finally {
20334            if (fd != null) {
20335                try {
20336                    fd.close();
20337                } catch (IOException e) {
20338                }
20339            }
20340        }
20341    }
20342
20343    @Override
20344    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20345            String reportPackage) {
20346        if (processName != null) {
20347            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20348                    "setDumpHeapDebugLimit()");
20349        } else {
20350            synchronized (mPidsSelfLocked) {
20351                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20352                if (proc == null) {
20353                    throw new SecurityException("No process found for calling pid "
20354                            + Binder.getCallingPid());
20355                }
20356                if (!Build.IS_DEBUGGABLE
20357                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20358                    throw new SecurityException("Not running a debuggable build");
20359                }
20360                processName = proc.processName;
20361                uid = proc.uid;
20362                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20363                    throw new SecurityException("Package " + reportPackage + " is not running in "
20364                            + proc);
20365                }
20366            }
20367        }
20368        synchronized (this) {
20369            if (maxMemSize > 0) {
20370                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20371            } else {
20372                if (uid != 0) {
20373                    mMemWatchProcesses.remove(processName, uid);
20374                } else {
20375                    mMemWatchProcesses.getMap().remove(processName);
20376                }
20377            }
20378        }
20379    }
20380
20381    @Override
20382    public void dumpHeapFinished(String path) {
20383        synchronized (this) {
20384            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20385                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20386                        + " does not match last pid " + mMemWatchDumpPid);
20387                return;
20388            }
20389            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20390                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20391                        + " does not match last path " + mMemWatchDumpFile);
20392                return;
20393            }
20394            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20395            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20396        }
20397    }
20398
20399    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20400    public void monitor() {
20401        synchronized (this) { }
20402    }
20403
20404    void onCoreSettingsChange(Bundle settings) {
20405        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20406            ProcessRecord processRecord = mLruProcesses.get(i);
20407            try {
20408                if (processRecord.thread != null) {
20409                    processRecord.thread.setCoreSettings(settings);
20410                }
20411            } catch (RemoteException re) {
20412                /* ignore */
20413            }
20414        }
20415    }
20416
20417    // Multi-user methods
20418
20419    /**
20420     * Start user, if its not already running, but don't bring it to foreground.
20421     */
20422    @Override
20423    public boolean startUserInBackground(final int userId) {
20424        return mUserController.startUser(userId, /* foreground */ false);
20425    }
20426
20427    @Override
20428    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20429        return mUserController.unlockUser(userId, token, secret);
20430    }
20431
20432    @Override
20433    public boolean switchUser(final int targetUserId) {
20434        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20435        UserInfo currentUserInfo;
20436        UserInfo targetUserInfo;
20437        synchronized (this) {
20438            int currentUserId = mUserController.getCurrentUserIdLocked();
20439            currentUserInfo = mUserController.getUserInfo(currentUserId);
20440            targetUserInfo = mUserController.getUserInfo(targetUserId);
20441            if (targetUserInfo == null) {
20442                Slog.w(TAG, "No user info for user #" + targetUserId);
20443                return false;
20444            }
20445            if (targetUserInfo.isManagedProfile()) {
20446                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20447                return false;
20448            }
20449            mUserController.setTargetUserIdLocked(targetUserId);
20450        }
20451        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20452        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20453        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20454        return true;
20455    }
20456
20457    void scheduleStartProfilesLocked() {
20458        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20459            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20460                    DateUtils.SECOND_IN_MILLIS);
20461        }
20462    }
20463
20464    @Override
20465    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20466        return mUserController.stopUser(userId, force, callback);
20467    }
20468
20469    @Override
20470    public UserInfo getCurrentUser() {
20471        return mUserController.getCurrentUser();
20472    }
20473
20474    @Override
20475    public boolean isUserRunning(int userId, int flags) {
20476        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20477                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20478            String msg = "Permission Denial: isUserRunning() from pid="
20479                    + Binder.getCallingPid()
20480                    + ", uid=" + Binder.getCallingUid()
20481                    + " requires " + INTERACT_ACROSS_USERS;
20482            Slog.w(TAG, msg);
20483            throw new SecurityException(msg);
20484        }
20485        synchronized (this) {
20486            return mUserController.isUserRunningLocked(userId, flags);
20487        }
20488    }
20489
20490    @Override
20491    public int[] getRunningUserIds() {
20492        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20493                != PackageManager.PERMISSION_GRANTED) {
20494            String msg = "Permission Denial: isUserRunning() from pid="
20495                    + Binder.getCallingPid()
20496                    + ", uid=" + Binder.getCallingUid()
20497                    + " requires " + INTERACT_ACROSS_USERS;
20498            Slog.w(TAG, msg);
20499            throw new SecurityException(msg);
20500        }
20501        synchronized (this) {
20502            return mUserController.getStartedUserArrayLocked();
20503        }
20504    }
20505
20506    @Override
20507    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20508        mUserController.registerUserSwitchObserver(observer);
20509    }
20510
20511    @Override
20512    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20513        mUserController.unregisterUserSwitchObserver(observer);
20514    }
20515
20516    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20517        if (info == null) return null;
20518        ApplicationInfo newInfo = new ApplicationInfo(info);
20519        newInfo.initForUser(userId);
20520        return newInfo;
20521    }
20522
20523    public boolean isUserStopped(int userId) {
20524        synchronized (this) {
20525            return mUserController.getStartedUserStateLocked(userId) == null;
20526        }
20527    }
20528
20529    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20530        if (aInfo == null
20531                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20532            return aInfo;
20533        }
20534
20535        ActivityInfo info = new ActivityInfo(aInfo);
20536        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20537        return info;
20538    }
20539
20540    private boolean processSanityChecksLocked(ProcessRecord process) {
20541        if (process == null || process.thread == null) {
20542            return false;
20543        }
20544
20545        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20546        if (!isDebuggable) {
20547            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20548                return false;
20549            }
20550        }
20551
20552        return true;
20553    }
20554
20555    public boolean startBinderTracking() throws RemoteException {
20556        synchronized (this) {
20557            mBinderTransactionTrackingEnabled = true;
20558            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20559            // permission (same as profileControl).
20560            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20561                    != PackageManager.PERMISSION_GRANTED) {
20562                throw new SecurityException("Requires permission "
20563                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20564            }
20565
20566            for (int i = 0; i < mLruProcesses.size(); i++) {
20567                ProcessRecord process = mLruProcesses.get(i);
20568                if (!processSanityChecksLocked(process)) {
20569                    continue;
20570                }
20571                try {
20572                    process.thread.startBinderTracking();
20573                } catch (RemoteException e) {
20574                    Log.v(TAG, "Process disappared");
20575                }
20576            }
20577            return true;
20578        }
20579    }
20580
20581    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20582        try {
20583            synchronized (this) {
20584                mBinderTransactionTrackingEnabled = false;
20585                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20586                // permission (same as profileControl).
20587                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20588                        != PackageManager.PERMISSION_GRANTED) {
20589                    throw new SecurityException("Requires permission "
20590                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20591                }
20592
20593                if (fd == null) {
20594                    throw new IllegalArgumentException("null fd");
20595                }
20596
20597                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20598                pw.println("Binder transaction traces for all processes.\n");
20599                for (ProcessRecord process : mLruProcesses) {
20600                    if (!processSanityChecksLocked(process)) {
20601                        continue;
20602                    }
20603
20604                    pw.println("Traces for process: " + process.processName);
20605                    pw.flush();
20606                    try {
20607                        TransferPipe tp = new TransferPipe();
20608                        try {
20609                            process.thread.stopBinderTrackingAndDump(
20610                                    tp.getWriteFd().getFileDescriptor());
20611                            tp.go(fd.getFileDescriptor());
20612                        } finally {
20613                            tp.kill();
20614                        }
20615                    } catch (IOException e) {
20616                        pw.println("Failure while dumping IPC traces from " + process +
20617                                ".  Exception: " + e);
20618                        pw.flush();
20619                    } catch (RemoteException e) {
20620                        pw.println("Got a RemoteException while dumping IPC traces from " +
20621                                process + ".  Exception: " + e);
20622                        pw.flush();
20623                    }
20624                }
20625                fd = null;
20626                return true;
20627            }
20628        } finally {
20629            if (fd != null) {
20630                try {
20631                    fd.close();
20632                } catch (IOException e) {
20633                }
20634            }
20635        }
20636    }
20637
20638    private final class LocalService extends ActivityManagerInternal {
20639        @Override
20640        public void onWakefulnessChanged(int wakefulness) {
20641            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20642        }
20643
20644        @Override
20645        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20646                String processName, String abiOverride, int uid, Runnable crashHandler) {
20647            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20648                    processName, abiOverride, uid, crashHandler);
20649        }
20650
20651        @Override
20652        public SleepToken acquireSleepToken(String tag) {
20653            Preconditions.checkNotNull(tag);
20654
20655            synchronized (ActivityManagerService.this) {
20656                SleepTokenImpl token = new SleepTokenImpl(tag);
20657                mSleepTokens.add(token);
20658                updateSleepIfNeededLocked();
20659                return token;
20660            }
20661        }
20662
20663        @Override
20664        public ComponentName getHomeActivityForUser(int userId) {
20665            synchronized (ActivityManagerService.this) {
20666                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20667                return homeActivity == null ? null : homeActivity.realActivity;
20668            }
20669        }
20670
20671        @Override
20672        public void onUserRemoved(int userId) {
20673            synchronized (ActivityManagerService.this) {
20674                ActivityManagerService.this.onUserStoppedLocked(userId);
20675            }
20676        }
20677
20678        @Override
20679        public void onLocalVoiceInteractionStarted(IBinder activity,
20680                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20681            synchronized (ActivityManagerService.this) {
20682                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20683                        voiceSession, voiceInteractor);
20684            }
20685        }
20686    }
20687
20688    private final class SleepTokenImpl extends SleepToken {
20689        private final String mTag;
20690        private final long mAcquireTime;
20691
20692        public SleepTokenImpl(String tag) {
20693            mTag = tag;
20694            mAcquireTime = SystemClock.uptimeMillis();
20695        }
20696
20697        @Override
20698        public void release() {
20699            synchronized (ActivityManagerService.this) {
20700                if (mSleepTokens.remove(this)) {
20701                    updateSleepIfNeededLocked();
20702                }
20703            }
20704        }
20705
20706        @Override
20707        public String toString() {
20708            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20709        }
20710    }
20711
20712    /**
20713     * An implementation of IAppTask, that allows an app to manage its own tasks via
20714     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20715     * only the process that calls getAppTasks() can call the AppTask methods.
20716     */
20717    class AppTaskImpl extends IAppTask.Stub {
20718        private int mTaskId;
20719        private int mCallingUid;
20720
20721        public AppTaskImpl(int taskId, int callingUid) {
20722            mTaskId = taskId;
20723            mCallingUid = callingUid;
20724        }
20725
20726        private void checkCaller() {
20727            if (mCallingUid != Binder.getCallingUid()) {
20728                throw new SecurityException("Caller " + mCallingUid
20729                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20730            }
20731        }
20732
20733        @Override
20734        public void finishAndRemoveTask() {
20735            checkCaller();
20736
20737            synchronized (ActivityManagerService.this) {
20738                long origId = Binder.clearCallingIdentity();
20739                try {
20740                    // We remove the task from recents to preserve backwards
20741                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20742                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20743                    }
20744                } finally {
20745                    Binder.restoreCallingIdentity(origId);
20746                }
20747            }
20748        }
20749
20750        @Override
20751        public ActivityManager.RecentTaskInfo getTaskInfo() {
20752            checkCaller();
20753
20754            synchronized (ActivityManagerService.this) {
20755                long origId = Binder.clearCallingIdentity();
20756                try {
20757                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20758                    if (tr == null) {
20759                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20760                    }
20761                    return createRecentTaskInfoFromTaskRecord(tr);
20762                } finally {
20763                    Binder.restoreCallingIdentity(origId);
20764                }
20765            }
20766        }
20767
20768        @Override
20769        public void moveToFront() {
20770            checkCaller();
20771            // Will bring task to front if it already has a root activity.
20772            final long origId = Binder.clearCallingIdentity();
20773            try {
20774                startActivityFromRecentsInner(mTaskId, null);
20775            } finally {
20776                Binder.restoreCallingIdentity(origId);
20777            }
20778        }
20779
20780        @Override
20781        public int startActivity(IBinder whoThread, String callingPackage,
20782                Intent intent, String resolvedType, Bundle bOptions) {
20783            checkCaller();
20784
20785            int callingUser = UserHandle.getCallingUserId();
20786            TaskRecord tr;
20787            IApplicationThread appThread;
20788            synchronized (ActivityManagerService.this) {
20789                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20790                if (tr == null) {
20791                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20792                }
20793                appThread = ApplicationThreadNative.asInterface(whoThread);
20794                if (appThread == null) {
20795                    throw new IllegalArgumentException("Bad app thread " + appThread);
20796                }
20797            }
20798            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20799                    resolvedType, null, null, null, null, 0, 0, null, null,
20800                    null, bOptions, false, callingUser, null, tr);
20801        }
20802
20803        @Override
20804        public void setExcludeFromRecents(boolean exclude) {
20805            checkCaller();
20806
20807            synchronized (ActivityManagerService.this) {
20808                long origId = Binder.clearCallingIdentity();
20809                try {
20810                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20811                    if (tr == null) {
20812                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20813                    }
20814                    Intent intent = tr.getBaseIntent();
20815                    if (exclude) {
20816                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20817                    } else {
20818                        intent.setFlags(intent.getFlags()
20819                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20820                    }
20821                } finally {
20822                    Binder.restoreCallingIdentity(origId);
20823                }
20824            }
20825        }
20826    }
20827
20828    /**
20829     * Kill processes for the user with id userId and that depend on the package named packageName
20830     */
20831    @Override
20832    public void killPackageDependents(String packageName, int userId) {
20833        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20834        if (packageName == null) {
20835            throw new NullPointerException(
20836                    "Cannot kill the dependents of a package without its name.");
20837        }
20838
20839        long callingId = Binder.clearCallingIdentity();
20840        IPackageManager pm = AppGlobals.getPackageManager();
20841        int pkgUid = -1;
20842        try {
20843            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20844        } catch (RemoteException e) {
20845        }
20846        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
20847            throw new IllegalArgumentException(
20848                    "Cannot kill dependents of non-existing package " + packageName);
20849        }
20850        try {
20851            synchronized(this) {
20852                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20853                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
20854                        "dep: " + packageName);
20855            }
20856        } finally {
20857            Binder.restoreCallingIdentity(callingId);
20858        }
20859    }
20860}
20861