ActivityManagerService.java revision 4d36b3a8c5ba1289d851ef337e46709bba333100
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.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
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.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.ShortcutServiceInternal;
145import android.content.pm.UserInfo;
146import android.content.res.CompatibilityInfo;
147import android.content.res.Configuration;
148import android.content.res.Resources;
149import android.database.ContentObserver;
150import android.graphics.Bitmap;
151import android.graphics.Point;
152import android.graphics.Rect;
153import android.location.LocationManager;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.BatteryStats;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IProcessInfoService;
171import android.os.IProgressListener;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.util.ArrayMap;
203import android.util.ArraySet;
204import android.util.AtomicFile;
205import android.util.DebugUtils;
206import android.util.EventLog;
207import android.util.LocaleList;
208import android.util.Log;
209import android.util.Pair;
210import android.util.PrintWriterPrinter;
211import android.util.Slog;
212import android.util.SparseArray;
213import android.util.TimeUtils;
214import android.util.Xml;
215import android.view.Display;
216import android.view.Gravity;
217import android.view.LayoutInflater;
218import android.view.View;
219import android.view.WindowManager;
220
221import java.io.File;
222import java.io.FileDescriptor;
223import java.io.FileInputStream;
224import java.io.FileNotFoundException;
225import java.io.FileOutputStream;
226import java.io.IOException;
227import java.io.InputStreamReader;
228import java.io.PrintWriter;
229import java.io.StringWriter;
230import java.lang.ref.WeakReference;
231import java.nio.charset.StandardCharsets;
232import java.util.ArrayList;
233import java.util.Arrays;
234import java.util.Collections;
235import java.util.Comparator;
236import java.util.HashMap;
237import java.util.HashSet;
238import java.util.Iterator;
239import java.util.List;
240import java.util.Locale;
241import java.util.Map;
242import java.util.Set;
243import java.util.concurrent.atomic.AtomicBoolean;
244import java.util.concurrent.atomic.AtomicLong;
245
246import dalvik.system.VMRuntime;
247
248import libcore.io.IoUtils;
249import libcore.util.EmptyArray;
250
251import static android.Manifest.permission.INTERACT_ACROSS_USERS;
252import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
253import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
254import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
255import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
256import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
257import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
258import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
259import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.HOME_STACK_ID;
262import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
263import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
267import static android.content.pm.PackageManager.GET_PROVIDERS;
268import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
269import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
270import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
271import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
272import static android.content.pm.PackageManager.PERMISSION_GRANTED;
273import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
274import static android.provider.Settings.Global.DEBUG_APP;
275import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
278import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
279import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
280import static android.provider.Settings.System.FONT_SCALE;
281import static com.android.internal.util.XmlUtils.readBooleanAttribute;
282import static com.android.internal.util.XmlUtils.readIntAttribute;
283import static com.android.internal.util.XmlUtils.readLongAttribute;
284import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
285import static com.android.internal.util.XmlUtils.writeIntAttribute;
286import static com.android.internal.util.XmlUtils.writeLongAttribute;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
345import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
346import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
347import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
348import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362import static org.xmlpull.v1.XmlPullParser.START_TAG;
363
364public final class ActivityManagerService extends ActivityManagerNative
365        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
366
367    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
368    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
369    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
370    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
371    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
372    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
373    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
374    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
375    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
376    private static final String TAG_LRU = TAG + POSTFIX_LRU;
377    private static final String TAG_MU = TAG + POSTFIX_MU;
378    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
379    private static final String TAG_POWER = TAG + POSTFIX_POWER;
380    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
381    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
382    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
383    private static final String TAG_PSS = TAG + POSTFIX_PSS;
384    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
385    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
386    private static final String TAG_STACK = TAG + POSTFIX_STACK;
387    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
388    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
389    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
390    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
391    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
392
393    /** Control over CPU and battery monitoring */
394    // write battery stats every 30 minutes.
395    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
396    static final boolean MONITOR_CPU_USAGE = true;
397    // don't sample cpu less than every 5 seconds.
398    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
399    // wait possibly forever for next cpu sample.
400    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
401    static final boolean MONITOR_THREAD_CPU_USAGE = false;
402
403    // The flags that are set for all calls we make to the package manager.
404    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
405
406    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
407
408    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
409
410    // Amount of time after a call to stopAppSwitches() during which we will
411    // prevent further untrusted switches from happening.
412    static final long APP_SWITCH_DELAY_TIME = 5*1000;
413
414    // How long we wait for a launched process to attach to the activity manager
415    // before we decide it's never going to come up for real.
416    static final int PROC_START_TIMEOUT = 10*1000;
417    // How long we wait for an attached process to publish its content providers
418    // before we decide it must be hung.
419    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
420
421    // How long we will retain processes hosting content providers in the "last activity"
422    // state before allowing them to drop down to the regular cached LRU list.  This is
423    // to avoid thrashing of provider processes under low memory situations.
424    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
425
426    // How long we wait for a launched process to attach to the activity manager
427    // before we decide it's never going to come up for real, when the process was
428    // started with a wrapper for instrumentation (such as Valgrind) because it
429    // could take much longer than usual.
430    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
431
432    // How long to wait after going idle before forcing apps to GC.
433    static final int GC_TIMEOUT = 5*1000;
434
435    // The minimum amount of time between successive GC requests for a process.
436    static final int GC_MIN_INTERVAL = 60*1000;
437
438    // The minimum amount of time between successive PSS requests for a process.
439    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
440
441    // The minimum amount of time between successive PSS requests for a process
442    // when the request is due to the memory state being lowered.
443    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
444
445    // The rate at which we check for apps using excessive power -- 15 mins.
446    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
447
448    // The minimum sample duration we will allow before deciding we have
449    // enough data on wake locks to start killing things.
450    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
451
452    // The minimum sample duration we will allow before deciding we have
453    // enough data on CPU usage to start killing things.
454    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
455
456    // How long we allow a receiver to run before giving up on it.
457    static final int BROADCAST_FG_TIMEOUT = 10*1000;
458    static final int BROADCAST_BG_TIMEOUT = 60*1000;
459
460    // How long we wait until we timeout on key dispatching.
461    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
462
463    // How long we wait until we timeout on key dispatching during instrumentation.
464    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
465
466    // This is the amount of time an app needs to be running a foreground service before
467    // we will consider it to be doing interaction for usage stats.
468    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
469
470    // Maximum amount of time we will allow to elapse before re-reporting usage stats
471    // interaction with foreground processes.
472    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
473
474    // This is the amount of time we allow an app to settle after it goes into the background,
475    // before we start restricting what it can do.
476    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
477
478    // How long to wait in getAssistContextExtras for the activity and foreground services
479    // to respond with the result.
480    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
481
482    // How long top wait when going through the modern assist (which doesn't need to block
483    // on getting this result before starting to launch its UI).
484    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
485
486    // Maximum number of persisted Uri grants a package is allowed
487    static final int MAX_PERSISTED_URI_GRANTS = 128;
488
489    static final int MY_PID = Process.myPid();
490
491    static final String[] EMPTY_STRING_ARRAY = new String[0];
492
493    // How many bytes to write into the dropbox log before truncating
494    static final int DROPBOX_MAX_SIZE = 256 * 1024;
495
496    // Access modes for handleIncomingUser.
497    static final int ALLOW_NON_FULL = 0;
498    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
499    static final int ALLOW_FULL_ONLY = 2;
500
501    // Delay in notifying task stack change listeners (in millis)
502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
503
504    // Necessary ApplicationInfo flags to mark an app as persistent
505    private static final int PERSISTENT_MASK =
506            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
507
508    // Intent sent when remote bugreport collection has been completed
509    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
510            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
511
512    // Delay to disable app launch boost
513    static final int APP_BOOST_MESSAGE_DELAY = 3000;
514    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
515    static final int APP_BOOST_TIMEOUT = 2500;
516
517    // Used to indicate that a task is removed it should also be removed from recents.
518    private static final boolean REMOVE_FROM_RECENTS = true;
519    // Used to indicate that an app transition should be animated.
520    static final boolean ANIMATE = true;
521
522    // Determines whether to take full screen screenshots
523    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
524    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
525
526    private static native int nativeMigrateToBoost();
527    private static native int nativeMigrateFromBoost();
528    private boolean mIsBoosted = false;
529    private long mBoostStartTime = 0;
530
531    /** All system services */
532    SystemServiceManager mSystemServiceManager;
533
534    private Installer mInstaller;
535
536    /** Run all ActivityStacks through this */
537    final ActivityStackSupervisor mStackSupervisor;
538
539    final ActivityStarter mActivityStarter;
540
541    /** Task stack change listeners. */
542    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
543            new RemoteCallbackList<ITaskStackListener>();
544
545    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
546
547    public IntentFirewall mIntentFirewall;
548
549    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
550    // default actuion automatically.  Important for devices without direct input
551    // devices.
552    private boolean mShowDialogs = true;
553    private boolean mInVrMode = false;
554
555    BroadcastQueue mFgBroadcastQueue;
556    BroadcastQueue mBgBroadcastQueue;
557    // Convenient for easy iteration over the queues. Foreground is first
558    // so that dispatch of foreground broadcasts gets precedence.
559    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
560
561    BroadcastQueue broadcastQueueForIntent(Intent intent) {
562        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
563        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
564                "Broadcast intent " + intent + " on "
565                + (isFg ? "foreground" : "background") + " queue");
566        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
567    }
568
569    /**
570     * Activity we have told the window manager to have key focus.
571     */
572    ActivityRecord mFocusedActivity = null;
573
574    /**
575     * User id of the last activity mFocusedActivity was set to.
576     */
577    private int mLastFocusedUserId;
578
579    /**
580     * If non-null, we are tracking the time the user spends in the currently focused app.
581     */
582    private AppTimeTracker mCurAppTimeTracker;
583
584    /**
585     * List of intents that were used to start the most recent tasks.
586     */
587    final RecentTasks mRecentTasks;
588
589    /**
590     * For addAppTask: cached of the last activity component that was added.
591     */
592    ComponentName mLastAddedTaskComponent;
593
594    /**
595     * For addAppTask: cached of the last activity uid that was added.
596     */
597    int mLastAddedTaskUid;
598
599    /**
600     * For addAppTask: cached of the last ActivityInfo that was added.
601     */
602    ActivityInfo mLastAddedTaskActivity;
603
604    /**
605     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
606     */
607    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
608
609    /**
610     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
611     */
612    String mDeviceOwnerName;
613
614    final UserController mUserController;
615
616    final AppErrors mAppErrors;
617
618    boolean mDoingSetFocusedActivity;
619
620    public boolean canShowErrorDialogs() {
621        return mShowDialogs && !mSleeping && !mShuttingDown;
622    }
623
624    public class PendingAssistExtras extends Binder implements Runnable {
625        public final ActivityRecord activity;
626        public final Bundle extras;
627        public final Intent intent;
628        public final String hint;
629        public final IResultReceiver receiver;
630        public final int userHandle;
631        public boolean haveResult = false;
632        public Bundle result = null;
633        public AssistStructure structure = null;
634        public AssistContent content = null;
635        public Bundle receiverExtras;
636
637        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
638                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
639            activity = _activity;
640            extras = _extras;
641            intent = _intent;
642            hint = _hint;
643            receiver = _receiver;
644            receiverExtras = _receiverExtras;
645            userHandle = _userHandle;
646        }
647        @Override
648        public void run() {
649            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
650            synchronized (this) {
651                haveResult = true;
652                notifyAll();
653            }
654            pendingAssistExtrasTimedOut(this);
655        }
656    }
657
658    final ArrayList<PendingAssistExtras> mPendingAssistExtras
659            = new ArrayList<PendingAssistExtras>();
660
661    /**
662     * Process management.
663     */
664    final ProcessList mProcessList = new ProcessList();
665
666    /**
667     * All of the applications we currently have running organized by name.
668     * The keys are strings of the application package name (as
669     * returned by the package manager), and the keys are ApplicationRecord
670     * objects.
671     */
672    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
673
674    /**
675     * Tracking long-term execution of processes to look for abuse and other
676     * bad app behavior.
677     */
678    final ProcessStatsService mProcessStats;
679
680    /**
681     * The currently running isolated processes.
682     */
683    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
684
685    /**
686     * Counter for assigning isolated process uids, to avoid frequently reusing the
687     * same ones.
688     */
689    int mNextIsolatedProcessUid = 0;
690
691    /**
692     * The currently running heavy-weight process, if any.
693     */
694    ProcessRecord mHeavyWeightProcess = null;
695
696    /**
697     * All of the processes we currently have running organized by pid.
698     * The keys are the pid running the application.
699     *
700     * <p>NOTE: This object is protected by its own lock, NOT the global
701     * activity manager lock!
702     */
703    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
704
705    /**
706     * All of the processes that have been forced to be foreground.  The key
707     * is the pid of the caller who requested it (we hold a death
708     * link on it).
709     */
710    abstract class ForegroundToken implements IBinder.DeathRecipient {
711        int pid;
712        IBinder token;
713    }
714    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
715
716    /**
717     * List of records for processes that someone had tried to start before the
718     * system was ready.  We don't start them at that point, but ensure they
719     * are started by the time booting is complete.
720     */
721    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
722
723    /**
724     * List of persistent applications that are in the process
725     * of being started.
726     */
727    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
728
729    /**
730     * Processes that are being forcibly torn down.
731     */
732    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
733
734    /**
735     * List of running applications, sorted by recent usage.
736     * The first entry in the list is the least recently used.
737     */
738    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
739
740    /**
741     * Where in mLruProcesses that the processes hosting activities start.
742     */
743    int mLruProcessActivityStart = 0;
744
745    /**
746     * Where in mLruProcesses that the processes hosting services start.
747     * This is after (lower index) than mLruProcessesActivityStart.
748     */
749    int mLruProcessServiceStart = 0;
750
751    /**
752     * List of processes that should gc as soon as things are idle.
753     */
754    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
755
756    /**
757     * Processes we want to collect PSS data from.
758     */
759    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
760
761    private boolean mBinderTransactionTrackingEnabled = false;
762
763    /**
764     * Last time we requested PSS data of all processes.
765     */
766    long mLastFullPssTime = SystemClock.uptimeMillis();
767
768    /**
769     * If set, the next time we collect PSS data we should do a full collection
770     * with data from native processes and the kernel.
771     */
772    boolean mFullPssPending = false;
773
774    /**
775     * This is the process holding what we currently consider to be
776     * the "home" activity.
777     */
778    ProcessRecord mHomeProcess;
779
780    /**
781     * This is the process holding the activity the user last visited that
782     * is in a different process from the one they are currently in.
783     */
784    ProcessRecord mPreviousProcess;
785
786    /**
787     * The time at which the previous process was last visible.
788     */
789    long mPreviousProcessVisibleTime;
790
791    /**
792     * Track all uids that have actively running processes.
793     */
794    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
795
796    /**
797     * This is for verifying the UID report flow.
798     */
799    static final boolean VALIDATE_UID_STATES = true;
800    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
801
802    /**
803     * Packages that the user has asked to have run in screen size
804     * compatibility mode instead of filling the screen.
805     */
806    final CompatModePackages mCompatModePackages;
807
808    /**
809     * Set of IntentSenderRecord objects that are currently active.
810     */
811    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
812            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
813
814    /**
815     * Fingerprints (hashCode()) of stack traces that we've
816     * already logged DropBox entries for.  Guarded by itself.  If
817     * something (rogue user app) forces this over
818     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
819     */
820    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
821    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
822
823    /**
824     * Strict Mode background batched logging state.
825     *
826     * The string buffer is guarded by itself, and its lock is also
827     * used to determine if another batched write is already
828     * in-flight.
829     */
830    private final StringBuilder mStrictModeBuffer = new StringBuilder();
831
832    /**
833     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
834     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
835     */
836    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
837
838    /**
839     * Resolver for broadcast intents to registered receivers.
840     * Holds BroadcastFilter (subclass of IntentFilter).
841     */
842    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
843            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
844        @Override
845        protected boolean allowFilterResult(
846                BroadcastFilter filter, List<BroadcastFilter> dest) {
847            IBinder target = filter.receiverList.receiver.asBinder();
848            for (int i = dest.size() - 1; i >= 0; i--) {
849                if (dest.get(i).receiverList.receiver.asBinder() == target) {
850                    return false;
851                }
852            }
853            return true;
854        }
855
856        @Override
857        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
858            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
859                    || userId == filter.owningUserId) {
860                return super.newResult(filter, match, userId);
861            }
862            return null;
863        }
864
865        @Override
866        protected BroadcastFilter[] newArray(int size) {
867            return new BroadcastFilter[size];
868        }
869
870        @Override
871        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
872            return packageName.equals(filter.packageName);
873        }
874    };
875
876    /**
877     * State of all active sticky broadcasts per user.  Keys are the action of the
878     * sticky Intent, values are an ArrayList of all broadcasted intents with
879     * that action (which should usually be one).  The SparseArray is keyed
880     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
881     * for stickies that are sent to all users.
882     */
883    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
884            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
885
886    final ActiveServices mServices;
887
888    final static class Association {
889        final int mSourceUid;
890        final String mSourceProcess;
891        final int mTargetUid;
892        final ComponentName mTargetComponent;
893        final String mTargetProcess;
894
895        int mCount;
896        long mTime;
897
898        int mNesting;
899        long mStartTime;
900
901        // states of the source process when the bind occurred.
902        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
903        long mLastStateUptime;
904        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
905                - ActivityManager.MIN_PROCESS_STATE+1];
906
907        Association(int sourceUid, String sourceProcess, int targetUid,
908                ComponentName targetComponent, String targetProcess) {
909            mSourceUid = sourceUid;
910            mSourceProcess = sourceProcess;
911            mTargetUid = targetUid;
912            mTargetComponent = targetComponent;
913            mTargetProcess = targetProcess;
914        }
915    }
916
917    /**
918     * When service association tracking is enabled, this is all of the associations we
919     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
920     * -> association data.
921     */
922    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
923            mAssociations = new SparseArray<>();
924    boolean mTrackingAssociations;
925
926    /**
927     * Backup/restore process management
928     */
929    String mBackupAppName = null;
930    BackupRecord mBackupTarget = null;
931
932    final ProviderMap mProviderMap;
933
934    /**
935     * List of content providers who have clients waiting for them.  The
936     * application is currently being launched and the provider will be
937     * removed from this list once it is published.
938     */
939    final ArrayList<ContentProviderRecord> mLaunchingProviders
940            = new ArrayList<ContentProviderRecord>();
941
942    /**
943     * File storing persisted {@link #mGrantedUriPermissions}.
944     */
945    private final AtomicFile mGrantFile;
946
947    /** XML constants used in {@link #mGrantFile} */
948    private static final String TAG_URI_GRANTS = "uri-grants";
949    private static final String TAG_URI_GRANT = "uri-grant";
950    private static final String ATTR_USER_HANDLE = "userHandle";
951    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
952    private static final String ATTR_TARGET_USER_ID = "targetUserId";
953    private static final String ATTR_SOURCE_PKG = "sourcePkg";
954    private static final String ATTR_TARGET_PKG = "targetPkg";
955    private static final String ATTR_URI = "uri";
956    private static final String ATTR_MODE_FLAGS = "modeFlags";
957    private static final String ATTR_CREATED_TIME = "createdTime";
958    private static final String ATTR_PREFIX = "prefix";
959
960    /**
961     * Global set of specific {@link Uri} permissions that have been granted.
962     * This optimized lookup structure maps from {@link UriPermission#targetUid}
963     * to {@link UriPermission#uri} to {@link UriPermission}.
964     */
965    @GuardedBy("this")
966    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
967            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
968
969    public static class GrantUri {
970        public final int sourceUserId;
971        public final Uri uri;
972        public boolean prefix;
973
974        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
975            this.sourceUserId = sourceUserId;
976            this.uri = uri;
977            this.prefix = prefix;
978        }
979
980        @Override
981        public int hashCode() {
982            int hashCode = 1;
983            hashCode = 31 * hashCode + sourceUserId;
984            hashCode = 31 * hashCode + uri.hashCode();
985            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
986            return hashCode;
987        }
988
989        @Override
990        public boolean equals(Object o) {
991            if (o instanceof GrantUri) {
992                GrantUri other = (GrantUri) o;
993                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
994                        && prefix == other.prefix;
995            }
996            return false;
997        }
998
999        @Override
1000        public String toString() {
1001            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1002            if (prefix) result += " [prefix]";
1003            return result;
1004        }
1005
1006        public String toSafeString() {
1007            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1008            if (prefix) result += " [prefix]";
1009            return result;
1010        }
1011
1012        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1013            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1014                    ContentProvider.getUriWithoutUserId(uri), false);
1015        }
1016    }
1017
1018    CoreSettingsObserver mCoreSettingsObserver;
1019
1020    FontScaleSettingObserver mFontScaleSettingObserver;
1021
1022    private final class FontScaleSettingObserver extends ContentObserver {
1023        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1024
1025        public FontScaleSettingObserver() {
1026            super(mHandler);
1027            ContentResolver resolver = mContext.getContentResolver();
1028            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1029        }
1030
1031        @Override
1032        public void onChange(boolean selfChange, Uri uri) {
1033            if (mFontScaleUri.equals(uri)) {
1034                updateFontScaleIfNeeded();
1035            }
1036        }
1037    }
1038
1039    /**
1040     * Thread-local storage used to carry caller permissions over through
1041     * indirect content-provider access.
1042     */
1043    private class Identity {
1044        public final IBinder token;
1045        public final int pid;
1046        public final int uid;
1047
1048        Identity(IBinder _token, int _pid, int _uid) {
1049            token = _token;
1050            pid = _pid;
1051            uid = _uid;
1052        }
1053    }
1054
1055    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1056
1057    /**
1058     * All information we have collected about the runtime performance of
1059     * any user id that can impact battery performance.
1060     */
1061    final BatteryStatsService mBatteryStatsService;
1062
1063    /**
1064     * Information about component usage
1065     */
1066    UsageStatsManagerInternal mUsageStatsService;
1067
1068    /**
1069     * Access to DeviceIdleController service.
1070     */
1071    DeviceIdleController.LocalService mLocalDeviceIdleController;
1072
1073    /**
1074     * Information about and control over application operations
1075     */
1076    final AppOpsService mAppOpsService;
1077
1078    /**
1079     * Current configuration information.  HistoryRecord objects are given
1080     * a reference to this object to indicate which configuration they are
1081     * currently running in, so this object must be kept immutable.
1082     */
1083    Configuration mConfiguration = new Configuration();
1084
1085    /**
1086     * Current sequencing integer of the configuration, for skipping old
1087     * configurations.
1088     */
1089    int mConfigurationSeq = 0;
1090
1091    boolean mSuppressResizeConfigChanges = false;
1092
1093    /**
1094     * Hardware-reported OpenGLES version.
1095     */
1096    final int GL_ES_VERSION;
1097
1098    /**
1099     * List of initialization arguments to pass to all processes when binding applications to them.
1100     * For example, references to the commonly used services.
1101     */
1102    HashMap<String, IBinder> mAppBindArgs;
1103
1104    /**
1105     * Temporary to avoid allocations.  Protected by main lock.
1106     */
1107    final StringBuilder mStringBuilder = new StringBuilder(256);
1108
1109    /**
1110     * Used to control how we initialize the service.
1111     */
1112    ComponentName mTopComponent;
1113    String mTopAction = Intent.ACTION_MAIN;
1114    String mTopData;
1115
1116    volatile boolean mProcessesReady = false;
1117    volatile boolean mSystemReady = false;
1118    volatile boolean mOnBattery = false;
1119    volatile int mFactoryTest;
1120
1121    @GuardedBy("this") boolean mBooting = false;
1122    @GuardedBy("this") boolean mCallFinishBooting = false;
1123    @GuardedBy("this") boolean mBootAnimationComplete = false;
1124    @GuardedBy("this") boolean mLaunchWarningShown = false;
1125    @GuardedBy("this") boolean mCheckedForSetup = false;
1126
1127    Context mContext;
1128
1129    /**
1130     * The time at which we will allow normal application switches again,
1131     * after a call to {@link #stopAppSwitches()}.
1132     */
1133    long mAppSwitchesAllowedTime;
1134
1135    /**
1136     * This is set to true after the first switch after mAppSwitchesAllowedTime
1137     * is set; any switches after that will clear the time.
1138     */
1139    boolean mDidAppSwitch;
1140
1141    /**
1142     * Last time (in realtime) at which we checked for power usage.
1143     */
1144    long mLastPowerCheckRealtime;
1145
1146    /**
1147     * Last time (in uptime) at which we checked for power usage.
1148     */
1149    long mLastPowerCheckUptime;
1150
1151    /**
1152     * Set while we are wanting to sleep, to prevent any
1153     * activities from being started/resumed.
1154     */
1155    private boolean mSleeping = false;
1156
1157    /**
1158     * The process state used for processes that are running the top activities.
1159     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1160     */
1161    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1162
1163    /**
1164     * Set while we are running a voice interaction.  This overrides
1165     * sleeping while it is active.
1166     */
1167    private IVoiceInteractionSession mRunningVoice;
1168
1169    /**
1170     * For some direct access we need to power manager.
1171     */
1172    PowerManagerInternal mLocalPowerManager;
1173
1174    /**
1175     * We want to hold a wake lock while running a voice interaction session, since
1176     * this may happen with the screen off and we need to keep the CPU running to
1177     * be able to continue to interact with the user.
1178     */
1179    PowerManager.WakeLock mVoiceWakeLock;
1180
1181    /**
1182     * State of external calls telling us if the device is awake or asleep.
1183     */
1184    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1185
1186    /**
1187     * A list of tokens that cause the top activity to be put to sleep.
1188     * They are used by components that may hide and block interaction with underlying
1189     * activities.
1190     */
1191    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1192
1193    static final int LOCK_SCREEN_HIDDEN = 0;
1194    static final int LOCK_SCREEN_LEAVING = 1;
1195    static final int LOCK_SCREEN_SHOWN = 2;
1196    /**
1197     * State of external call telling us if the lock screen is shown.
1198     */
1199    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1200
1201    /**
1202     * Set if we are shutting down the system, similar to sleeping.
1203     */
1204    boolean mShuttingDown = false;
1205
1206    /**
1207     * Current sequence id for oom_adj computation traversal.
1208     */
1209    int mAdjSeq = 0;
1210
1211    /**
1212     * Current sequence id for process LRU updating.
1213     */
1214    int mLruSeq = 0;
1215
1216    /**
1217     * Keep track of the non-cached/empty process we last found, to help
1218     * determine how to distribute cached/empty processes next time.
1219     */
1220    int mNumNonCachedProcs = 0;
1221
1222    /**
1223     * Keep track of the number of cached hidden procs, to balance oom adj
1224     * distribution between those and empty procs.
1225     */
1226    int mNumCachedHiddenProcs = 0;
1227
1228    /**
1229     * Keep track of the number of service processes we last found, to
1230     * determine on the next iteration which should be B services.
1231     */
1232    int mNumServiceProcs = 0;
1233    int mNewNumAServiceProcs = 0;
1234    int mNewNumServiceProcs = 0;
1235
1236    /**
1237     * Allow the current computed overall memory level of the system to go down?
1238     * This is set to false when we are killing processes for reasons other than
1239     * memory management, so that the now smaller process list will not be taken as
1240     * an indication that memory is tighter.
1241     */
1242    boolean mAllowLowerMemLevel = false;
1243
1244    /**
1245     * The last computed memory level, for holding when we are in a state that
1246     * processes are going away for other reasons.
1247     */
1248    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1249
1250    /**
1251     * The last total number of process we have, to determine if changes actually look
1252     * like a shrinking number of process due to lower RAM.
1253     */
1254    int mLastNumProcesses;
1255
1256    /**
1257     * The uptime of the last time we performed idle maintenance.
1258     */
1259    long mLastIdleTime = SystemClock.uptimeMillis();
1260
1261    /**
1262     * Total time spent with RAM that has been added in the past since the last idle time.
1263     */
1264    long mLowRamTimeSinceLastIdle = 0;
1265
1266    /**
1267     * If RAM is currently low, when that horrible situation started.
1268     */
1269    long mLowRamStartTime = 0;
1270
1271    /**
1272     * For reporting to battery stats the current top application.
1273     */
1274    private String mCurResumedPackage = null;
1275    private int mCurResumedUid = -1;
1276
1277    /**
1278     * For reporting to battery stats the apps currently running foreground
1279     * service.  The ProcessMap is package/uid tuples; each of these contain
1280     * an array of the currently foreground processes.
1281     */
1282    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1283            = new ProcessMap<ArrayList<ProcessRecord>>();
1284
1285    /**
1286     * This is set if we had to do a delayed dexopt of an app before launching
1287     * it, to increase the ANR timeouts in that case.
1288     */
1289    boolean mDidDexOpt;
1290
1291    /**
1292     * Set if the systemServer made a call to enterSafeMode.
1293     */
1294    boolean mSafeMode;
1295
1296    /**
1297     * If true, we are running under a test environment so will sample PSS from processes
1298     * much more rapidly to try to collect better data when the tests are rapidly
1299     * running through apps.
1300     */
1301    boolean mTestPssMode = false;
1302
1303    String mDebugApp = null;
1304    boolean mWaitForDebugger = false;
1305    boolean mDebugTransient = false;
1306    String mOrigDebugApp = null;
1307    boolean mOrigWaitForDebugger = false;
1308    boolean mAlwaysFinishActivities = false;
1309    boolean mLenientBackgroundCheck = false;
1310    boolean mForceResizableActivities;
1311    boolean mSupportsMultiWindow;
1312    boolean mSupportsFreeformWindowManagement;
1313    boolean mSupportsPictureInPicture;
1314    Rect mDefaultPinnedStackBounds;
1315    IActivityController mController = null;
1316    boolean mControllerIsAMonkey = false;
1317    String mProfileApp = null;
1318    ProcessRecord mProfileProc = null;
1319    String mProfileFile;
1320    ParcelFileDescriptor mProfileFd;
1321    int mSamplingInterval = 0;
1322    boolean mAutoStopProfiler = false;
1323    int mProfileType = 0;
1324    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1325    String mMemWatchDumpProcName;
1326    String mMemWatchDumpFile;
1327    int mMemWatchDumpPid;
1328    int mMemWatchDumpUid;
1329    String mTrackAllocationApp = null;
1330    String mNativeDebuggingApp = null;
1331
1332    final long[] mTmpLong = new long[2];
1333
1334    static final class ProcessChangeItem {
1335        static final int CHANGE_ACTIVITIES = 1<<0;
1336        static final int CHANGE_PROCESS_STATE = 1<<1;
1337        int changes;
1338        int uid;
1339        int pid;
1340        int processState;
1341        boolean foregroundActivities;
1342    }
1343
1344    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1345    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1346
1347    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1348    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1349
1350    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1351    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1352
1353    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1354    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1355
1356    /**
1357     * Runtime CPU use collection thread.  This object's lock is used to
1358     * perform synchronization with the thread (notifying it to run).
1359     */
1360    final Thread mProcessCpuThread;
1361
1362    /**
1363     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1364     * Must acquire this object's lock when accessing it.
1365     * NOTE: this lock will be held while doing long operations (trawling
1366     * through all processes in /proc), so it should never be acquired by
1367     * any critical paths such as when holding the main activity manager lock.
1368     */
1369    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1370            MONITOR_THREAD_CPU_USAGE);
1371    final AtomicLong mLastCpuTime = new AtomicLong(0);
1372    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1373
1374    long mLastWriteTime = 0;
1375
1376    /**
1377     * Used to retain an update lock when the foreground activity is in
1378     * immersive mode.
1379     */
1380    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1381
1382    /**
1383     * Set to true after the system has finished booting.
1384     */
1385    boolean mBooted = false;
1386
1387    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1388    int mProcessLimitOverride = -1;
1389
1390    WindowManagerService mWindowManager;
1391    final ActivityThread mSystemThread;
1392
1393    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1394        final ProcessRecord mApp;
1395        final int mPid;
1396        final IApplicationThread mAppThread;
1397
1398        AppDeathRecipient(ProcessRecord app, int pid,
1399                IApplicationThread thread) {
1400            if (DEBUG_ALL) Slog.v(
1401                TAG, "New death recipient " + this
1402                + " for thread " + thread.asBinder());
1403            mApp = app;
1404            mPid = pid;
1405            mAppThread = thread;
1406        }
1407
1408        @Override
1409        public void binderDied() {
1410            if (DEBUG_ALL) Slog.v(
1411                TAG, "Death received in " + this
1412                + " for thread " + mAppThread.asBinder());
1413            synchronized(ActivityManagerService.this) {
1414                appDiedLocked(mApp, mPid, mAppThread, true);
1415            }
1416        }
1417    }
1418
1419    static final int SHOW_ERROR_UI_MSG = 1;
1420    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1421    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1422    static final int UPDATE_CONFIGURATION_MSG = 4;
1423    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1424    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1425    static final int SERVICE_TIMEOUT_MSG = 12;
1426    static final int UPDATE_TIME_ZONE = 13;
1427    static final int SHOW_UID_ERROR_UI_MSG = 14;
1428    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1429    static final int PROC_START_TIMEOUT_MSG = 20;
1430    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1431    static final int KILL_APPLICATION_MSG = 22;
1432    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1433    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1434    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1435    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1436    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1437    static final int CLEAR_DNS_CACHE_MSG = 28;
1438    static final int UPDATE_HTTP_PROXY_MSG = 29;
1439    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1440    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1441    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1442    static final int REPORT_MEM_USAGE_MSG = 33;
1443    static final int REPORT_USER_SWITCH_MSG = 34;
1444    static final int CONTINUE_USER_SWITCH_MSG = 35;
1445    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1446    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1447    static final int PERSIST_URI_GRANTS_MSG = 38;
1448    static final int REQUEST_ALL_PSS_MSG = 39;
1449    static final int START_PROFILES_MSG = 40;
1450    static final int UPDATE_TIME = 41;
1451    static final int SYSTEM_USER_START_MSG = 42;
1452    static final int SYSTEM_USER_CURRENT_MSG = 43;
1453    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1454    static final int FINISH_BOOTING_MSG = 45;
1455    static final int START_USER_SWITCH_UI_MSG = 46;
1456    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1457    static final int DISMISS_DIALOG_UI_MSG = 48;
1458    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1459    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1460    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1461    static final int DELETE_DUMPHEAP_MSG = 52;
1462    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1463    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1464    static final int REPORT_TIME_TRACKER_MSG = 55;
1465    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1466    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1467    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1468    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1469    static final int IDLE_UIDS_MSG = 60;
1470    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1471    static final int LOG_STACK_STATE = 62;
1472    static final int VR_MODE_CHANGE_MSG = 63;
1473    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1474    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1475    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1476    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1477    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1478    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1479
1480    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1481    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1482    static final int FIRST_COMPAT_MODE_MSG = 300;
1483    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1484
1485    static ServiceThread sKillThread = null;
1486    static KillHandler sKillHandler = null;
1487
1488    CompatModeDialog mCompatModeDialog;
1489    long mLastMemUsageReportTime = 0;
1490
1491    /**
1492     * Flag whether the current user is a "monkey", i.e. whether
1493     * the UI is driven by a UI automation tool.
1494     */
1495    private boolean mUserIsMonkey;
1496
1497    /** Flag whether the device has a Recents UI */
1498    boolean mHasRecents;
1499
1500    /** The dimensions of the thumbnails in the Recents UI. */
1501    int mThumbnailWidth;
1502    int mThumbnailHeight;
1503    float mFullscreenThumbnailScale;
1504
1505    final ServiceThread mHandlerThread;
1506    final MainHandler mHandler;
1507    final UiHandler mUiHandler;
1508
1509    PackageManagerInternal mPackageManagerInt;
1510
1511    final class KillHandler extends Handler {
1512        static final int KILL_PROCESS_GROUP_MSG = 4000;
1513
1514        public KillHandler(Looper looper) {
1515            super(looper, null, true);
1516        }
1517
1518        @Override
1519        public void handleMessage(Message msg) {
1520            switch (msg.what) {
1521                case KILL_PROCESS_GROUP_MSG:
1522                {
1523                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1524                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1525                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1526                }
1527                break;
1528
1529                default:
1530                    super.handleMessage(msg);
1531            }
1532        }
1533    }
1534
1535    final class UiHandler extends Handler {
1536        public UiHandler() {
1537            super(com.android.server.UiThread.get().getLooper(), null, true);
1538        }
1539
1540        @Override
1541        public void handleMessage(Message msg) {
1542            switch (msg.what) {
1543            case SHOW_ERROR_UI_MSG: {
1544                mAppErrors.handleShowAppErrorUi(msg);
1545                ensureBootCompleted();
1546            } break;
1547            case SHOW_NOT_RESPONDING_UI_MSG: {
1548                mAppErrors.handleShowAnrUi(msg);
1549                ensureBootCompleted();
1550            } break;
1551            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1552                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1553                synchronized (ActivityManagerService.this) {
1554                    ProcessRecord proc = (ProcessRecord) data.get("app");
1555                    if (proc == null) {
1556                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1557                        break;
1558                    }
1559                    if (proc.crashDialog != null) {
1560                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1561                        return;
1562                    }
1563                    AppErrorResult res = (AppErrorResult) data.get("result");
1564                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1565                        Dialog d = new StrictModeViolationDialog(mContext,
1566                                ActivityManagerService.this, res, proc);
1567                        d.show();
1568                        proc.crashDialog = d;
1569                    } else {
1570                        // The device is asleep, so just pretend that the user
1571                        // saw a crash dialog and hit "force quit".
1572                        res.set(0);
1573                    }
1574                }
1575                ensureBootCompleted();
1576            } break;
1577            case SHOW_FACTORY_ERROR_UI_MSG: {
1578                Dialog d = new FactoryErrorDialog(
1579                    mContext, msg.getData().getCharSequence("msg"));
1580                d.show();
1581                ensureBootCompleted();
1582            } break;
1583            case WAIT_FOR_DEBUGGER_UI_MSG: {
1584                synchronized (ActivityManagerService.this) {
1585                    ProcessRecord app = (ProcessRecord)msg.obj;
1586                    if (msg.arg1 != 0) {
1587                        if (!app.waitedForDebugger) {
1588                            Dialog d = new AppWaitingForDebuggerDialog(
1589                                    ActivityManagerService.this,
1590                                    mContext, app);
1591                            app.waitDialog = d;
1592                            app.waitedForDebugger = true;
1593                            d.show();
1594                        }
1595                    } else {
1596                        if (app.waitDialog != null) {
1597                            app.waitDialog.dismiss();
1598                            app.waitDialog = null;
1599                        }
1600                    }
1601                }
1602            } break;
1603            case SHOW_UID_ERROR_UI_MSG: {
1604                if (mShowDialogs) {
1605                    AlertDialog d = new BaseErrorDialog(mContext);
1606                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1607                    d.setCancelable(false);
1608                    d.setTitle(mContext.getText(R.string.android_system_label));
1609                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1610                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1611                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1612                    d.show();
1613                }
1614            } break;
1615            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1616                if (mShowDialogs) {
1617                    AlertDialog d = new BaseErrorDialog(mContext);
1618                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1619                    d.setCancelable(false);
1620                    d.setTitle(mContext.getText(R.string.android_system_label));
1621                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1622                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1623                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1624                    d.show();
1625                }
1626            } break;
1627            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1628                synchronized (ActivityManagerService.this) {
1629                    ActivityRecord ar = (ActivityRecord) msg.obj;
1630                    if (mCompatModeDialog != null) {
1631                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1632                                ar.info.applicationInfo.packageName)) {
1633                            return;
1634                        }
1635                        mCompatModeDialog.dismiss();
1636                        mCompatModeDialog = null;
1637                    }
1638                    if (ar != null && false) {
1639                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1640                                ar.packageName)) {
1641                            int mode = mCompatModePackages.computeCompatModeLocked(
1642                                    ar.info.applicationInfo);
1643                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1644                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1645                                mCompatModeDialog = new CompatModeDialog(
1646                                        ActivityManagerService.this, mContext,
1647                                        ar.info.applicationInfo);
1648                                mCompatModeDialog.show();
1649                            }
1650                        }
1651                    }
1652                }
1653                break;
1654            }
1655            case START_USER_SWITCH_UI_MSG: {
1656                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1657                break;
1658            }
1659            case DISMISS_DIALOG_UI_MSG: {
1660                final Dialog d = (Dialog) msg.obj;
1661                d.dismiss();
1662                break;
1663            }
1664            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1665                dispatchProcessesChanged();
1666                break;
1667            }
1668            case DISPATCH_PROCESS_DIED_UI_MSG: {
1669                final int pid = msg.arg1;
1670                final int uid = msg.arg2;
1671                dispatchProcessDied(pid, uid);
1672                break;
1673            }
1674            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1675                dispatchUidsChanged();
1676            } break;
1677            }
1678        }
1679    }
1680
1681    final class MainHandler extends Handler {
1682        public MainHandler(Looper looper) {
1683            super(looper, null, true);
1684        }
1685
1686        @Override
1687        public void handleMessage(Message msg) {
1688            switch (msg.what) {
1689            case UPDATE_CONFIGURATION_MSG: {
1690                final ContentResolver resolver = mContext.getContentResolver();
1691                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1692                        msg.arg1);
1693            } break;
1694            case GC_BACKGROUND_PROCESSES_MSG: {
1695                synchronized (ActivityManagerService.this) {
1696                    performAppGcsIfAppropriateLocked();
1697                }
1698            } break;
1699            case SERVICE_TIMEOUT_MSG: {
1700                if (mDidDexOpt) {
1701                    mDidDexOpt = false;
1702                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1703                    nmsg.obj = msg.obj;
1704                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1705                    return;
1706                }
1707                mServices.serviceTimeout((ProcessRecord)msg.obj);
1708            } break;
1709            case UPDATE_TIME_ZONE: {
1710                synchronized (ActivityManagerService.this) {
1711                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1712                        ProcessRecord r = mLruProcesses.get(i);
1713                        if (r.thread != null) {
1714                            try {
1715                                r.thread.updateTimeZone();
1716                            } catch (RemoteException ex) {
1717                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1718                            }
1719                        }
1720                    }
1721                }
1722            } break;
1723            case CLEAR_DNS_CACHE_MSG: {
1724                synchronized (ActivityManagerService.this) {
1725                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1726                        ProcessRecord r = mLruProcesses.get(i);
1727                        if (r.thread != null) {
1728                            try {
1729                                r.thread.clearDnsCache();
1730                            } catch (RemoteException ex) {
1731                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1732                            }
1733                        }
1734                    }
1735                }
1736            } break;
1737            case UPDATE_HTTP_PROXY_MSG: {
1738                ProxyInfo proxy = (ProxyInfo)msg.obj;
1739                String host = "";
1740                String port = "";
1741                String exclList = "";
1742                Uri pacFileUrl = Uri.EMPTY;
1743                if (proxy != null) {
1744                    host = proxy.getHost();
1745                    port = Integer.toString(proxy.getPort());
1746                    exclList = proxy.getExclusionListAsString();
1747                    pacFileUrl = proxy.getPacFileUrl();
1748                }
1749                synchronized (ActivityManagerService.this) {
1750                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1751                        ProcessRecord r = mLruProcesses.get(i);
1752                        if (r.thread != null) {
1753                            try {
1754                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1755                            } catch (RemoteException ex) {
1756                                Slog.w(TAG, "Failed to update http proxy for: " +
1757                                        r.info.processName);
1758                            }
1759                        }
1760                    }
1761                }
1762            } break;
1763            case PROC_START_TIMEOUT_MSG: {
1764                if (mDidDexOpt) {
1765                    mDidDexOpt = false;
1766                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1767                    nmsg.obj = msg.obj;
1768                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1769                    return;
1770                }
1771                ProcessRecord app = (ProcessRecord)msg.obj;
1772                synchronized (ActivityManagerService.this) {
1773                    processStartTimedOutLocked(app);
1774                }
1775            } break;
1776            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1777                ProcessRecord app = (ProcessRecord)msg.obj;
1778                synchronized (ActivityManagerService.this) {
1779                    processContentProviderPublishTimedOutLocked(app);
1780                }
1781            } break;
1782            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1783                synchronized (ActivityManagerService.this) {
1784                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1785                }
1786            } break;
1787            case KILL_APPLICATION_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    int appid = msg.arg1;
1790                    boolean restart = (msg.arg2 == 1);
1791                    Bundle bundle = (Bundle)msg.obj;
1792                    String pkg = bundle.getString("pkg");
1793                    String reason = bundle.getString("reason");
1794                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1795                            false, UserHandle.USER_ALL, reason);
1796                }
1797            } break;
1798            case FINALIZE_PENDING_INTENT_MSG: {
1799                ((PendingIntentRecord)msg.obj).completeFinalize();
1800            } break;
1801            case POST_HEAVY_NOTIFICATION_MSG: {
1802                INotificationManager inm = NotificationManager.getService();
1803                if (inm == null) {
1804                    return;
1805                }
1806
1807                ActivityRecord root = (ActivityRecord)msg.obj;
1808                ProcessRecord process = root.app;
1809                if (process == null) {
1810                    return;
1811                }
1812
1813                try {
1814                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1815                    String text = mContext.getString(R.string.heavy_weight_notification,
1816                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1817                    Notification notification = new Notification.Builder(context)
1818                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1819                            .setWhen(0)
1820                            .setOngoing(true)
1821                            .setTicker(text)
1822                            .setColor(mContext.getColor(
1823                                    com.android.internal.R.color.system_notification_accent_color))
1824                            .setContentTitle(text)
1825                            .setContentText(
1826                                    mContext.getText(R.string.heavy_weight_notification_detail))
1827                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1828                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1829                                    new UserHandle(root.userId)))
1830                            .build();
1831                    try {
1832                        int[] outId = new int[1];
1833                        inm.enqueueNotificationWithTag("android", "android", null,
1834                                R.string.heavy_weight_notification,
1835                                notification, outId, root.userId);
1836                    } catch (RuntimeException e) {
1837                        Slog.w(ActivityManagerService.TAG,
1838                                "Error showing notification for heavy-weight app", e);
1839                    } catch (RemoteException e) {
1840                    }
1841                } catch (NameNotFoundException e) {
1842                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1843                }
1844            } break;
1845            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1846                INotificationManager inm = NotificationManager.getService();
1847                if (inm == null) {
1848                    return;
1849                }
1850                try {
1851                    inm.cancelNotificationWithTag("android", null,
1852                            R.string.heavy_weight_notification,  msg.arg1);
1853                } catch (RuntimeException e) {
1854                    Slog.w(ActivityManagerService.TAG,
1855                            "Error canceling notification for service", e);
1856                } catch (RemoteException e) {
1857                }
1858            } break;
1859            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    checkExcessivePowerUsageLocked(true);
1862                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1863                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1864                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1865                }
1866            } break;
1867            case REPORT_MEM_USAGE_MSG: {
1868                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1869                Thread thread = new Thread() {
1870                    @Override public void run() {
1871                        reportMemUsage(memInfos);
1872                    }
1873                };
1874                thread.start();
1875                break;
1876            }
1877            case REPORT_USER_SWITCH_MSG: {
1878                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1879                break;
1880            }
1881            case CONTINUE_USER_SWITCH_MSG: {
1882                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1883                break;
1884            }
1885            case USER_SWITCH_TIMEOUT_MSG: {
1886                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1887                break;
1888            }
1889            case IMMERSIVE_MODE_LOCK_MSG: {
1890                final boolean nextState = (msg.arg1 != 0);
1891                if (mUpdateLock.isHeld() != nextState) {
1892                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1893                            "Applying new update lock state '" + nextState
1894                            + "' for " + (ActivityRecord)msg.obj);
1895                    if (nextState) {
1896                        mUpdateLock.acquire();
1897                    } else {
1898                        mUpdateLock.release();
1899                    }
1900                }
1901                break;
1902            }
1903            case PERSIST_URI_GRANTS_MSG: {
1904                writeGrantedUriPermissions();
1905                break;
1906            }
1907            case REQUEST_ALL_PSS_MSG: {
1908                synchronized (ActivityManagerService.this) {
1909                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1910                }
1911                break;
1912            }
1913            case START_PROFILES_MSG: {
1914                synchronized (ActivityManagerService.this) {
1915                    mUserController.startProfilesLocked();
1916                }
1917                break;
1918            }
1919            case UPDATE_TIME: {
1920                synchronized (ActivityManagerService.this) {
1921                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1922                        ProcessRecord r = mLruProcesses.get(i);
1923                        if (r.thread != null) {
1924                            try {
1925                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1926                            } catch (RemoteException ex) {
1927                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1928                            }
1929                        }
1930                    }
1931                }
1932                break;
1933            }
1934            case SYSTEM_USER_START_MSG: {
1935                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1936                        Integer.toString(msg.arg1), msg.arg1);
1937                mSystemServiceManager.startUser(msg.arg1);
1938                break;
1939            }
1940            case SYSTEM_USER_UNLOCK_MSG: {
1941                final int userId = msg.arg1;
1942                mSystemServiceManager.unlockUser(userId);
1943                synchronized (ActivityManagerService.this) {
1944                    mRecentTasks.loadUserRecentsLocked(userId);
1945                }
1946                if (userId == UserHandle.USER_SYSTEM) {
1947                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1948                }
1949                installEncryptionUnawareProviders(userId);
1950                mUserController.finishUserUnlocked((UserState) msg.obj);
1951                break;
1952            }
1953            case SYSTEM_USER_CURRENT_MSG: {
1954                mBatteryStatsService.noteEvent(
1955                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1956                        Integer.toString(msg.arg2), msg.arg2);
1957                mBatteryStatsService.noteEvent(
1958                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1959                        Integer.toString(msg.arg1), msg.arg1);
1960                mSystemServiceManager.switchUser(msg.arg1);
1961                break;
1962            }
1963            case ENTER_ANIMATION_COMPLETE_MSG: {
1964                synchronized (ActivityManagerService.this) {
1965                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1966                    if (r != null && r.app != null && r.app.thread != null) {
1967                        try {
1968                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1969                        } catch (RemoteException e) {
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case FINISH_BOOTING_MSG: {
1976                if (msg.arg1 != 0) {
1977                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1978                    finishBooting();
1979                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1980                }
1981                if (msg.arg2 != 0) {
1982                    enableScreenAfterBoot();
1983                }
1984                break;
1985            }
1986            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1987                try {
1988                    Locale l = (Locale) msg.obj;
1989                    IBinder service = ServiceManager.getService("mount");
1990                    IMountService mountService = IMountService.Stub.asInterface(service);
1991                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1992                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1993                } catch (RemoteException e) {
1994                    Log.e(TAG, "Error storing locale for decryption UI", e);
1995                }
1996                break;
1997            }
1998            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1999                synchronized (ActivityManagerService.this) {
2000                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2001                        try {
2002                            // Make a one-way callback to the listener
2003                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2004                        } catch (RemoteException e){
2005                            // Handled by the RemoteCallbackList
2006                        }
2007                    }
2008                    mTaskStackListeners.finishBroadcast();
2009                }
2010                break;
2011            }
2012            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2013                synchronized (ActivityManagerService.this) {
2014                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2015                        try {
2016                            // Make a one-way callback to the listener
2017                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2018                        } catch (RemoteException e){
2019                            // Handled by the RemoteCallbackList
2020                        }
2021                    }
2022                    mTaskStackListeners.finishBroadcast();
2023                }
2024                break;
2025            }
2026            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2027                synchronized (ActivityManagerService.this) {
2028                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2029                        try {
2030                            // Make a one-way callback to the listener
2031                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2032                        } catch (RemoteException e){
2033                            // Handled by the RemoteCallbackList
2034                        }
2035                    }
2036                    mTaskStackListeners.finishBroadcast();
2037                }
2038                break;
2039            }
2040            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2041                synchronized (ActivityManagerService.this) {
2042                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2043                        try {
2044                            // Make a one-way callback to the listener
2045                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2046                        } catch (RemoteException e){
2047                            // Handled by the RemoteCallbackList
2048                        }
2049                    }
2050                    mTaskStackListeners.finishBroadcast();
2051                }
2052                break;
2053            }
2054            case NOTIFY_FORCED_RESIZABLE_MSG: {
2055                synchronized (ActivityManagerService.this) {
2056                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2057                        try {
2058                            // Make a one-way callback to the listener
2059                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2060                                    (String) msg.obj, msg.arg1);
2061                        } catch (RemoteException e){
2062                            // Handled by the RemoteCallbackList
2063                        }
2064                    }
2065                    mTaskStackListeners.finishBroadcast();
2066                }
2067                break;
2068            }
2069                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2070                    synchronized (ActivityManagerService.this) {
2071                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2072                            try {
2073                                // Make a one-way callback to the listener
2074                                mTaskStackListeners.getBroadcastItem(i)
2075                                        .onActivityDismissingDockedStack();
2076                            } catch (RemoteException e){
2077                                // Handled by the RemoteCallbackList
2078                            }
2079                        }
2080                        mTaskStackListeners.finishBroadcast();
2081                    }
2082                    break;
2083                }
2084            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2085                final int uid = msg.arg1;
2086                final byte[] firstPacket = (byte[]) msg.obj;
2087
2088                synchronized (mPidsSelfLocked) {
2089                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2090                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2091                        if (p.uid == uid) {
2092                            try {
2093                                p.thread.notifyCleartextNetwork(firstPacket);
2094                            } catch (RemoteException ignored) {
2095                            }
2096                        }
2097                    }
2098                }
2099                break;
2100            }
2101            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2102                final String procName;
2103                final int uid;
2104                final long memLimit;
2105                final String reportPackage;
2106                synchronized (ActivityManagerService.this) {
2107                    procName = mMemWatchDumpProcName;
2108                    uid = mMemWatchDumpUid;
2109                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2110                    if (val == null) {
2111                        val = mMemWatchProcesses.get(procName, 0);
2112                    }
2113                    if (val != null) {
2114                        memLimit = val.first;
2115                        reportPackage = val.second;
2116                    } else {
2117                        memLimit = 0;
2118                        reportPackage = null;
2119                    }
2120                }
2121                if (procName == null) {
2122                    return;
2123                }
2124
2125                if (DEBUG_PSS) Slog.d(TAG_PSS,
2126                        "Showing dump heap notification from " + procName + "/" + uid);
2127
2128                INotificationManager inm = NotificationManager.getService();
2129                if (inm == null) {
2130                    return;
2131                }
2132
2133                String text = mContext.getString(R.string.dump_heap_notification, procName);
2134
2135
2136                Intent deleteIntent = new Intent();
2137                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2138                Intent intent = new Intent();
2139                intent.setClassName("android", DumpHeapActivity.class.getName());
2140                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2141                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2142                if (reportPackage != null) {
2143                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2144                }
2145                int userId = UserHandle.getUserId(uid);
2146                Notification notification = new Notification.Builder(mContext)
2147                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2148                        .setWhen(0)
2149                        .setOngoing(true)
2150                        .setAutoCancel(true)
2151                        .setTicker(text)
2152                        .setColor(mContext.getColor(
2153                                com.android.internal.R.color.system_notification_accent_color))
2154                        .setContentTitle(text)
2155                        .setContentText(
2156                                mContext.getText(R.string.dump_heap_notification_detail))
2157                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2158                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2159                                new UserHandle(userId)))
2160                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2161                                deleteIntent, 0, UserHandle.SYSTEM))
2162                        .build();
2163
2164                try {
2165                    int[] outId = new int[1];
2166                    inm.enqueueNotificationWithTag("android", "android", null,
2167                            R.string.dump_heap_notification,
2168                            notification, outId, userId);
2169                } catch (RuntimeException e) {
2170                    Slog.w(ActivityManagerService.TAG,
2171                            "Error showing notification for dump heap", e);
2172                } catch (RemoteException e) {
2173                }
2174            } break;
2175            case DELETE_DUMPHEAP_MSG: {
2176                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2177                        DumpHeapActivity.JAVA_URI,
2178                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2179                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2180                        UserHandle.myUserId());
2181                synchronized (ActivityManagerService.this) {
2182                    mMemWatchDumpFile = null;
2183                    mMemWatchDumpProcName = null;
2184                    mMemWatchDumpPid = -1;
2185                    mMemWatchDumpUid = -1;
2186                }
2187            } break;
2188            case FOREGROUND_PROFILE_CHANGED_MSG: {
2189                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2190            } break;
2191            case REPORT_TIME_TRACKER_MSG: {
2192                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2193                tracker.deliverResult(mContext);
2194            } break;
2195            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2196                mUserController.dispatchUserSwitchComplete(msg.arg1);
2197            } break;
2198            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2199                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2200                try {
2201                    connection.shutdown();
2202                } catch (RemoteException e) {
2203                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2204                }
2205                // Only a UiAutomation can set this flag and now that
2206                // it is finished we make sure it is reset to its default.
2207                mUserIsMonkey = false;
2208            } break;
2209            case APP_BOOST_DEACTIVATE_MSG: {
2210                synchronized(ActivityManagerService.this) {
2211                    if (mIsBoosted) {
2212                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2213                            nativeMigrateFromBoost();
2214                            mIsBoosted = false;
2215                            mBoostStartTime = 0;
2216                        } else {
2217                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2218                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2219                        }
2220                    }
2221                }
2222            } break;
2223            case IDLE_UIDS_MSG: {
2224                idleUids();
2225            } break;
2226            case LOG_STACK_STATE: {
2227                synchronized (ActivityManagerService.this) {
2228                    mStackSupervisor.logStackState();
2229                }
2230            } break;
2231            case VR_MODE_CHANGE_MSG: {
2232                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2233                final ActivityRecord r = (ActivityRecord) msg.obj;
2234                boolean vrMode;
2235                ComponentName requestedPackage;
2236                ComponentName callingPackage;
2237                int userId;
2238                synchronized (ActivityManagerService.this) {
2239                    vrMode = r.requestedVrComponent != null;
2240                    requestedPackage = r.requestedVrComponent;
2241                    userId = r.userId;
2242                    callingPackage = r.info.getComponentName();
2243                    if (mInVrMode != vrMode) {
2244                        mInVrMode = vrMode;
2245                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2246                    }
2247                }
2248                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2249            } break;
2250            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2251                final ActivityRecord r = (ActivityRecord) msg.obj;
2252                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2253                if (needsVrMode) {
2254                    VrManagerInternal vrService =
2255                            LocalServices.getService(VrManagerInternal.class);
2256                    boolean enable = msg.arg1 == 1;
2257                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2258                            r.info.getComponentName());
2259                }
2260            } break;
2261            }
2262        }
2263    };
2264
2265    static final int COLLECT_PSS_BG_MSG = 1;
2266
2267    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2268        @Override
2269        public void handleMessage(Message msg) {
2270            switch (msg.what) {
2271            case COLLECT_PSS_BG_MSG: {
2272                long start = SystemClock.uptimeMillis();
2273                MemInfoReader memInfo = null;
2274                synchronized (ActivityManagerService.this) {
2275                    if (mFullPssPending) {
2276                        mFullPssPending = false;
2277                        memInfo = new MemInfoReader();
2278                    }
2279                }
2280                if (memInfo != null) {
2281                    updateCpuStatsNow();
2282                    long nativeTotalPss = 0;
2283                    synchronized (mProcessCpuTracker) {
2284                        final int N = mProcessCpuTracker.countStats();
2285                        for (int j=0; j<N; j++) {
2286                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2287                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2288                                // This is definitely an application process; skip it.
2289                                continue;
2290                            }
2291                            synchronized (mPidsSelfLocked) {
2292                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2293                                    // This is one of our own processes; skip it.
2294                                    continue;
2295                                }
2296                            }
2297                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2298                        }
2299                    }
2300                    memInfo.readMemInfo();
2301                    synchronized (ActivityManagerService.this) {
2302                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2303                                + (SystemClock.uptimeMillis()-start) + "ms");
2304                        final long cachedKb = memInfo.getCachedSizeKb();
2305                        final long freeKb = memInfo.getFreeSizeKb();
2306                        final long zramKb = memInfo.getZramTotalSizeKb();
2307                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2308                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2309                                kernelKb*1024, nativeTotalPss*1024);
2310                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2311                                nativeTotalPss);
2312                    }
2313                }
2314
2315                int num = 0;
2316                long[] tmp = new long[2];
2317                do {
2318                    ProcessRecord proc;
2319                    int procState;
2320                    int pid;
2321                    long lastPssTime;
2322                    synchronized (ActivityManagerService.this) {
2323                        if (mPendingPssProcesses.size() <= 0) {
2324                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2325                                    "Collected PSS of " + num + " processes in "
2326                                    + (SystemClock.uptimeMillis() - start) + "ms");
2327                            mPendingPssProcesses.clear();
2328                            return;
2329                        }
2330                        proc = mPendingPssProcesses.remove(0);
2331                        procState = proc.pssProcState;
2332                        lastPssTime = proc.lastPssTime;
2333                        if (proc.thread != null && procState == proc.setProcState
2334                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2335                                        < SystemClock.uptimeMillis()) {
2336                            pid = proc.pid;
2337                        } else {
2338                            proc = null;
2339                            pid = 0;
2340                        }
2341                    }
2342                    if (proc != null) {
2343                        long pss = Debug.getPss(pid, tmp, null);
2344                        synchronized (ActivityManagerService.this) {
2345                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2346                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2347                                num++;
2348                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2349                                        SystemClock.uptimeMillis());
2350                            }
2351                        }
2352                    }
2353                } while (true);
2354            }
2355            }
2356        }
2357    };
2358
2359    public void setSystemProcess() {
2360        try {
2361            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2362            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2363            ServiceManager.addService("meminfo", new MemBinder(this));
2364            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2365            ServiceManager.addService("dbinfo", new DbBinder(this));
2366            if (MONITOR_CPU_USAGE) {
2367                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2368            }
2369            ServiceManager.addService("permission", new PermissionController(this));
2370            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2371
2372            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2373                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2374            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2375
2376            synchronized (this) {
2377                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2378                app.persistent = true;
2379                app.pid = MY_PID;
2380                app.maxAdj = ProcessList.SYSTEM_ADJ;
2381                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2382                synchronized (mPidsSelfLocked) {
2383                    mPidsSelfLocked.put(app.pid, app);
2384                }
2385                updateLruProcessLocked(app, false, null);
2386                updateOomAdjLocked();
2387            }
2388        } catch (PackageManager.NameNotFoundException e) {
2389            throw new RuntimeException(
2390                    "Unable to find android system package", e);
2391        }
2392    }
2393
2394    public void setWindowManager(WindowManagerService wm) {
2395        mWindowManager = wm;
2396        mStackSupervisor.setWindowManager(wm);
2397        mActivityStarter.setWindowManager(wm);
2398    }
2399
2400    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2401        mUsageStatsService = usageStatsManager;
2402    }
2403
2404    public void startObservingNativeCrashes() {
2405        final NativeCrashListener ncl = new NativeCrashListener(this);
2406        ncl.start();
2407    }
2408
2409    public IAppOpsService getAppOpsService() {
2410        return mAppOpsService;
2411    }
2412
2413    static class MemBinder extends Binder {
2414        ActivityManagerService mActivityManagerService;
2415        MemBinder(ActivityManagerService activityManagerService) {
2416            mActivityManagerService = activityManagerService;
2417        }
2418
2419        @Override
2420        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2421            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2422                    != PackageManager.PERMISSION_GRANTED) {
2423                pw.println("Permission Denial: can't dump meminfo from from pid="
2424                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2425                        + " without permission " + android.Manifest.permission.DUMP);
2426                return;
2427            }
2428
2429            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2430        }
2431    }
2432
2433    static class GraphicsBinder extends Binder {
2434        ActivityManagerService mActivityManagerService;
2435        GraphicsBinder(ActivityManagerService activityManagerService) {
2436            mActivityManagerService = activityManagerService;
2437        }
2438
2439        @Override
2440        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2441            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2442                    != PackageManager.PERMISSION_GRANTED) {
2443                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2444                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2445                        + " without permission " + android.Manifest.permission.DUMP);
2446                return;
2447            }
2448
2449            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2450        }
2451    }
2452
2453    static class DbBinder extends Binder {
2454        ActivityManagerService mActivityManagerService;
2455        DbBinder(ActivityManagerService activityManagerService) {
2456            mActivityManagerService = activityManagerService;
2457        }
2458
2459        @Override
2460        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2461            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2462                    != PackageManager.PERMISSION_GRANTED) {
2463                pw.println("Permission Denial: can't dump dbinfo from from pid="
2464                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2465                        + " without permission " + android.Manifest.permission.DUMP);
2466                return;
2467            }
2468
2469            mActivityManagerService.dumpDbInfo(fd, pw, args);
2470        }
2471    }
2472
2473    static class CpuBinder extends Binder {
2474        ActivityManagerService mActivityManagerService;
2475        CpuBinder(ActivityManagerService activityManagerService) {
2476            mActivityManagerService = activityManagerService;
2477        }
2478
2479        @Override
2480        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2481            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2482                    != PackageManager.PERMISSION_GRANTED) {
2483                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2484                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2485                        + " without permission " + android.Manifest.permission.DUMP);
2486                return;
2487            }
2488
2489            synchronized (mActivityManagerService.mProcessCpuTracker) {
2490                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2491                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2492                        SystemClock.uptimeMillis()));
2493            }
2494        }
2495    }
2496
2497    public static final class Lifecycle extends SystemService {
2498        private final ActivityManagerService mService;
2499
2500        public Lifecycle(Context context) {
2501            super(context);
2502            mService = new ActivityManagerService(context);
2503        }
2504
2505        @Override
2506        public void onStart() {
2507            mService.start();
2508        }
2509
2510        public ActivityManagerService getService() {
2511            return mService;
2512        }
2513    }
2514
2515    // Note: This method is invoked on the main thread but may need to attach various
2516    // handlers to other threads.  So take care to be explicit about the looper.
2517    public ActivityManagerService(Context systemContext) {
2518        mContext = systemContext;
2519        mFactoryTest = FactoryTest.getMode();
2520        mSystemThread = ActivityThread.currentActivityThread();
2521
2522        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2523
2524        mHandlerThread = new ServiceThread(TAG,
2525                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2526        mHandlerThread.start();
2527        mHandler = new MainHandler(mHandlerThread.getLooper());
2528        mUiHandler = new UiHandler();
2529
2530        /* static; one-time init here */
2531        if (sKillHandler == null) {
2532            sKillThread = new ServiceThread(TAG + ":kill",
2533                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2534            sKillThread.start();
2535            sKillHandler = new KillHandler(sKillThread.getLooper());
2536        }
2537
2538        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2539                "foreground", BROADCAST_FG_TIMEOUT, false);
2540        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2541                "background", BROADCAST_BG_TIMEOUT, true);
2542        mBroadcastQueues[0] = mFgBroadcastQueue;
2543        mBroadcastQueues[1] = mBgBroadcastQueue;
2544
2545        mServices = new ActiveServices(this);
2546        mProviderMap = new ProviderMap(this);
2547        mAppErrors = new AppErrors(mContext, this);
2548
2549        // TODO: Move creation of battery stats service outside of activity manager service.
2550        File dataDir = Environment.getDataDirectory();
2551        File systemDir = new File(dataDir, "system");
2552        systemDir.mkdirs();
2553        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2554        mBatteryStatsService.getActiveStatistics().readLocked();
2555        mBatteryStatsService.scheduleWriteToDisk();
2556        mOnBattery = DEBUG_POWER ? true
2557                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2558        mBatteryStatsService.getActiveStatistics().setCallback(this);
2559
2560        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2561
2562        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2563        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2564                new IAppOpsCallback.Stub() {
2565                    @Override public void opChanged(int op, int uid, String packageName) {
2566                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2567                            if (mAppOpsService.checkOperation(op, uid, packageName)
2568                                    != AppOpsManager.MODE_ALLOWED) {
2569                                runInBackgroundDisabled(uid);
2570                            }
2571                        }
2572                    }
2573                });
2574
2575        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2576
2577        mUserController = new UserController(this);
2578
2579        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2580            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2581
2582        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2583
2584        mConfiguration.setToDefaults();
2585        mConfiguration.setLocales(LocaleList.getDefault());
2586
2587        mConfigurationSeq = mConfiguration.seq = 1;
2588        mProcessCpuTracker.init();
2589
2590        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2591        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2592        mStackSupervisor = new ActivityStackSupervisor(this);
2593        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2594        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2595
2596        mProcessCpuThread = new Thread("CpuTracker") {
2597            @Override
2598            public void run() {
2599                while (true) {
2600                    try {
2601                        try {
2602                            synchronized(this) {
2603                                final long now = SystemClock.uptimeMillis();
2604                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2605                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2606                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2607                                //        + ", write delay=" + nextWriteDelay);
2608                                if (nextWriteDelay < nextCpuDelay) {
2609                                    nextCpuDelay = nextWriteDelay;
2610                                }
2611                                if (nextCpuDelay > 0) {
2612                                    mProcessCpuMutexFree.set(true);
2613                                    this.wait(nextCpuDelay);
2614                                }
2615                            }
2616                        } catch (InterruptedException e) {
2617                        }
2618                        updateCpuStatsNow();
2619                    } catch (Exception e) {
2620                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2621                    }
2622                }
2623            }
2624        };
2625
2626        Watchdog.getInstance().addMonitor(this);
2627        Watchdog.getInstance().addThread(mHandler);
2628    }
2629
2630    public void setSystemServiceManager(SystemServiceManager mgr) {
2631        mSystemServiceManager = mgr;
2632    }
2633
2634    public void setInstaller(Installer installer) {
2635        mInstaller = installer;
2636    }
2637
2638    private void start() {
2639        Process.removeAllProcessGroups();
2640        mProcessCpuThread.start();
2641
2642        mBatteryStatsService.publish(mContext);
2643        mAppOpsService.publish(mContext);
2644        Slog.d("AppOps", "AppOpsService published");
2645        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2646    }
2647
2648    void onUserStoppedLocked(int userId) {
2649        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2650    }
2651
2652    public void initPowerManagement() {
2653        mStackSupervisor.initPowerManagement();
2654        mBatteryStatsService.initPowerManagement();
2655        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2656        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2657        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2658        mVoiceWakeLock.setReferenceCounted(false);
2659    }
2660
2661    @Override
2662    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2663            throws RemoteException {
2664        if (code == SYSPROPS_TRANSACTION) {
2665            // We need to tell all apps about the system property change.
2666            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2667            synchronized(this) {
2668                final int NP = mProcessNames.getMap().size();
2669                for (int ip=0; ip<NP; ip++) {
2670                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2671                    final int NA = apps.size();
2672                    for (int ia=0; ia<NA; ia++) {
2673                        ProcessRecord app = apps.valueAt(ia);
2674                        if (app.thread != null) {
2675                            procs.add(app.thread.asBinder());
2676                        }
2677                    }
2678                }
2679            }
2680
2681            int N = procs.size();
2682            for (int i=0; i<N; i++) {
2683                Parcel data2 = Parcel.obtain();
2684                try {
2685                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2686                } catch (RemoteException e) {
2687                }
2688                data2.recycle();
2689            }
2690        }
2691        try {
2692            return super.onTransact(code, data, reply, flags);
2693        } catch (RuntimeException e) {
2694            // The activity manager only throws security exceptions, so let's
2695            // log all others.
2696            if (!(e instanceof SecurityException)) {
2697                Slog.wtf(TAG, "Activity Manager Crash", e);
2698            }
2699            throw e;
2700        }
2701    }
2702
2703    void updateCpuStats() {
2704        final long now = SystemClock.uptimeMillis();
2705        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2706            return;
2707        }
2708        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2709            synchronized (mProcessCpuThread) {
2710                mProcessCpuThread.notify();
2711            }
2712        }
2713    }
2714
2715    void updateCpuStatsNow() {
2716        synchronized (mProcessCpuTracker) {
2717            mProcessCpuMutexFree.set(false);
2718            final long now = SystemClock.uptimeMillis();
2719            boolean haveNewCpuStats = false;
2720
2721            if (MONITOR_CPU_USAGE &&
2722                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2723                mLastCpuTime.set(now);
2724                mProcessCpuTracker.update();
2725                if (mProcessCpuTracker.hasGoodLastStats()) {
2726                    haveNewCpuStats = true;
2727                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2728                    //Slog.i(TAG, "Total CPU usage: "
2729                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2730
2731                    // Slog the cpu usage if the property is set.
2732                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2733                        int user = mProcessCpuTracker.getLastUserTime();
2734                        int system = mProcessCpuTracker.getLastSystemTime();
2735                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2736                        int irq = mProcessCpuTracker.getLastIrqTime();
2737                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2738                        int idle = mProcessCpuTracker.getLastIdleTime();
2739
2740                        int total = user + system + iowait + irq + softIrq + idle;
2741                        if (total == 0) total = 1;
2742
2743                        EventLog.writeEvent(EventLogTags.CPU,
2744                                ((user+system+iowait+irq+softIrq) * 100) / total,
2745                                (user * 100) / total,
2746                                (system * 100) / total,
2747                                (iowait * 100) / total,
2748                                (irq * 100) / total,
2749                                (softIrq * 100) / total);
2750                    }
2751                }
2752            }
2753
2754            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2755            synchronized(bstats) {
2756                synchronized(mPidsSelfLocked) {
2757                    if (haveNewCpuStats) {
2758                        if (bstats.startAddingCpuLocked()) {
2759                            int totalUTime = 0;
2760                            int totalSTime = 0;
2761                            final int N = mProcessCpuTracker.countStats();
2762                            for (int i=0; i<N; i++) {
2763                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2764                                if (!st.working) {
2765                                    continue;
2766                                }
2767                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2768                                totalUTime += st.rel_utime;
2769                                totalSTime += st.rel_stime;
2770                                if (pr != null) {
2771                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2772                                    if (ps == null || !ps.isActive()) {
2773                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2774                                                pr.info.uid, pr.processName);
2775                                    }
2776                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2777                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2778                                } else {
2779                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2780                                    if (ps == null || !ps.isActive()) {
2781                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2782                                                bstats.mapUid(st.uid), st.name);
2783                                    }
2784                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2785                                }
2786                            }
2787                            final int userTime = mProcessCpuTracker.getLastUserTime();
2788                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2789                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2790                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2791                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2792                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2793                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2794                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2795                        }
2796                    }
2797                }
2798
2799                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2800                    mLastWriteTime = now;
2801                    mBatteryStatsService.scheduleWriteToDisk();
2802                }
2803            }
2804        }
2805    }
2806
2807    @Override
2808    public void batteryNeedsCpuUpdate() {
2809        updateCpuStatsNow();
2810    }
2811
2812    @Override
2813    public void batteryPowerChanged(boolean onBattery) {
2814        // When plugging in, update the CPU stats first before changing
2815        // the plug state.
2816        updateCpuStatsNow();
2817        synchronized (this) {
2818            synchronized(mPidsSelfLocked) {
2819                mOnBattery = DEBUG_POWER ? true : onBattery;
2820            }
2821        }
2822    }
2823
2824    @Override
2825    public void batterySendBroadcast(Intent intent) {
2826        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2827                AppOpsManager.OP_NONE, null, false, false,
2828                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2829    }
2830
2831    /**
2832     * Initialize the application bind args. These are passed to each
2833     * process when the bindApplication() IPC is sent to the process. They're
2834     * lazily setup to make sure the services are running when they're asked for.
2835     */
2836    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2837        if (mAppBindArgs == null) {
2838            mAppBindArgs = new HashMap<>();
2839
2840            // Isolated processes won't get this optimization, so that we don't
2841            // violate the rules about which services they have access to.
2842            if (!isolated) {
2843                // Setup the application init args
2844                mAppBindArgs.put("package", ServiceManager.getService("package"));
2845                mAppBindArgs.put("window", ServiceManager.getService("window"));
2846                mAppBindArgs.put(Context.ALARM_SERVICE,
2847                        ServiceManager.getService(Context.ALARM_SERVICE));
2848            }
2849        }
2850        return mAppBindArgs;
2851    }
2852
2853    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2854        if (r == null || mFocusedActivity == r) {
2855            return false;
2856        }
2857
2858        if (!r.isFocusable()) {
2859            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2860            return false;
2861        }
2862
2863        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2864
2865        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2866        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2867                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2868        mDoingSetFocusedActivity = true;
2869
2870        final ActivityRecord last = mFocusedActivity;
2871        mFocusedActivity = r;
2872        if (r.task.isApplicationTask()) {
2873            if (mCurAppTimeTracker != r.appTimeTracker) {
2874                // We are switching app tracking.  Complete the current one.
2875                if (mCurAppTimeTracker != null) {
2876                    mCurAppTimeTracker.stop();
2877                    mHandler.obtainMessage(
2878                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2879                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2880                    mCurAppTimeTracker = null;
2881                }
2882                if (r.appTimeTracker != null) {
2883                    mCurAppTimeTracker = r.appTimeTracker;
2884                    startTimeTrackingFocusedActivityLocked();
2885                }
2886            } else {
2887                startTimeTrackingFocusedActivityLocked();
2888            }
2889        } else {
2890            r.appTimeTracker = null;
2891        }
2892        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2893        // TODO: Probably not, because we don't want to resume voice on switching
2894        // back to this activity
2895        if (r.task.voiceInteractor != null) {
2896            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2897        } else {
2898            finishRunningVoiceLocked();
2899            IVoiceInteractionSession session;
2900            if (last != null && ((session = last.task.voiceSession) != null
2901                    || (session = last.voiceSession) != null)) {
2902                // We had been in a voice interaction session, but now focused has
2903                // move to something different.  Just finish the session, we can't
2904                // return to it and retain the proper state and synchronization with
2905                // the voice interaction service.
2906                finishVoiceTask(session);
2907            }
2908        }
2909        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2910            mWindowManager.setFocusedApp(r.appToken, true);
2911        }
2912        applyUpdateLockStateLocked(r);
2913        applyUpdateVrModeLocked(r);
2914        if (mFocusedActivity.userId != mLastFocusedUserId) {
2915            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2916            mHandler.obtainMessage(
2917                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2918            mLastFocusedUserId = mFocusedActivity.userId;
2919        }
2920
2921        // Log a warning if the focused app is changed during the process. This could
2922        // indicate a problem of the focus setting logic!
2923        if (mFocusedActivity != r) Slog.w(TAG,
2924                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2925        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2926
2927        EventLogTags.writeAmFocusedActivity(
2928                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2929                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2930                reason);
2931        return true;
2932    }
2933
2934    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2935        if (mFocusedActivity != goingAway) {
2936            return;
2937        }
2938
2939        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2940        if (focusedStack != null) {
2941            final ActivityRecord top = focusedStack.topActivity();
2942            if (top != null && top.userId != mLastFocusedUserId) {
2943                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2944                mHandler.sendMessage(
2945                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2946                mLastFocusedUserId = top.userId;
2947            }
2948        }
2949
2950        // Try to move focus to another activity if possible.
2951        if (setFocusedActivityLocked(
2952                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2953            return;
2954        }
2955
2956        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2957                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2958        mFocusedActivity = null;
2959        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2960    }
2961
2962    @Override
2963    public void setFocusedStack(int stackId) {
2964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2965        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2966        final long callingId = Binder.clearCallingIdentity();
2967        try {
2968            synchronized (this) {
2969                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2970                if (stack == null) {
2971                    return;
2972                }
2973                final ActivityRecord r = stack.topRunningActivityLocked();
2974                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2975                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2976                }
2977            }
2978        } finally {
2979            Binder.restoreCallingIdentity(callingId);
2980        }
2981    }
2982
2983    @Override
2984    public void setFocusedTask(int taskId) {
2985        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2986        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2987        final long callingId = Binder.clearCallingIdentity();
2988        try {
2989            synchronized (this) {
2990                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2991                if (task == null) {
2992                    return;
2993                }
2994                final ActivityRecord r = task.topRunningActivityLocked();
2995                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2996                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2997                }
2998            }
2999        } finally {
3000            Binder.restoreCallingIdentity(callingId);
3001        }
3002    }
3003
3004    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3005    @Override
3006    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3007        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3008        synchronized (this) {
3009            if (listener != null) {
3010                mTaskStackListeners.register(listener);
3011            }
3012        }
3013    }
3014
3015    @Override
3016    public void notifyActivityDrawn(IBinder token) {
3017        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3018        synchronized (this) {
3019            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3020            if (r != null) {
3021                r.task.stack.notifyActivityDrawnLocked(r);
3022            }
3023        }
3024    }
3025
3026    final void applyUpdateLockStateLocked(ActivityRecord r) {
3027        // Modifications to the UpdateLock state are done on our handler, outside
3028        // the activity manager's locks.  The new state is determined based on the
3029        // state *now* of the relevant activity record.  The object is passed to
3030        // the handler solely for logging detail, not to be consulted/modified.
3031        final boolean nextState = r != null && r.immersive;
3032        mHandler.sendMessage(
3033                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3034    }
3035
3036    final void applyUpdateVrModeLocked(ActivityRecord r) {
3037        mHandler.sendMessage(
3038                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3039    }
3040
3041    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3044    }
3045
3046    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3047        Message msg = Message.obtain();
3048        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3049        msg.obj = r.task.askedCompatMode ? null : r;
3050        mUiHandler.sendMessage(msg);
3051    }
3052
3053    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3054            String what, Object obj, ProcessRecord srcApp) {
3055        app.lastActivityTime = now;
3056
3057        if (app.activities.size() > 0) {
3058            // Don't want to touch dependent processes that are hosting activities.
3059            return index;
3060        }
3061
3062        int lrui = mLruProcesses.lastIndexOf(app);
3063        if (lrui < 0) {
3064            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3065                    + what + " " + obj + " from " + srcApp);
3066            return index;
3067        }
3068
3069        if (lrui >= index) {
3070            // Don't want to cause this to move dependent processes *back* in the
3071            // list as if they were less frequently used.
3072            return index;
3073        }
3074
3075        if (lrui >= mLruProcessActivityStart) {
3076            // Don't want to touch dependent processes that are hosting activities.
3077            return index;
3078        }
3079
3080        mLruProcesses.remove(lrui);
3081        if (index > 0) {
3082            index--;
3083        }
3084        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3085                + " in LRU list: " + app);
3086        mLruProcesses.add(index, app);
3087        return index;
3088    }
3089
3090    static void killProcessGroup(int uid, int pid) {
3091        if (sKillHandler != null) {
3092            sKillHandler.sendMessage(
3093                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3094        } else {
3095            Slog.w(TAG, "Asked to kill process group before system bringup!");
3096            Process.killProcessGroup(uid, pid);
3097        }
3098    }
3099
3100    final void removeLruProcessLocked(ProcessRecord app) {
3101        int lrui = mLruProcesses.lastIndexOf(app);
3102        if (lrui >= 0) {
3103            if (!app.killed) {
3104                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3105                Process.killProcessQuiet(app.pid);
3106                killProcessGroup(app.uid, app.pid);
3107            }
3108            if (lrui <= mLruProcessActivityStart) {
3109                mLruProcessActivityStart--;
3110            }
3111            if (lrui <= mLruProcessServiceStart) {
3112                mLruProcessServiceStart--;
3113            }
3114            mLruProcesses.remove(lrui);
3115        }
3116    }
3117
3118    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3119            ProcessRecord client) {
3120        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3121                || app.treatLikeActivity;
3122        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3123        if (!activityChange && hasActivity) {
3124            // The process has activities, so we are only allowing activity-based adjustments
3125            // to move it.  It should be kept in the front of the list with other
3126            // processes that have activities, and we don't want those to change their
3127            // order except due to activity operations.
3128            return;
3129        }
3130
3131        mLruSeq++;
3132        final long now = SystemClock.uptimeMillis();
3133        app.lastActivityTime = now;
3134
3135        // First a quick reject: if the app is already at the position we will
3136        // put it, then there is nothing to do.
3137        if (hasActivity) {
3138            final int N = mLruProcesses.size();
3139            if (N > 0 && mLruProcesses.get(N-1) == app) {
3140                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3141                return;
3142            }
3143        } else {
3144            if (mLruProcessServiceStart > 0
3145                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3146                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3147                return;
3148            }
3149        }
3150
3151        int lrui = mLruProcesses.lastIndexOf(app);
3152
3153        if (app.persistent && lrui >= 0) {
3154            // We don't care about the position of persistent processes, as long as
3155            // they are in the list.
3156            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3157            return;
3158        }
3159
3160        /* In progress: compute new position first, so we can avoid doing work
3161           if the process is not actually going to move.  Not yet working.
3162        int addIndex;
3163        int nextIndex;
3164        boolean inActivity = false, inService = false;
3165        if (hasActivity) {
3166            // Process has activities, put it at the very tipsy-top.
3167            addIndex = mLruProcesses.size();
3168            nextIndex = mLruProcessServiceStart;
3169            inActivity = true;
3170        } else if (hasService) {
3171            // Process has services, put it at the top of the service list.
3172            addIndex = mLruProcessActivityStart;
3173            nextIndex = mLruProcessServiceStart;
3174            inActivity = true;
3175            inService = true;
3176        } else  {
3177            // Process not otherwise of interest, it goes to the top of the non-service area.
3178            addIndex = mLruProcessServiceStart;
3179            if (client != null) {
3180                int clientIndex = mLruProcesses.lastIndexOf(client);
3181                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3182                        + app);
3183                if (clientIndex >= 0 && addIndex > clientIndex) {
3184                    addIndex = clientIndex;
3185                }
3186            }
3187            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3188        }
3189
3190        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3191                + mLruProcessActivityStart + "): " + app);
3192        */
3193
3194        if (lrui >= 0) {
3195            if (lrui < mLruProcessActivityStart) {
3196                mLruProcessActivityStart--;
3197            }
3198            if (lrui < mLruProcessServiceStart) {
3199                mLruProcessServiceStart--;
3200            }
3201            /*
3202            if (addIndex > lrui) {
3203                addIndex--;
3204            }
3205            if (nextIndex > lrui) {
3206                nextIndex--;
3207            }
3208            */
3209            mLruProcesses.remove(lrui);
3210        }
3211
3212        /*
3213        mLruProcesses.add(addIndex, app);
3214        if (inActivity) {
3215            mLruProcessActivityStart++;
3216        }
3217        if (inService) {
3218            mLruProcessActivityStart++;
3219        }
3220        */
3221
3222        int nextIndex;
3223        if (hasActivity) {
3224            final int N = mLruProcesses.size();
3225            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3226                // Process doesn't have activities, but has clients with
3227                // activities...  move it up, but one below the top (the top
3228                // should always have a real activity).
3229                if (DEBUG_LRU) Slog.d(TAG_LRU,
3230                        "Adding to second-top of LRU activity list: " + app);
3231                mLruProcesses.add(N - 1, app);
3232                // To keep it from spamming the LRU list (by making a bunch of clients),
3233                // we will push down any other entries owned by the app.
3234                final int uid = app.info.uid;
3235                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3236                    ProcessRecord subProc = mLruProcesses.get(i);
3237                    if (subProc.info.uid == uid) {
3238                        // We want to push this one down the list.  If the process after
3239                        // it is for the same uid, however, don't do so, because we don't
3240                        // want them internally to be re-ordered.
3241                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3242                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3243                                    "Pushing uid " + uid + " swapping at " + i + ": "
3244                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3245                            ProcessRecord tmp = mLruProcesses.get(i);
3246                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3247                            mLruProcesses.set(i - 1, tmp);
3248                            i--;
3249                        }
3250                    } else {
3251                        // A gap, we can stop here.
3252                        break;
3253                    }
3254                }
3255            } else {
3256                // Process has activities, put it at the very tipsy-top.
3257                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3258                mLruProcesses.add(app);
3259            }
3260            nextIndex = mLruProcessServiceStart;
3261        } else if (hasService) {
3262            // Process has services, put it at the top of the service list.
3263            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3264            mLruProcesses.add(mLruProcessActivityStart, app);
3265            nextIndex = mLruProcessServiceStart;
3266            mLruProcessActivityStart++;
3267        } else  {
3268            // Process not otherwise of interest, it goes to the top of the non-service area.
3269            int index = mLruProcessServiceStart;
3270            if (client != null) {
3271                // If there is a client, don't allow the process to be moved up higher
3272                // in the list than that client.
3273                int clientIndex = mLruProcesses.lastIndexOf(client);
3274                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3275                        + " when updating " + app);
3276                if (clientIndex <= lrui) {
3277                    // Don't allow the client index restriction to push it down farther in the
3278                    // list than it already is.
3279                    clientIndex = lrui;
3280                }
3281                if (clientIndex >= 0 && index > clientIndex) {
3282                    index = clientIndex;
3283                }
3284            }
3285            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3286            mLruProcesses.add(index, app);
3287            nextIndex = index-1;
3288            mLruProcessActivityStart++;
3289            mLruProcessServiceStart++;
3290        }
3291
3292        // If the app is currently using a content provider or service,
3293        // bump those processes as well.
3294        for (int j=app.connections.size()-1; j>=0; j--) {
3295            ConnectionRecord cr = app.connections.valueAt(j);
3296            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3297                    && cr.binding.service.app != null
3298                    && cr.binding.service.app.lruSeq != mLruSeq
3299                    && !cr.binding.service.app.persistent) {
3300                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3301                        "service connection", cr, app);
3302            }
3303        }
3304        for (int j=app.conProviders.size()-1; j>=0; j--) {
3305            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3306            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3307                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3308                        "provider reference", cpr, app);
3309            }
3310        }
3311    }
3312
3313    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3314        if (uid == Process.SYSTEM_UID) {
3315            // The system gets to run in any process.  If there are multiple
3316            // processes with the same uid, just pick the first (this
3317            // should never happen).
3318            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3319            if (procs == null) return null;
3320            final int procCount = procs.size();
3321            for (int i = 0; i < procCount; i++) {
3322                final int procUid = procs.keyAt(i);
3323                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3324                    // Don't use an app process or different user process for system component.
3325                    continue;
3326                }
3327                return procs.valueAt(i);
3328            }
3329        }
3330        ProcessRecord proc = mProcessNames.get(processName, uid);
3331        if (false && proc != null && !keepIfLarge
3332                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3333                && proc.lastCachedPss >= 4000) {
3334            // Turn this condition on to cause killing to happen regularly, for testing.
3335            if (proc.baseProcessTracker != null) {
3336                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3337            }
3338            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3339        } else if (proc != null && !keepIfLarge
3340                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3341                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3342            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3343            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3344                if (proc.baseProcessTracker != null) {
3345                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3346                }
3347                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3348            }
3349        }
3350        return proc;
3351    }
3352
3353    void notifyPackageUse(String packageName, int reason) {
3354        IPackageManager pm = AppGlobals.getPackageManager();
3355        try {
3356            pm.notifyPackageUse(packageName, reason);
3357        } catch (RemoteException e) {
3358        }
3359    }
3360
3361    boolean isNextTransitionForward() {
3362        int transit = mWindowManager.getPendingAppTransition();
3363        return transit == TRANSIT_ACTIVITY_OPEN
3364                || transit == TRANSIT_TASK_OPEN
3365                || transit == TRANSIT_TASK_TO_FRONT;
3366    }
3367
3368    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3369            String processName, String abiOverride, int uid, Runnable crashHandler) {
3370        synchronized(this) {
3371            ApplicationInfo info = new ApplicationInfo();
3372            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3373            // For isolated processes, the former contains the parent's uid and the latter the
3374            // actual uid of the isolated process.
3375            // In the special case introduced by this method (which is, starting an isolated
3376            // process directly from the SystemServer without an actual parent app process) the
3377            // closest thing to a parent's uid is SYSTEM_UID.
3378            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3379            // the |isolated| logic in the ProcessRecord constructor.
3380            info.uid = Process.SYSTEM_UID;
3381            info.processName = processName;
3382            info.className = entryPoint;
3383            info.packageName = "android";
3384            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3385                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3386                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3387                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3388                    crashHandler);
3389            return proc != null ? proc.pid : 0;
3390        }
3391    }
3392
3393    final ProcessRecord startProcessLocked(String processName,
3394            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3395            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3396            boolean isolated, boolean keepIfLarge) {
3397        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3398                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3399                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3400                null /* crashHandler */);
3401    }
3402
3403    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3404            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3405            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3406            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3407        long startTime = SystemClock.elapsedRealtime();
3408        ProcessRecord app;
3409        if (!isolated) {
3410            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3411            checkTime(startTime, "startProcess: after getProcessRecord");
3412
3413            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3414                // If we are in the background, then check to see if this process
3415                // is bad.  If so, we will just silently fail.
3416                if (mAppErrors.isBadProcessLocked(info)) {
3417                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3418                            + "/" + info.processName);
3419                    return null;
3420                }
3421            } else {
3422                // When the user is explicitly starting a process, then clear its
3423                // crash count so that we won't make it bad until they see at
3424                // least one crash dialog again, and make the process good again
3425                // if it had been bad.
3426                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3427                        + "/" + info.processName);
3428                mAppErrors.resetProcessCrashTimeLocked(info);
3429                if (mAppErrors.isBadProcessLocked(info)) {
3430                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3431                            UserHandle.getUserId(info.uid), info.uid,
3432                            info.processName);
3433                    mAppErrors.clearBadProcessLocked(info);
3434                    if (app != null) {
3435                        app.bad = false;
3436                    }
3437                }
3438            }
3439        } else {
3440            // If this is an isolated process, it can't re-use an existing process.
3441            app = null;
3442        }
3443
3444        // app launch boost for big.little configurations
3445        // use cpusets to migrate freshly launched tasks to big cores
3446        synchronized(ActivityManagerService.this) {
3447            nativeMigrateToBoost();
3448            mIsBoosted = true;
3449            mBoostStartTime = SystemClock.uptimeMillis();
3450            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3451            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3452        }
3453
3454        // We don't have to do anything more if:
3455        // (1) There is an existing application record; and
3456        // (2) The caller doesn't think it is dead, OR there is no thread
3457        //     object attached to it so we know it couldn't have crashed; and
3458        // (3) There is a pid assigned to it, so it is either starting or
3459        //     already running.
3460        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3461                + " app=" + app + " knownToBeDead=" + knownToBeDead
3462                + " thread=" + (app != null ? app.thread : null)
3463                + " pid=" + (app != null ? app.pid : -1));
3464        if (app != null && app.pid > 0) {
3465            if (!knownToBeDead || app.thread == null) {
3466                // We already have the app running, or are waiting for it to
3467                // come up (we have a pid but not yet its thread), so keep it.
3468                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3469                // If this is a new package in the process, add the package to the list
3470                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3471                checkTime(startTime, "startProcess: done, added package to proc");
3472                return app;
3473            }
3474
3475            // An application record is attached to a previous process,
3476            // clean it up now.
3477            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3478            checkTime(startTime, "startProcess: bad proc running, killing");
3479            killProcessGroup(app.uid, app.pid);
3480            handleAppDiedLocked(app, true, true);
3481            checkTime(startTime, "startProcess: done killing old proc");
3482        }
3483
3484        String hostingNameStr = hostingName != null
3485                ? hostingName.flattenToShortString() : null;
3486
3487        if (app == null) {
3488            checkTime(startTime, "startProcess: creating new process record");
3489            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3490            if (app == null) {
3491                Slog.w(TAG, "Failed making new process record for "
3492                        + processName + "/" + info.uid + " isolated=" + isolated);
3493                return null;
3494            }
3495            app.crashHandler = crashHandler;
3496            checkTime(startTime, "startProcess: done creating new process record");
3497        } else {
3498            // If this is a new package in the process, add the package to the list
3499            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3500            checkTime(startTime, "startProcess: added package to existing proc");
3501        }
3502
3503        // If the system is not ready yet, then hold off on starting this
3504        // process until it is.
3505        if (!mProcessesReady
3506                && !isAllowedWhileBooting(info)
3507                && !allowWhileBooting) {
3508            if (!mProcessesOnHold.contains(app)) {
3509                mProcessesOnHold.add(app);
3510            }
3511            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3512                    "System not ready, putting on hold: " + app);
3513            checkTime(startTime, "startProcess: returning with proc on hold");
3514            return app;
3515        }
3516
3517        checkTime(startTime, "startProcess: stepping in to startProcess");
3518        startProcessLocked(
3519                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3520        checkTime(startTime, "startProcess: done starting proc!");
3521        return (app.pid != 0) ? app : null;
3522    }
3523
3524    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3525        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3526    }
3527
3528    private final void startProcessLocked(ProcessRecord app,
3529            String hostingType, String hostingNameStr) {
3530        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3531                null /* entryPoint */, null /* entryPointArgs */);
3532    }
3533
3534    private final void startProcessLocked(ProcessRecord app, String hostingType,
3535            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3536        long startTime = SystemClock.elapsedRealtime();
3537        if (app.pid > 0 && app.pid != MY_PID) {
3538            checkTime(startTime, "startProcess: removing from pids map");
3539            synchronized (mPidsSelfLocked) {
3540                mPidsSelfLocked.remove(app.pid);
3541                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3542            }
3543            checkTime(startTime, "startProcess: done removing from pids map");
3544            app.setPid(0);
3545        }
3546
3547        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3548                "startProcessLocked removing on hold: " + app);
3549        mProcessesOnHold.remove(app);
3550
3551        checkTime(startTime, "startProcess: starting to update cpu stats");
3552        updateCpuStats();
3553        checkTime(startTime, "startProcess: done updating cpu stats");
3554
3555        try {
3556            try {
3557                final int userId = UserHandle.getUserId(app.uid);
3558                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3559            } catch (RemoteException e) {
3560                throw e.rethrowAsRuntimeException();
3561            }
3562
3563            int uid = app.uid;
3564            int[] gids = null;
3565            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3566            if (!app.isolated) {
3567                int[] permGids = null;
3568                try {
3569                    checkTime(startTime, "startProcess: getting gids from package manager");
3570                    final IPackageManager pm = AppGlobals.getPackageManager();
3571                    permGids = pm.getPackageGids(app.info.packageName,
3572                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3573                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3574                            MountServiceInternal.class);
3575                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3576                            app.info.packageName);
3577                } catch (RemoteException e) {
3578                    throw e.rethrowAsRuntimeException();
3579                }
3580
3581                /*
3582                 * Add shared application and profile GIDs so applications can share some
3583                 * resources like shared libraries and access user-wide resources
3584                 */
3585                if (ArrayUtils.isEmpty(permGids)) {
3586                    gids = new int[2];
3587                } else {
3588                    gids = new int[permGids.length + 2];
3589                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3590                }
3591                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3592                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3593            }
3594            checkTime(startTime, "startProcess: building args");
3595            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3596                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3597                        && mTopComponent != null
3598                        && app.processName.equals(mTopComponent.getPackageName())) {
3599                    uid = 0;
3600                }
3601                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3602                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3603                    uid = 0;
3604                }
3605            }
3606            int debugFlags = 0;
3607            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3608                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3609                // Also turn on CheckJNI for debuggable apps. It's quite
3610                // awkward to turn on otherwise.
3611                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3612            }
3613            // Run the app in safe mode if its manifest requests so or the
3614            // system is booted in safe mode.
3615            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3616                mSafeMode == true) {
3617                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3618            }
3619            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3620                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3621            }
3622            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3623            if ("true".equals(genDebugInfoProperty)) {
3624                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3625            }
3626            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3627                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3628            }
3629            if ("1".equals(SystemProperties.get("debug.assert"))) {
3630                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3631            }
3632            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3633                // Enable all debug flags required by the native debugger.
3634                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3635                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3636                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3637                mNativeDebuggingApp = null;
3638            }
3639
3640            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3641            if (requiredAbi == null) {
3642                requiredAbi = Build.SUPPORTED_ABIS[0];
3643            }
3644
3645            String instructionSet = null;
3646            if (app.info.primaryCpuAbi != null) {
3647                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3648            }
3649
3650            app.gids = gids;
3651            app.requiredAbi = requiredAbi;
3652            app.instructionSet = instructionSet;
3653
3654            // Start the process.  It will either succeed and return a result containing
3655            // the PID of the new process, or else throw a RuntimeException.
3656            boolean isActivityProcess = (entryPoint == null);
3657            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3658            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3659                    app.processName);
3660            checkTime(startTime, "startProcess: asking zygote to start proc");
3661            Process.ProcessStartResult startResult = Process.start(entryPoint,
3662                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3663                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3664                    app.info.dataDir, entryPointArgs);
3665            checkTime(startTime, "startProcess: returned from zygote!");
3666            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3667
3668            if (app.isolated) {
3669                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3670            }
3671            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3672            checkTime(startTime, "startProcess: done updating battery stats");
3673
3674            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3675                    UserHandle.getUserId(uid), startResult.pid, uid,
3676                    app.processName, hostingType,
3677                    hostingNameStr != null ? hostingNameStr : "");
3678
3679            try {
3680                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3681                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3682            } catch (RemoteException ex) {
3683                // Ignore
3684            }
3685
3686            if (app.persistent) {
3687                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3688            }
3689
3690            checkTime(startTime, "startProcess: building log message");
3691            StringBuilder buf = mStringBuilder;
3692            buf.setLength(0);
3693            buf.append("Start proc ");
3694            buf.append(startResult.pid);
3695            buf.append(':');
3696            buf.append(app.processName);
3697            buf.append('/');
3698            UserHandle.formatUid(buf, uid);
3699            if (!isActivityProcess) {
3700                buf.append(" [");
3701                buf.append(entryPoint);
3702                buf.append("]");
3703            }
3704            buf.append(" for ");
3705            buf.append(hostingType);
3706            if (hostingNameStr != null) {
3707                buf.append(" ");
3708                buf.append(hostingNameStr);
3709            }
3710            Slog.i(TAG, buf.toString());
3711            app.setPid(startResult.pid);
3712            app.usingWrapper = startResult.usingWrapper;
3713            app.removed = false;
3714            app.killed = false;
3715            app.killedByAm = false;
3716            checkTime(startTime, "startProcess: starting to update pids map");
3717            synchronized (mPidsSelfLocked) {
3718                this.mPidsSelfLocked.put(startResult.pid, app);
3719                if (isActivityProcess) {
3720                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3721                    msg.obj = app;
3722                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3723                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3724                }
3725            }
3726            checkTime(startTime, "startProcess: done updating pids map");
3727        } catch (RuntimeException e) {
3728            // XXX do better error recovery.
3729            app.setPid(0);
3730            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3731            if (app.isolated) {
3732                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3733            }
3734            Slog.e(TAG, "Failure starting process " + app.processName, e);
3735        }
3736    }
3737
3738    void updateUsageStats(ActivityRecord component, boolean resumed) {
3739        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3740                "updateUsageStats: comp=" + component + "res=" + resumed);
3741        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3742        if (resumed) {
3743            if (mUsageStatsService != null) {
3744                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3745                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3746            }
3747            synchronized (stats) {
3748                stats.noteActivityResumedLocked(component.app.uid);
3749            }
3750        } else {
3751            if (mUsageStatsService != null) {
3752                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3753                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3754            }
3755            synchronized (stats) {
3756                stats.noteActivityPausedLocked(component.app.uid);
3757            }
3758        }
3759    }
3760
3761    Intent getHomeIntent() {
3762        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3763        intent.setComponent(mTopComponent);
3764        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3765        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3766            intent.addCategory(Intent.CATEGORY_HOME);
3767        }
3768        return intent;
3769    }
3770
3771    boolean startHomeActivityLocked(int userId, String reason) {
3772        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3773                && mTopAction == null) {
3774            // We are running in factory test mode, but unable to find
3775            // the factory test app, so just sit around displaying the
3776            // error message and don't try to start anything.
3777            return false;
3778        }
3779        Intent intent = getHomeIntent();
3780        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3781        if (aInfo != null) {
3782            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3783            // Don't do this if the home app is currently being
3784            // instrumented.
3785            aInfo = new ActivityInfo(aInfo);
3786            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3787            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3788                    aInfo.applicationInfo.uid, true);
3789            if (app == null || app.instrumentationClass == null) {
3790                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3791                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3792            }
3793        }
3794
3795        return true;
3796    }
3797
3798    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3799        ActivityInfo ai = null;
3800        ComponentName comp = intent.getComponent();
3801        try {
3802            if (comp != null) {
3803                // Factory test.
3804                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3805            } else {
3806                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3807                        intent,
3808                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3809                        flags, userId);
3810
3811                if (info != null) {
3812                    ai = info.activityInfo;
3813                }
3814            }
3815        } catch (RemoteException e) {
3816            // ignore
3817        }
3818
3819        return ai;
3820    }
3821
3822    /**
3823     * Starts the "new version setup screen" if appropriate.
3824     */
3825    void startSetupActivityLocked() {
3826        // Only do this once per boot.
3827        if (mCheckedForSetup) {
3828            return;
3829        }
3830
3831        // We will show this screen if the current one is a different
3832        // version than the last one shown, and we are not running in
3833        // low-level factory test mode.
3834        final ContentResolver resolver = mContext.getContentResolver();
3835        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3836                Settings.Global.getInt(resolver,
3837                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3838            mCheckedForSetup = true;
3839
3840            // See if we should be showing the platform update setup UI.
3841            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3842            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3843                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3844            if (!ris.isEmpty()) {
3845                final ResolveInfo ri = ris.get(0);
3846                String vers = ri.activityInfo.metaData != null
3847                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3848                        : null;
3849                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3850                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3851                            Intent.METADATA_SETUP_VERSION);
3852                }
3853                String lastVers = Settings.Secure.getString(
3854                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3855                if (vers != null && !vers.equals(lastVers)) {
3856                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3857                    intent.setComponent(new ComponentName(
3858                            ri.activityInfo.packageName, ri.activityInfo.name));
3859                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3860                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3861                            null, 0, 0, 0, null, false, false, null, null, null);
3862                }
3863            }
3864        }
3865    }
3866
3867    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3868        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3869    }
3870
3871    void enforceNotIsolatedCaller(String caller) {
3872        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3873            throw new SecurityException("Isolated process not allowed to call " + caller);
3874        }
3875    }
3876
3877    void enforceShellRestriction(String restriction, int userHandle) {
3878        if (Binder.getCallingUid() == Process.SHELL_UID) {
3879            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3880                throw new SecurityException("Shell does not have permission to access user "
3881                        + userHandle);
3882            }
3883        }
3884    }
3885
3886    @Override
3887    public int getFrontActivityScreenCompatMode() {
3888        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3889        synchronized (this) {
3890            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3891        }
3892    }
3893
3894    @Override
3895    public void setFrontActivityScreenCompatMode(int mode) {
3896        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3897                "setFrontActivityScreenCompatMode");
3898        synchronized (this) {
3899            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3900        }
3901    }
3902
3903    @Override
3904    public int getPackageScreenCompatMode(String packageName) {
3905        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3906        synchronized (this) {
3907            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3908        }
3909    }
3910
3911    @Override
3912    public void setPackageScreenCompatMode(String packageName, int mode) {
3913        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3914                "setPackageScreenCompatMode");
3915        synchronized (this) {
3916            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3917        }
3918    }
3919
3920    @Override
3921    public boolean getPackageAskScreenCompat(String packageName) {
3922        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3923        synchronized (this) {
3924            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3925        }
3926    }
3927
3928    @Override
3929    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3930        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3931                "setPackageAskScreenCompat");
3932        synchronized (this) {
3933            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3934        }
3935    }
3936
3937    private boolean hasUsageStatsPermission(String callingPackage) {
3938        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3939                Binder.getCallingUid(), callingPackage);
3940        if (mode == AppOpsManager.MODE_DEFAULT) {
3941            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3942                    == PackageManager.PERMISSION_GRANTED;
3943        }
3944        return mode == AppOpsManager.MODE_ALLOWED;
3945    }
3946
3947    @Override
3948    public int getPackageProcessState(String packageName, String callingPackage) {
3949        if (!hasUsageStatsPermission(callingPackage)) {
3950            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3951                    "getPackageProcessState");
3952        }
3953
3954        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3955        synchronized (this) {
3956            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3957                final ProcessRecord proc = mLruProcesses.get(i);
3958                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3959                        || procState > proc.setProcState) {
3960                    boolean found = false;
3961                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3962                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3963                            procState = proc.setProcState;
3964                            found = true;
3965                        }
3966                    }
3967                    if (proc.pkgDeps != null && !found) {
3968                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3969                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3970                                procState = proc.setProcState;
3971                                break;
3972                            }
3973                        }
3974                    }
3975                }
3976            }
3977        }
3978        return procState;
3979    }
3980
3981    @Override
3982    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3983        synchronized (this) {
3984            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3985            if (app == null) {
3986                return false;
3987            }
3988            if (app.trimMemoryLevel < level && app.thread != null &&
3989                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3990                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3991                try {
3992                    app.thread.scheduleTrimMemory(level);
3993                    app.trimMemoryLevel = level;
3994                    return true;
3995                } catch (RemoteException e) {
3996                    // Fallthrough to failure case.
3997                }
3998            }
3999        }
4000        return false;
4001    }
4002
4003    private void dispatchProcessesChanged() {
4004        int N;
4005        synchronized (this) {
4006            N = mPendingProcessChanges.size();
4007            if (mActiveProcessChanges.length < N) {
4008                mActiveProcessChanges = new ProcessChangeItem[N];
4009            }
4010            mPendingProcessChanges.toArray(mActiveProcessChanges);
4011            mPendingProcessChanges.clear();
4012            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4013                    "*** Delivering " + N + " process changes");
4014        }
4015
4016        int i = mProcessObservers.beginBroadcast();
4017        while (i > 0) {
4018            i--;
4019            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4020            if (observer != null) {
4021                try {
4022                    for (int j=0; j<N; j++) {
4023                        ProcessChangeItem item = mActiveProcessChanges[j];
4024                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4025                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4026                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4027                                    + item.uid + ": " + item.foregroundActivities);
4028                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4029                                    item.foregroundActivities);
4030                        }
4031                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4032                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4033                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4034                                    + ": " + item.processState);
4035                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4036                        }
4037                    }
4038                } catch (RemoteException e) {
4039                }
4040            }
4041        }
4042        mProcessObservers.finishBroadcast();
4043
4044        synchronized (this) {
4045            for (int j=0; j<N; j++) {
4046                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4047            }
4048        }
4049    }
4050
4051    private void dispatchProcessDied(int pid, int uid) {
4052        int i = mProcessObservers.beginBroadcast();
4053        while (i > 0) {
4054            i--;
4055            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4056            if (observer != null) {
4057                try {
4058                    observer.onProcessDied(pid, uid);
4059                } catch (RemoteException e) {
4060                }
4061            }
4062        }
4063        mProcessObservers.finishBroadcast();
4064    }
4065
4066    private void dispatchUidsChanged() {
4067        int N;
4068        synchronized (this) {
4069            N = mPendingUidChanges.size();
4070            if (mActiveUidChanges.length < N) {
4071                mActiveUidChanges = new UidRecord.ChangeItem[N];
4072            }
4073            for (int i=0; i<N; i++) {
4074                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4075                mActiveUidChanges[i] = change;
4076                if (change.uidRecord != null) {
4077                    change.uidRecord.pendingChange = null;
4078                    change.uidRecord = null;
4079                }
4080            }
4081            mPendingUidChanges.clear();
4082            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4083                    "*** Delivering " + N + " uid changes");
4084        }
4085
4086        if (mLocalPowerManager != null) {
4087            for (int j=0; j<N; j++) {
4088                UidRecord.ChangeItem item = mActiveUidChanges[j];
4089                if (item.change == UidRecord.CHANGE_GONE
4090                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4091                    mLocalPowerManager.uidGone(item.uid);
4092                } else {
4093                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4094                }
4095            }
4096        }
4097
4098        int i = mUidObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4102            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4103            if (observer != null) {
4104                try {
4105                    for (int j=0; j<N; j++) {
4106                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4107                        final int change = item.change;
4108                        UidRecord validateUid = null;
4109                        if (VALIDATE_UID_STATES && i == 0) {
4110                            validateUid = mValidateUids.get(item.uid);
4111                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4112                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4113                                validateUid = new UidRecord(item.uid);
4114                                mValidateUids.put(item.uid, validateUid);
4115                            }
4116                        }
4117                        if (change == UidRecord.CHANGE_IDLE
4118                                || change == UidRecord.CHANGE_GONE_IDLE) {
4119                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4120                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4121                                        "UID idle uid=" + item.uid);
4122                                observer.onUidIdle(item.uid);
4123                            }
4124                            if (VALIDATE_UID_STATES && i == 0) {
4125                                if (validateUid != null) {
4126                                    validateUid.idle = true;
4127                                }
4128                            }
4129                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4130                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4131                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4132                                        "UID active uid=" + item.uid);
4133                                observer.onUidActive(item.uid);
4134                            }
4135                            if (VALIDATE_UID_STATES && i == 0) {
4136                                validateUid.idle = false;
4137                            }
4138                        }
4139                        if (change == UidRecord.CHANGE_GONE
4140                                || change == UidRecord.CHANGE_GONE_IDLE) {
4141                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4142                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4143                                        "UID gone uid=" + item.uid);
4144                                observer.onUidGone(item.uid);
4145                            }
4146                            if (VALIDATE_UID_STATES && i == 0) {
4147                                if (validateUid != null) {
4148                                    mValidateUids.remove(item.uid);
4149                                }
4150                            }
4151                        } else {
4152                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4153                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4154                                        "UID CHANGED uid=" + item.uid
4155                                                + ": " + item.processState);
4156                                observer.onUidStateChanged(item.uid, item.processState);
4157                            }
4158                            if (VALIDATE_UID_STATES && i == 0) {
4159                                validateUid.curProcState = validateUid.setProcState
4160                                        = item.processState;
4161                            }
4162                        }
4163                    }
4164                } catch (RemoteException e) {
4165                }
4166            }
4167        }
4168        mUidObservers.finishBroadcast();
4169
4170        synchronized (this) {
4171            for (int j=0; j<N; j++) {
4172                mAvailUidChanges.add(mActiveUidChanges[j]);
4173            }
4174        }
4175    }
4176
4177    @Override
4178    public final int startActivity(IApplicationThread caller, String callingPackage,
4179            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4180            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4181        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4182                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4183                UserHandle.getCallingUserId());
4184    }
4185
4186    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4187        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4188        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4189                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4190                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4191
4192        // TODO: Switch to user app stacks here.
4193        String mimeType = intent.getType();
4194        final Uri data = intent.getData();
4195        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4196            mimeType = getProviderMimeType(data, userId);
4197        }
4198        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4199
4200        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4201        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4202                null, 0, 0, null, null, null, null, false, userId, container, null);
4203    }
4204
4205    @Override
4206    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4207            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4208            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4209        enforceNotIsolatedCaller("startActivity");
4210        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4211                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4212        // TODO: Switch to user app stacks here.
4213        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4214                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4215                profilerInfo, null, null, bOptions, false, userId, null, null);
4216    }
4217
4218    @Override
4219    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4220            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4221            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4222            int userId) {
4223
4224        // This is very dangerous -- it allows you to perform a start activity (including
4225        // permission grants) as any app that may launch one of your own activities.  So
4226        // we will only allow this to be done from activities that are part of the core framework,
4227        // and then only when they are running as the system.
4228        final ActivityRecord sourceRecord;
4229        final int targetUid;
4230        final String targetPackage;
4231        synchronized (this) {
4232            if (resultTo == null) {
4233                throw new SecurityException("Must be called from an activity");
4234            }
4235            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4236            if (sourceRecord == null) {
4237                throw new SecurityException("Called with bad activity token: " + resultTo);
4238            }
4239            if (!sourceRecord.info.packageName.equals("android")) {
4240                throw new SecurityException(
4241                        "Must be called from an activity that is declared in the android package");
4242            }
4243            if (sourceRecord.app == null) {
4244                throw new SecurityException("Called without a process attached to activity");
4245            }
4246            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4247                // This is still okay, as long as this activity is running under the
4248                // uid of the original calling activity.
4249                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4250                    throw new SecurityException(
4251                            "Calling activity in uid " + sourceRecord.app.uid
4252                                    + " must be system uid or original calling uid "
4253                                    + sourceRecord.launchedFromUid);
4254                }
4255            }
4256            if (ignoreTargetSecurity) {
4257                if (intent.getComponent() == null) {
4258                    throw new SecurityException(
4259                            "Component must be specified with ignoreTargetSecurity");
4260                }
4261                if (intent.getSelector() != null) {
4262                    throw new SecurityException(
4263                            "Selector not allowed with ignoreTargetSecurity");
4264                }
4265            }
4266            targetUid = sourceRecord.launchedFromUid;
4267            targetPackage = sourceRecord.launchedFromPackage;
4268        }
4269
4270        if (userId == UserHandle.USER_NULL) {
4271            userId = UserHandle.getUserId(sourceRecord.app.uid);
4272        }
4273
4274        // TODO: Switch to user app stacks here.
4275        try {
4276            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4277                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4278                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4279            return ret;
4280        } catch (SecurityException e) {
4281            // XXX need to figure out how to propagate to original app.
4282            // A SecurityException here is generally actually a fault of the original
4283            // calling activity (such as a fairly granting permissions), so propagate it
4284            // back to them.
4285            /*
4286            StringBuilder msg = new StringBuilder();
4287            msg.append("While launching");
4288            msg.append(intent.toString());
4289            msg.append(": ");
4290            msg.append(e.getMessage());
4291            */
4292            throw e;
4293        }
4294    }
4295
4296    @Override
4297    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4298            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4299            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4300        enforceNotIsolatedCaller("startActivityAndWait");
4301        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4302                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4303        WaitResult res = new WaitResult();
4304        // TODO: Switch to user app stacks here.
4305        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4306                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4307                bOptions, false, userId, null, null);
4308        return res;
4309    }
4310
4311    @Override
4312    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4313            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4314            int startFlags, Configuration config, Bundle bOptions, int userId) {
4315        enforceNotIsolatedCaller("startActivityWithConfig");
4316        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4317                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4318        // TODO: Switch to user app stacks here.
4319        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4320                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4321                null, null, config, bOptions, false, userId, null, null);
4322        return ret;
4323    }
4324
4325    @Override
4326    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4327            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4328            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4329            throws TransactionTooLargeException {
4330        enforceNotIsolatedCaller("startActivityIntentSender");
4331        // Refuse possible leaked file descriptors
4332        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4333            throw new IllegalArgumentException("File descriptors passed in Intent");
4334        }
4335
4336        IIntentSender sender = intent.getTarget();
4337        if (!(sender instanceof PendingIntentRecord)) {
4338            throw new IllegalArgumentException("Bad PendingIntent object");
4339        }
4340
4341        PendingIntentRecord pir = (PendingIntentRecord)sender;
4342
4343        synchronized (this) {
4344            // If this is coming from the currently resumed activity, it is
4345            // effectively saying that app switches are allowed at this point.
4346            final ActivityStack stack = getFocusedStack();
4347            if (stack.mResumedActivity != null &&
4348                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4349                mAppSwitchesAllowedTime = 0;
4350            }
4351        }
4352        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4353                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4354        return ret;
4355    }
4356
4357    @Override
4358    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4359            Intent intent, String resolvedType, IVoiceInteractionSession session,
4360            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4361            Bundle bOptions, int userId) {
4362        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4363                != PackageManager.PERMISSION_GRANTED) {
4364            String msg = "Permission Denial: startVoiceActivity() from pid="
4365                    + Binder.getCallingPid()
4366                    + ", uid=" + Binder.getCallingUid()
4367                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4368            Slog.w(TAG, msg);
4369            throw new SecurityException(msg);
4370        }
4371        if (session == null || interactor == null) {
4372            throw new NullPointerException("null session or interactor");
4373        }
4374        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4375                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4376        // TODO: Switch to user app stacks here.
4377        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4378                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4379                null, bOptions, false, userId, null, null);
4380    }
4381
4382    @Override
4383    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4384            throws RemoteException {
4385        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4386        synchronized (this) {
4387            ActivityRecord activity = getFocusedStack().topActivity();
4388            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4389                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4390            }
4391            if (mRunningVoice != null || activity.task.voiceSession != null
4392                    || activity.voiceSession != null) {
4393                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4394                return;
4395            }
4396            if (activity.pendingVoiceInteractionStart) {
4397                Slog.w(TAG, "Pending start of voice interaction already.");
4398                return;
4399            }
4400            activity.pendingVoiceInteractionStart = true;
4401        }
4402        LocalServices.getService(VoiceInteractionManagerInternal.class)
4403                .startLocalVoiceInteraction(callingActivity, options);
4404    }
4405
4406    @Override
4407    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4408        LocalServices.getService(VoiceInteractionManagerInternal.class)
4409                .stopLocalVoiceInteraction(callingActivity);
4410    }
4411
4412    @Override
4413    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4414        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4415                .supportsLocalVoiceInteraction();
4416    }
4417
4418    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4419            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4420        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4421        if (activityToCallback == null) return;
4422        activityToCallback.setVoiceSessionLocked(voiceSession);
4423
4424        // Inform the activity
4425        try {
4426            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4427                    voiceInteractor);
4428            long token = Binder.clearCallingIdentity();
4429            try {
4430                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4431            } finally {
4432                Binder.restoreCallingIdentity(token);
4433            }
4434            // TODO: VI Should we cache the activity so that it's easier to find later
4435            // rather than scan through all the stacks and activities?
4436        } catch (RemoteException re) {
4437            activityToCallback.clearVoiceSessionLocked();
4438            // TODO: VI Should this terminate the voice session?
4439        }
4440    }
4441
4442    @Override
4443    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4444        synchronized (this) {
4445            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4446                if (keepAwake) {
4447                    mVoiceWakeLock.acquire();
4448                } else {
4449                    mVoiceWakeLock.release();
4450                }
4451            }
4452        }
4453    }
4454
4455    @Override
4456    public boolean startNextMatchingActivity(IBinder callingActivity,
4457            Intent intent, Bundle bOptions) {
4458        // Refuse possible leaked file descriptors
4459        if (intent != null && intent.hasFileDescriptors() == true) {
4460            throw new IllegalArgumentException("File descriptors passed in Intent");
4461        }
4462        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4463
4464        synchronized (this) {
4465            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4466            if (r == null) {
4467                ActivityOptions.abort(options);
4468                return false;
4469            }
4470            if (r.app == null || r.app.thread == null) {
4471                // The caller is not running...  d'oh!
4472                ActivityOptions.abort(options);
4473                return false;
4474            }
4475            intent = new Intent(intent);
4476            // The caller is not allowed to change the data.
4477            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4478            // And we are resetting to find the next component...
4479            intent.setComponent(null);
4480
4481            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4482
4483            ActivityInfo aInfo = null;
4484            try {
4485                List<ResolveInfo> resolves =
4486                    AppGlobals.getPackageManager().queryIntentActivities(
4487                            intent, r.resolvedType,
4488                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4489                            UserHandle.getCallingUserId()).getList();
4490
4491                // Look for the original activity in the list...
4492                final int N = resolves != null ? resolves.size() : 0;
4493                for (int i=0; i<N; i++) {
4494                    ResolveInfo rInfo = resolves.get(i);
4495                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4496                            && rInfo.activityInfo.name.equals(r.info.name)) {
4497                        // We found the current one...  the next matching is
4498                        // after it.
4499                        i++;
4500                        if (i<N) {
4501                            aInfo = resolves.get(i).activityInfo;
4502                        }
4503                        if (debug) {
4504                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4505                                    + "/" + r.info.name);
4506                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4507                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4508                        }
4509                        break;
4510                    }
4511                }
4512            } catch (RemoteException e) {
4513            }
4514
4515            if (aInfo == null) {
4516                // Nobody who is next!
4517                ActivityOptions.abort(options);
4518                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4519                return false;
4520            }
4521
4522            intent.setComponent(new ComponentName(
4523                    aInfo.applicationInfo.packageName, aInfo.name));
4524            intent.setFlags(intent.getFlags()&~(
4525                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4526                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4527                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4528                    Intent.FLAG_ACTIVITY_NEW_TASK));
4529
4530            // Okay now we need to start the new activity, replacing the
4531            // currently running activity.  This is a little tricky because
4532            // we want to start the new one as if the current one is finished,
4533            // but not finish the current one first so that there is no flicker.
4534            // And thus...
4535            final boolean wasFinishing = r.finishing;
4536            r.finishing = true;
4537
4538            // Propagate reply information over to the new activity.
4539            final ActivityRecord resultTo = r.resultTo;
4540            final String resultWho = r.resultWho;
4541            final int requestCode = r.requestCode;
4542            r.resultTo = null;
4543            if (resultTo != null) {
4544                resultTo.removeResultsLocked(r, resultWho, requestCode);
4545            }
4546
4547            final long origId = Binder.clearCallingIdentity();
4548            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4549                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4550                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4551                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4552                    false, false, null, null, null);
4553            Binder.restoreCallingIdentity(origId);
4554
4555            r.finishing = wasFinishing;
4556            if (res != ActivityManager.START_SUCCESS) {
4557                return false;
4558            }
4559            return true;
4560        }
4561    }
4562
4563    @Override
4564    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4565        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4566            String msg = "Permission Denial: startActivityFromRecents called without " +
4567                    START_TASKS_FROM_RECENTS;
4568            Slog.w(TAG, msg);
4569            throw new SecurityException(msg);
4570        }
4571        final long origId = Binder.clearCallingIdentity();
4572        try {
4573            synchronized (this) {
4574                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4575            }
4576        } finally {
4577            Binder.restoreCallingIdentity(origId);
4578        }
4579    }
4580
4581    final int startActivityInPackage(int uid, String callingPackage,
4582            Intent intent, String resolvedType, IBinder resultTo,
4583            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4584            IActivityContainer container, TaskRecord inTask) {
4585
4586        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4588
4589        // TODO: Switch to user app stacks here.
4590        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4591                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4592                null, null, null, bOptions, false, userId, container, inTask);
4593        return ret;
4594    }
4595
4596    @Override
4597    public final int startActivities(IApplicationThread caller, String callingPackage,
4598            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4599            int userId) {
4600        enforceNotIsolatedCaller("startActivities");
4601        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4602                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4603        // TODO: Switch to user app stacks here.
4604        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4605                resolvedTypes, resultTo, bOptions, userId);
4606        return ret;
4607    }
4608
4609    final int startActivitiesInPackage(int uid, String callingPackage,
4610            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4611            Bundle bOptions, int userId) {
4612
4613        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4614                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4615        // TODO: Switch to user app stacks here.
4616        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4617                resultTo, bOptions, userId);
4618        return ret;
4619    }
4620
4621    @Override
4622    public void reportActivityFullyDrawn(IBinder token) {
4623        synchronized (this) {
4624            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4625            if (r == null) {
4626                return;
4627            }
4628            r.reportFullyDrawnLocked();
4629        }
4630    }
4631
4632    @Override
4633    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4634        synchronized (this) {
4635            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4636            if (r == null) {
4637                return;
4638            }
4639            TaskRecord task = r.task;
4640            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4641                // Fixed screen orientation isn't supported when activities aren't in full screen
4642                // mode.
4643                return;
4644            }
4645            final long origId = Binder.clearCallingIdentity();
4646            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4647            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4648                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4649            if (config != null) {
4650                r.frozenBeforeDestroy = true;
4651                if (!updateConfigurationLocked(config, r, false)) {
4652                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4653                }
4654            }
4655            Binder.restoreCallingIdentity(origId);
4656        }
4657    }
4658
4659    @Override
4660    public int getRequestedOrientation(IBinder token) {
4661        synchronized (this) {
4662            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4663            if (r == null) {
4664                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4665            }
4666            return mWindowManager.getAppOrientation(r.appToken);
4667        }
4668    }
4669
4670    /**
4671     * This is the internal entry point for handling Activity.finish().
4672     *
4673     * @param token The Binder token referencing the Activity we want to finish.
4674     * @param resultCode Result code, if any, from this Activity.
4675     * @param resultData Result data (Intent), if any, from this Activity.
4676     * @param finishTask Whether to finish the task associated with this Activity.
4677     *
4678     * @return Returns true if the activity successfully finished, or false if it is still running.
4679     */
4680    @Override
4681    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4682            int finishTask) {
4683        // Refuse possible leaked file descriptors
4684        if (resultData != null && resultData.hasFileDescriptors() == true) {
4685            throw new IllegalArgumentException("File descriptors passed in Intent");
4686        }
4687
4688        synchronized(this) {
4689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4690            if (r == null) {
4691                return true;
4692            }
4693            // Keep track of the root activity of the task before we finish it
4694            TaskRecord tr = r.task;
4695            ActivityRecord rootR = tr.getRootActivity();
4696            if (rootR == null) {
4697                Slog.w(TAG, "Finishing task with all activities already finished");
4698            }
4699            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4700            // finish.
4701            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4702                    mStackSupervisor.isLastLockedTask(tr)) {
4703                Slog.i(TAG, "Not finishing task in lock task mode");
4704                mStackSupervisor.showLockTaskToast();
4705                return false;
4706            }
4707            if (mController != null) {
4708                // Find the first activity that is not finishing.
4709                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4710                if (next != null) {
4711                    // ask watcher if this is allowed
4712                    boolean resumeOK = true;
4713                    try {
4714                        resumeOK = mController.activityResuming(next.packageName);
4715                    } catch (RemoteException e) {
4716                        mController = null;
4717                        Watchdog.getInstance().setActivityController(null);
4718                    }
4719
4720                    if (!resumeOK) {
4721                        Slog.i(TAG, "Not finishing activity because controller resumed");
4722                        return false;
4723                    }
4724                }
4725            }
4726            final long origId = Binder.clearCallingIdentity();
4727            try {
4728                boolean res;
4729                final boolean finishWithRootActivity =
4730                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4731                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4732                        || (finishWithRootActivity && r == rootR)) {
4733                    // If requested, remove the task that is associated to this activity only if it
4734                    // was the root activity in the task. The result code and data is ignored
4735                    // because we don't support returning them across task boundaries. Also, to
4736                    // keep backwards compatibility we remove the task from recents when finishing
4737                    // task with root activity.
4738                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4739                    if (!res) {
4740                        Slog.i(TAG, "Removing task failed to finish activity");
4741                    }
4742                } else {
4743                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4744                            resultData, "app-request", true);
4745                    if (!res) {
4746                        Slog.i(TAG, "Failed to finish by app-request");
4747                    }
4748                }
4749                return res;
4750            } finally {
4751                Binder.restoreCallingIdentity(origId);
4752            }
4753        }
4754    }
4755
4756    @Override
4757    public final void finishHeavyWeightApp() {
4758        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4759                != PackageManager.PERMISSION_GRANTED) {
4760            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4761                    + Binder.getCallingPid()
4762                    + ", uid=" + Binder.getCallingUid()
4763                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4764            Slog.w(TAG, msg);
4765            throw new SecurityException(msg);
4766        }
4767
4768        synchronized(this) {
4769            if (mHeavyWeightProcess == null) {
4770                return;
4771            }
4772
4773            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4774            for (int i = 0; i < activities.size(); i++) {
4775                ActivityRecord r = activities.get(i);
4776                if (!r.finishing && r.isInStackLocked()) {
4777                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4778                            null, "finish-heavy", true);
4779                }
4780            }
4781
4782            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4783                    mHeavyWeightProcess.userId, 0));
4784            mHeavyWeightProcess = null;
4785        }
4786    }
4787
4788    @Override
4789    public void crashApplication(int uid, int initialPid, String packageName,
4790            String message) {
4791        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4792                != PackageManager.PERMISSION_GRANTED) {
4793            String msg = "Permission Denial: crashApplication() from pid="
4794                    + Binder.getCallingPid()
4795                    + ", uid=" + Binder.getCallingUid()
4796                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4797            Slog.w(TAG, msg);
4798            throw new SecurityException(msg);
4799        }
4800
4801        synchronized(this) {
4802            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4803        }
4804    }
4805
4806    @Override
4807    public final void finishSubActivity(IBinder token, String resultWho,
4808            int requestCode) {
4809        synchronized(this) {
4810            final long origId = Binder.clearCallingIdentity();
4811            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4812            if (r != null) {
4813                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4814            }
4815            Binder.restoreCallingIdentity(origId);
4816        }
4817    }
4818
4819    @Override
4820    public boolean finishActivityAffinity(IBinder token) {
4821        synchronized(this) {
4822            final long origId = Binder.clearCallingIdentity();
4823            try {
4824                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4825                if (r == null) {
4826                    return false;
4827                }
4828
4829                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4830                // can finish.
4831                final TaskRecord task = r.task;
4832                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4833                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4834                    mStackSupervisor.showLockTaskToast();
4835                    return false;
4836                }
4837                return task.stack.finishActivityAffinityLocked(r);
4838            } finally {
4839                Binder.restoreCallingIdentity(origId);
4840            }
4841        }
4842    }
4843
4844    @Override
4845    public void finishVoiceTask(IVoiceInteractionSession session) {
4846        synchronized (this) {
4847            final long origId = Binder.clearCallingIdentity();
4848            try {
4849                // TODO: VI Consider treating local voice interactions and voice tasks
4850                // differently here
4851                mStackSupervisor.finishVoiceTask(session);
4852            } finally {
4853                Binder.restoreCallingIdentity(origId);
4854            }
4855        }
4856
4857    }
4858
4859    @Override
4860    public boolean releaseActivityInstance(IBinder token) {
4861        synchronized(this) {
4862            final long origId = Binder.clearCallingIdentity();
4863            try {
4864                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4865                if (r == null) {
4866                    return false;
4867                }
4868                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4869            } finally {
4870                Binder.restoreCallingIdentity(origId);
4871            }
4872        }
4873    }
4874
4875    @Override
4876    public void releaseSomeActivities(IApplicationThread appInt) {
4877        synchronized(this) {
4878            final long origId = Binder.clearCallingIdentity();
4879            try {
4880                ProcessRecord app = getRecordForAppLocked(appInt);
4881                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4882            } finally {
4883                Binder.restoreCallingIdentity(origId);
4884            }
4885        }
4886    }
4887
4888    @Override
4889    public boolean willActivityBeVisible(IBinder token) {
4890        synchronized(this) {
4891            ActivityStack stack = ActivityRecord.getStackLocked(token);
4892            if (stack != null) {
4893                return stack.willActivityBeVisibleLocked(token);
4894            }
4895            return false;
4896        }
4897    }
4898
4899    @Override
4900    public void overridePendingTransition(IBinder token, String packageName,
4901            int enterAnim, int exitAnim) {
4902        synchronized(this) {
4903            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4904            if (self == null) {
4905                return;
4906            }
4907
4908            final long origId = Binder.clearCallingIdentity();
4909
4910            if (self.state == ActivityState.RESUMED
4911                    || self.state == ActivityState.PAUSING) {
4912                mWindowManager.overridePendingAppTransition(packageName,
4913                        enterAnim, exitAnim, null);
4914            }
4915
4916            Binder.restoreCallingIdentity(origId);
4917        }
4918    }
4919
4920    /**
4921     * Main function for removing an existing process from the activity manager
4922     * as a result of that process going away.  Clears out all connections
4923     * to the process.
4924     */
4925    private final void handleAppDiedLocked(ProcessRecord app,
4926            boolean restarting, boolean allowRestart) {
4927        int pid = app.pid;
4928        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4929        if (!kept && !restarting) {
4930            removeLruProcessLocked(app);
4931            if (pid > 0) {
4932                ProcessList.remove(pid);
4933            }
4934        }
4935
4936        if (mProfileProc == app) {
4937            clearProfilerLocked();
4938        }
4939
4940        // Remove this application's activities from active lists.
4941        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4942
4943        app.activities.clear();
4944
4945        if (app.instrumentationClass != null) {
4946            Slog.w(TAG, "Crash of app " + app.processName
4947                  + " running instrumentation " + app.instrumentationClass);
4948            Bundle info = new Bundle();
4949            info.putString("shortMsg", "Process crashed.");
4950            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4951        }
4952
4953        if (!restarting && hasVisibleActivities
4954                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4955            // If there was nothing to resume, and we are not already restarting this process, but
4956            // there is a visible activity that is hosted by the process...  then make sure all
4957            // visible activities are running, taking care of restarting this process.
4958            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4959        }
4960    }
4961
4962    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4963        IBinder threadBinder = thread.asBinder();
4964        // Find the application record.
4965        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4966            ProcessRecord rec = mLruProcesses.get(i);
4967            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4968                return i;
4969            }
4970        }
4971        return -1;
4972    }
4973
4974    final ProcessRecord getRecordForAppLocked(
4975            IApplicationThread thread) {
4976        if (thread == null) {
4977            return null;
4978        }
4979
4980        int appIndex = getLRURecordIndexForAppLocked(thread);
4981        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4982    }
4983
4984    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4985        // If there are no longer any background processes running,
4986        // and the app that died was not running instrumentation,
4987        // then tell everyone we are now low on memory.
4988        boolean haveBg = false;
4989        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4990            ProcessRecord rec = mLruProcesses.get(i);
4991            if (rec.thread != null
4992                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4993                haveBg = true;
4994                break;
4995            }
4996        }
4997
4998        if (!haveBg) {
4999            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5000            if (doReport) {
5001                long now = SystemClock.uptimeMillis();
5002                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5003                    doReport = false;
5004                } else {
5005                    mLastMemUsageReportTime = now;
5006                }
5007            }
5008            final ArrayList<ProcessMemInfo> memInfos
5009                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5010            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5011            long now = SystemClock.uptimeMillis();
5012            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5013                ProcessRecord rec = mLruProcesses.get(i);
5014                if (rec == dyingProc || rec.thread == null) {
5015                    continue;
5016                }
5017                if (doReport) {
5018                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5019                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5020                }
5021                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5022                    // The low memory report is overriding any current
5023                    // state for a GC request.  Make sure to do
5024                    // heavy/important/visible/foreground processes first.
5025                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5026                        rec.lastRequestedGc = 0;
5027                    } else {
5028                        rec.lastRequestedGc = rec.lastLowMemory;
5029                    }
5030                    rec.reportLowMemory = true;
5031                    rec.lastLowMemory = now;
5032                    mProcessesToGc.remove(rec);
5033                    addProcessToGcListLocked(rec);
5034                }
5035            }
5036            if (doReport) {
5037                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5038                mHandler.sendMessage(msg);
5039            }
5040            scheduleAppGcsLocked();
5041        }
5042    }
5043
5044    final void appDiedLocked(ProcessRecord app) {
5045       appDiedLocked(app, app.pid, app.thread, false);
5046    }
5047
5048    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5049            boolean fromBinderDied) {
5050        // First check if this ProcessRecord is actually active for the pid.
5051        synchronized (mPidsSelfLocked) {
5052            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5053            if (curProc != app) {
5054                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5055                return;
5056            }
5057        }
5058
5059        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5060        synchronized (stats) {
5061            stats.noteProcessDiedLocked(app.info.uid, pid);
5062        }
5063
5064        if (!app.killed) {
5065            if (!fromBinderDied) {
5066                Process.killProcessQuiet(pid);
5067            }
5068            killProcessGroup(app.uid, pid);
5069            app.killed = true;
5070        }
5071
5072        // Clean up already done if the process has been re-started.
5073        if (app.pid == pid && app.thread != null &&
5074                app.thread.asBinder() == thread.asBinder()) {
5075            boolean doLowMem = app.instrumentationClass == null;
5076            boolean doOomAdj = doLowMem;
5077            if (!app.killedByAm) {
5078                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5079                        + ") has died");
5080                mAllowLowerMemLevel = true;
5081            } else {
5082                // Note that we always want to do oom adj to update our state with the
5083                // new number of procs.
5084                mAllowLowerMemLevel = false;
5085                doLowMem = false;
5086            }
5087            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5088            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5089                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5090            handleAppDiedLocked(app, false, true);
5091
5092            if (doOomAdj) {
5093                updateOomAdjLocked();
5094            }
5095            if (doLowMem) {
5096                doLowMemReportIfNeededLocked(app);
5097            }
5098        } else if (app.pid != pid) {
5099            // A new process has already been started.
5100            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5101                    + ") has died and restarted (pid " + app.pid + ").");
5102            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5103        } else if (DEBUG_PROCESSES) {
5104            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5105                    + thread.asBinder());
5106        }
5107    }
5108
5109    /**
5110     * If a stack trace dump file is configured, dump process stack traces.
5111     * @param clearTraces causes the dump file to be erased prior to the new
5112     *    traces being written, if true; when false, the new traces will be
5113     *    appended to any existing file content.
5114     * @param firstPids of dalvik VM processes to dump stack traces for first
5115     * @param lastPids of dalvik VM processes to dump stack traces for last
5116     * @param nativeProcs optional list of native process names to dump stack crawls
5117     * @return file containing stack traces, or null if no dump file is configured
5118     */
5119    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5120            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5121        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5122        if (tracesPath == null || tracesPath.length() == 0) {
5123            return null;
5124        }
5125
5126        File tracesFile = new File(tracesPath);
5127        try {
5128            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5129            tracesFile.createNewFile();
5130            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5131        } catch (IOException e) {
5132            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5133            return null;
5134        }
5135
5136        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5137        return tracesFile;
5138    }
5139
5140    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5141            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5142        // Use a FileObserver to detect when traces finish writing.
5143        // The order of traces is considered important to maintain for legibility.
5144        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5145            @Override
5146            public synchronized void onEvent(int event, String path) { notify(); }
5147        };
5148
5149        try {
5150            observer.startWatching();
5151
5152            // First collect all of the stacks of the most important pids.
5153            if (firstPids != null) {
5154                try {
5155                    int num = firstPids.size();
5156                    for (int i = 0; i < num; i++) {
5157                        synchronized (observer) {
5158                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5159                                    + firstPids.get(i));
5160                            final long sime = SystemClock.elapsedRealtime();
5161                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5162                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5163                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5164                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5165                        }
5166                    }
5167                } catch (InterruptedException e) {
5168                    Slog.wtf(TAG, e);
5169                }
5170            }
5171
5172            // Next collect the stacks of the native pids
5173            if (nativeProcs != null) {
5174                int[] pids = Process.getPidsForCommands(nativeProcs);
5175                if (pids != null) {
5176                    for (int pid : pids) {
5177                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5178                        final long sime = SystemClock.elapsedRealtime();
5179                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5180                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5181                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5182                    }
5183                }
5184            }
5185
5186            // Lastly, measure CPU usage.
5187            if (processCpuTracker != null) {
5188                processCpuTracker.init();
5189                System.gc();
5190                processCpuTracker.update();
5191                try {
5192                    synchronized (processCpuTracker) {
5193                        processCpuTracker.wait(500); // measure over 1/2 second.
5194                    }
5195                } catch (InterruptedException e) {
5196                }
5197                processCpuTracker.update();
5198
5199                // We'll take the stack crawls of just the top apps using CPU.
5200                final int N = processCpuTracker.countWorkingStats();
5201                int numProcs = 0;
5202                for (int i=0; i<N && numProcs<5; i++) {
5203                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5204                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5205                        numProcs++;
5206                        try {
5207                            synchronized (observer) {
5208                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5209                                        + stats.pid);
5210                                final long stime = SystemClock.elapsedRealtime();
5211                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5212                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5213                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5214                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5215                            }
5216                        } catch (InterruptedException e) {
5217                            Slog.wtf(TAG, e);
5218                        }
5219                    } else if (DEBUG_ANR) {
5220                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5221                                + stats.pid);
5222                    }
5223                }
5224            }
5225        } finally {
5226            observer.stopWatching();
5227        }
5228    }
5229
5230    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5231        if (true || IS_USER_BUILD) {
5232            return;
5233        }
5234        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5235        if (tracesPath == null || tracesPath.length() == 0) {
5236            return;
5237        }
5238
5239        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5240        StrictMode.allowThreadDiskWrites();
5241        try {
5242            final File tracesFile = new File(tracesPath);
5243            final File tracesDir = tracesFile.getParentFile();
5244            final File tracesTmp = new File(tracesDir, "__tmp__");
5245            try {
5246                if (tracesFile.exists()) {
5247                    tracesTmp.delete();
5248                    tracesFile.renameTo(tracesTmp);
5249                }
5250                StringBuilder sb = new StringBuilder();
5251                Time tobj = new Time();
5252                tobj.set(System.currentTimeMillis());
5253                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5254                sb.append(": ");
5255                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5256                sb.append(" since ");
5257                sb.append(msg);
5258                FileOutputStream fos = new FileOutputStream(tracesFile);
5259                fos.write(sb.toString().getBytes());
5260                if (app == null) {
5261                    fos.write("\n*** No application process!".getBytes());
5262                }
5263                fos.close();
5264                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5265            } catch (IOException e) {
5266                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5267                return;
5268            }
5269
5270            if (app != null) {
5271                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5272                firstPids.add(app.pid);
5273                dumpStackTraces(tracesPath, firstPids, null, null, null);
5274            }
5275
5276            File lastTracesFile = null;
5277            File curTracesFile = null;
5278            for (int i=9; i>=0; i--) {
5279                String name = String.format(Locale.US, "slow%02d.txt", i);
5280                curTracesFile = new File(tracesDir, name);
5281                if (curTracesFile.exists()) {
5282                    if (lastTracesFile != null) {
5283                        curTracesFile.renameTo(lastTracesFile);
5284                    } else {
5285                        curTracesFile.delete();
5286                    }
5287                }
5288                lastTracesFile = curTracesFile;
5289            }
5290            tracesFile.renameTo(curTracesFile);
5291            if (tracesTmp.exists()) {
5292                tracesTmp.renameTo(tracesFile);
5293            }
5294        } finally {
5295            StrictMode.setThreadPolicy(oldPolicy);
5296        }
5297    }
5298
5299    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5300        if (!mLaunchWarningShown) {
5301            mLaunchWarningShown = true;
5302            mUiHandler.post(new Runnable() {
5303                @Override
5304                public void run() {
5305                    synchronized (ActivityManagerService.this) {
5306                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5307                        d.show();
5308                        mUiHandler.postDelayed(new Runnable() {
5309                            @Override
5310                            public void run() {
5311                                synchronized (ActivityManagerService.this) {
5312                                    d.dismiss();
5313                                    mLaunchWarningShown = false;
5314                                }
5315                            }
5316                        }, 4000);
5317                    }
5318                }
5319            });
5320        }
5321    }
5322
5323    @Override
5324    public boolean clearApplicationUserData(final String packageName,
5325            final IPackageDataObserver observer, int userId) {
5326        enforceNotIsolatedCaller("clearApplicationUserData");
5327        int uid = Binder.getCallingUid();
5328        int pid = Binder.getCallingPid();
5329        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5330                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5331
5332        final DevicePolicyManagerInternal dpmi = LocalServices
5333                .getService(DevicePolicyManagerInternal.class);
5334        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5335            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5336        }
5337
5338        long callingId = Binder.clearCallingIdentity();
5339        try {
5340            IPackageManager pm = AppGlobals.getPackageManager();
5341            int pkgUid = -1;
5342            synchronized(this) {
5343                try {
5344                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5345                } catch (RemoteException e) {
5346                }
5347                if (pkgUid == -1) {
5348                    Slog.w(TAG, "Invalid packageName: " + packageName);
5349                    if (observer != null) {
5350                        try {
5351                            observer.onRemoveCompleted(packageName, false);
5352                        } catch (RemoteException e) {
5353                            Slog.i(TAG, "Observer no longer exists.");
5354                        }
5355                    }
5356                    return false;
5357                }
5358                if (uid == pkgUid || checkComponentPermission(
5359                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5360                        pid, uid, -1, true)
5361                        == PackageManager.PERMISSION_GRANTED) {
5362                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5363                } else {
5364                    throw new SecurityException("PID " + pid + " does not have permission "
5365                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5366                                    + " of package " + packageName);
5367                }
5368
5369                // Remove all tasks match the cleared application package and user
5370                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5371                    final TaskRecord tr = mRecentTasks.get(i);
5372                    final String taskPackageName =
5373                            tr.getBaseIntent().getComponent().getPackageName();
5374                    if (tr.userId != userId) continue;
5375                    if (!taskPackageName.equals(packageName)) continue;
5376                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5377                }
5378            }
5379
5380            try {
5381                // Clear application user data
5382                pm.clearApplicationUserData(packageName, observer, userId);
5383
5384                synchronized(this) {
5385                    // Remove all permissions granted from/to this package
5386                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5387                }
5388
5389                // Remove all zen rules created by this package; revoke it's zen access.
5390                INotificationManager inm = NotificationManager.getService();
5391                inm.removeAutomaticZenRules(packageName);
5392                inm.setNotificationPolicyAccessGranted(packageName, false);
5393
5394                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5395                        Uri.fromParts("package", packageName, null));
5396                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5397                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5398                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5399                        null, null, 0, null, null, null, null, false, false, userId);
5400            } catch (RemoteException e) {
5401            }
5402        } finally {
5403            Binder.restoreCallingIdentity(callingId);
5404        }
5405        return true;
5406    }
5407
5408    @Override
5409    public void killBackgroundProcesses(final String packageName, int userId) {
5410        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5411                != PackageManager.PERMISSION_GRANTED &&
5412                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5413                        != PackageManager.PERMISSION_GRANTED) {
5414            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5415                    + Binder.getCallingPid()
5416                    + ", uid=" + Binder.getCallingUid()
5417                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5418            Slog.w(TAG, msg);
5419            throw new SecurityException(msg);
5420        }
5421
5422        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5423                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5424        long callingId = Binder.clearCallingIdentity();
5425        try {
5426            IPackageManager pm = AppGlobals.getPackageManager();
5427            synchronized(this) {
5428                int appId = -1;
5429                try {
5430                    appId = UserHandle.getAppId(
5431                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5432                } catch (RemoteException e) {
5433                }
5434                if (appId == -1) {
5435                    Slog.w(TAG, "Invalid packageName: " + packageName);
5436                    return;
5437                }
5438                killPackageProcessesLocked(packageName, appId, userId,
5439                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5440            }
5441        } finally {
5442            Binder.restoreCallingIdentity(callingId);
5443        }
5444    }
5445
5446    @Override
5447    public void killAllBackgroundProcesses() {
5448        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5449                != PackageManager.PERMISSION_GRANTED) {
5450            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5451                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5452                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5453            Slog.w(TAG, msg);
5454            throw new SecurityException(msg);
5455        }
5456
5457        final long callingId = Binder.clearCallingIdentity();
5458        try {
5459            synchronized (this) {
5460                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5461                final int NP = mProcessNames.getMap().size();
5462                for (int ip = 0; ip < NP; ip++) {
5463                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5464                    final int NA = apps.size();
5465                    for (int ia = 0; ia < NA; ia++) {
5466                        final ProcessRecord app = apps.valueAt(ia);
5467                        if (app.persistent) {
5468                            // We don't kill persistent processes.
5469                            continue;
5470                        }
5471                        if (app.removed) {
5472                            procs.add(app);
5473                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5474                            app.removed = true;
5475                            procs.add(app);
5476                        }
5477                    }
5478                }
5479
5480                final int N = procs.size();
5481                for (int i = 0; i < N; i++) {
5482                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5483                }
5484
5485                mAllowLowerMemLevel = true;
5486
5487                updateOomAdjLocked();
5488                doLowMemReportIfNeededLocked(null);
5489            }
5490        } finally {
5491            Binder.restoreCallingIdentity(callingId);
5492        }
5493    }
5494
5495    /**
5496     * Kills all background processes, except those matching any of the
5497     * specified properties.
5498     *
5499     * @param minTargetSdk the target SDK version at or above which to preserve
5500     *                     processes, or {@code -1} to ignore the target SDK
5501     * @param maxProcState the process state at or below which to preserve
5502     *                     processes, or {@code -1} to ignore the process state
5503     */
5504    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5505        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5506                != PackageManager.PERMISSION_GRANTED) {
5507            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5508                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5509                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5510            Slog.w(TAG, msg);
5511            throw new SecurityException(msg);
5512        }
5513
5514        final long callingId = Binder.clearCallingIdentity();
5515        try {
5516            synchronized (this) {
5517                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5518                final int NP = mProcessNames.getMap().size();
5519                for (int ip = 0; ip < NP; ip++) {
5520                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5521                    final int NA = apps.size();
5522                    for (int ia = 0; ia < NA; ia++) {
5523                        final ProcessRecord app = apps.valueAt(ia);
5524                        if (app.removed) {
5525                            procs.add(app);
5526                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5527                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5528                            app.removed = true;
5529                            procs.add(app);
5530                        }
5531                    }
5532                }
5533
5534                final int N = procs.size();
5535                for (int i = 0; i < N; i++) {
5536                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5537                }
5538            }
5539        } finally {
5540            Binder.restoreCallingIdentity(callingId);
5541        }
5542    }
5543
5544    @Override
5545    public void forceStopPackage(final String packageName, int userId) {
5546        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5547                != PackageManager.PERMISSION_GRANTED) {
5548            String msg = "Permission Denial: forceStopPackage() from pid="
5549                    + Binder.getCallingPid()
5550                    + ", uid=" + Binder.getCallingUid()
5551                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5552            Slog.w(TAG, msg);
5553            throw new SecurityException(msg);
5554        }
5555        final int callingPid = Binder.getCallingPid();
5556        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5557                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5558        long callingId = Binder.clearCallingIdentity();
5559        try {
5560            IPackageManager pm = AppGlobals.getPackageManager();
5561            synchronized(this) {
5562                int[] users = userId == UserHandle.USER_ALL
5563                        ? mUserController.getUsers() : new int[] { userId };
5564                for (int user : users) {
5565                    int pkgUid = -1;
5566                    try {
5567                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5568                                user);
5569                    } catch (RemoteException e) {
5570                    }
5571                    if (pkgUid == -1) {
5572                        Slog.w(TAG, "Invalid packageName: " + packageName);
5573                        continue;
5574                    }
5575                    try {
5576                        pm.setPackageStoppedState(packageName, true, user);
5577                    } catch (RemoteException e) {
5578                    } catch (IllegalArgumentException e) {
5579                        Slog.w(TAG, "Failed trying to unstop package "
5580                                + packageName + ": " + e);
5581                    }
5582                    if (mUserController.isUserRunningLocked(user, 0)) {
5583                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5584                    }
5585                }
5586            }
5587        } finally {
5588            Binder.restoreCallingIdentity(callingId);
5589        }
5590    }
5591
5592    @Override
5593    public void addPackageDependency(String packageName) {
5594        synchronized (this) {
5595            int callingPid = Binder.getCallingPid();
5596            if (callingPid == Process.myPid()) {
5597                //  Yeah, um, no.
5598                return;
5599            }
5600            ProcessRecord proc;
5601            synchronized (mPidsSelfLocked) {
5602                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5603            }
5604            if (proc != null) {
5605                if (proc.pkgDeps == null) {
5606                    proc.pkgDeps = new ArraySet<String>(1);
5607                }
5608                proc.pkgDeps.add(packageName);
5609            }
5610        }
5611    }
5612
5613    /*
5614     * The pkg name and app id have to be specified.
5615     */
5616    @Override
5617    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5618        if (pkg == null) {
5619            return;
5620        }
5621        // Make sure the uid is valid.
5622        if (appid < 0) {
5623            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5624            return;
5625        }
5626        int callerUid = Binder.getCallingUid();
5627        // Only the system server can kill an application
5628        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5629            // Post an aysnc message to kill the application
5630            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5631            msg.arg1 = appid;
5632            msg.arg2 = 0;
5633            Bundle bundle = new Bundle();
5634            bundle.putString("pkg", pkg);
5635            bundle.putString("reason", reason);
5636            msg.obj = bundle;
5637            mHandler.sendMessage(msg);
5638        } else {
5639            throw new SecurityException(callerUid + " cannot kill pkg: " +
5640                    pkg);
5641        }
5642    }
5643
5644    @Override
5645    public void closeSystemDialogs(String reason) {
5646        enforceNotIsolatedCaller("closeSystemDialogs");
5647
5648        final int pid = Binder.getCallingPid();
5649        final int uid = Binder.getCallingUid();
5650        final long origId = Binder.clearCallingIdentity();
5651        try {
5652            synchronized (this) {
5653                // Only allow this from foreground processes, so that background
5654                // applications can't abuse it to prevent system UI from being shown.
5655                if (uid >= Process.FIRST_APPLICATION_UID) {
5656                    ProcessRecord proc;
5657                    synchronized (mPidsSelfLocked) {
5658                        proc = mPidsSelfLocked.get(pid);
5659                    }
5660                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5661                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5662                                + " from background process " + proc);
5663                        return;
5664                    }
5665                }
5666                closeSystemDialogsLocked(reason);
5667            }
5668        } finally {
5669            Binder.restoreCallingIdentity(origId);
5670        }
5671    }
5672
5673    void closeSystemDialogsLocked(String reason) {
5674        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5675        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5676                | Intent.FLAG_RECEIVER_FOREGROUND);
5677        if (reason != null) {
5678            intent.putExtra("reason", reason);
5679        }
5680        mWindowManager.closeSystemDialogs(reason);
5681
5682        mStackSupervisor.closeSystemDialogsLocked();
5683
5684        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5685                AppOpsManager.OP_NONE, null, false, false,
5686                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5687    }
5688
5689    @Override
5690    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5691        enforceNotIsolatedCaller("getProcessMemoryInfo");
5692        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5693        for (int i=pids.length-1; i>=0; i--) {
5694            ProcessRecord proc;
5695            int oomAdj;
5696            synchronized (this) {
5697                synchronized (mPidsSelfLocked) {
5698                    proc = mPidsSelfLocked.get(pids[i]);
5699                    oomAdj = proc != null ? proc.setAdj : 0;
5700                }
5701            }
5702            infos[i] = new Debug.MemoryInfo();
5703            Debug.getMemoryInfo(pids[i], infos[i]);
5704            if (proc != null) {
5705                synchronized (this) {
5706                    if (proc.thread != null && proc.setAdj == oomAdj) {
5707                        // Record this for posterity if the process has been stable.
5708                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5709                                infos[i].getTotalUss(), false, proc.pkgList);
5710                    }
5711                }
5712            }
5713        }
5714        return infos;
5715    }
5716
5717    @Override
5718    public long[] getProcessPss(int[] pids) {
5719        enforceNotIsolatedCaller("getProcessPss");
5720        long[] pss = new long[pids.length];
5721        for (int i=pids.length-1; i>=0; i--) {
5722            ProcessRecord proc;
5723            int oomAdj;
5724            synchronized (this) {
5725                synchronized (mPidsSelfLocked) {
5726                    proc = mPidsSelfLocked.get(pids[i]);
5727                    oomAdj = proc != null ? proc.setAdj : 0;
5728                }
5729            }
5730            long[] tmpUss = new long[1];
5731            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5732            if (proc != null) {
5733                synchronized (this) {
5734                    if (proc.thread != null && proc.setAdj == oomAdj) {
5735                        // Record this for posterity if the process has been stable.
5736                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5737                    }
5738                }
5739            }
5740        }
5741        return pss;
5742    }
5743
5744    @Override
5745    public void killApplicationProcess(String processName, int uid) {
5746        if (processName == null) {
5747            return;
5748        }
5749
5750        int callerUid = Binder.getCallingUid();
5751        // Only the system server can kill an application
5752        if (callerUid == Process.SYSTEM_UID) {
5753            synchronized (this) {
5754                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5755                if (app != null && app.thread != null) {
5756                    try {
5757                        app.thread.scheduleSuicide();
5758                    } catch (RemoteException e) {
5759                        // If the other end already died, then our work here is done.
5760                    }
5761                } else {
5762                    Slog.w(TAG, "Process/uid not found attempting kill of "
5763                            + processName + " / " + uid);
5764                }
5765            }
5766        } else {
5767            throw new SecurityException(callerUid + " cannot kill app process: " +
5768                    processName);
5769        }
5770    }
5771
5772    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5773        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5774                false, true, false, false, UserHandle.getUserId(uid), reason);
5775        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5776                Uri.fromParts("package", packageName, null));
5777        if (!mProcessesReady) {
5778            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5779                    | Intent.FLAG_RECEIVER_FOREGROUND);
5780        }
5781        intent.putExtra(Intent.EXTRA_UID, uid);
5782        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5783        broadcastIntentLocked(null, null, intent,
5784                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5785                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5786    }
5787
5788
5789    private final boolean killPackageProcessesLocked(String packageName, int appId,
5790            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5791            boolean doit, boolean evenPersistent, String reason) {
5792        ArrayList<ProcessRecord> procs = new ArrayList<>();
5793
5794        // Remove all processes this package may have touched: all with the
5795        // same UID (except for the system or root user), and all whose name
5796        // matches the package name.
5797        final int NP = mProcessNames.getMap().size();
5798        for (int ip=0; ip<NP; ip++) {
5799            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5800            final int NA = apps.size();
5801            for (int ia=0; ia<NA; ia++) {
5802                ProcessRecord app = apps.valueAt(ia);
5803                if (app.persistent && !evenPersistent) {
5804                    // we don't kill persistent processes
5805                    continue;
5806                }
5807                if (app.removed) {
5808                    if (doit) {
5809                        procs.add(app);
5810                    }
5811                    continue;
5812                }
5813
5814                // Skip process if it doesn't meet our oom adj requirement.
5815                if (app.setAdj < minOomAdj) {
5816                    continue;
5817                }
5818
5819                // If no package is specified, we call all processes under the
5820                // give user id.
5821                if (packageName == null) {
5822                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5823                        continue;
5824                    }
5825                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5826                        continue;
5827                    }
5828                // Package has been specified, we want to hit all processes
5829                // that match it.  We need to qualify this by the processes
5830                // that are running under the specified app and user ID.
5831                } else {
5832                    final boolean isDep = app.pkgDeps != null
5833                            && app.pkgDeps.contains(packageName);
5834                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5835                        continue;
5836                    }
5837                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5838                        continue;
5839                    }
5840                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5841                        continue;
5842                    }
5843                }
5844
5845                // Process has passed all conditions, kill it!
5846                if (!doit) {
5847                    return true;
5848                }
5849                app.removed = true;
5850                procs.add(app);
5851            }
5852        }
5853
5854        int N = procs.size();
5855        for (int i=0; i<N; i++) {
5856            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5857        }
5858        updateOomAdjLocked();
5859        return N > 0;
5860    }
5861
5862    private void cleanupDisabledPackageComponentsLocked(
5863            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5864
5865        Set<String> disabledClasses = null;
5866        boolean packageDisabled = false;
5867        IPackageManager pm = AppGlobals.getPackageManager();
5868
5869        if (changedClasses == null) {
5870            // Nothing changed...
5871            return;
5872        }
5873
5874        // Determine enable/disable state of the package and its components.
5875        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5876        for (int i = changedClasses.length - 1; i >= 0; i--) {
5877            final String changedClass = changedClasses[i];
5878
5879            if (changedClass.equals(packageName)) {
5880                try {
5881                    // Entire package setting changed
5882                    enabled = pm.getApplicationEnabledSetting(packageName,
5883                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5884                } catch (Exception e) {
5885                    // No such package/component; probably racing with uninstall.  In any
5886                    // event it means we have nothing further to do here.
5887                    return;
5888                }
5889                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5890                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5891                if (packageDisabled) {
5892                    // Entire package is disabled.
5893                    // No need to continue to check component states.
5894                    disabledClasses = null;
5895                    break;
5896                }
5897            } else {
5898                try {
5899                    enabled = pm.getComponentEnabledSetting(
5900                            new ComponentName(packageName, changedClass),
5901                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5902                } catch (Exception e) {
5903                    // As above, probably racing with uninstall.
5904                    return;
5905                }
5906                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5907                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5908                    if (disabledClasses == null) {
5909                        disabledClasses = new ArraySet<>(changedClasses.length);
5910                    }
5911                    disabledClasses.add(changedClass);
5912                }
5913            }
5914        }
5915
5916        if (!packageDisabled && disabledClasses == null) {
5917            // Nothing to do here...
5918            return;
5919        }
5920
5921        // Clean-up disabled activities.
5922        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5923                packageName, disabledClasses, true, false, userId) && mBooted) {
5924            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5925            mStackSupervisor.scheduleIdleLocked();
5926        }
5927
5928        // Clean-up disabled tasks
5929        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5930
5931        // Clean-up disabled services.
5932        mServices.bringDownDisabledPackageServicesLocked(
5933                packageName, disabledClasses, userId, false, killProcess, true);
5934
5935        // Clean-up disabled providers.
5936        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5937        mProviderMap.collectPackageProvidersLocked(
5938                packageName, disabledClasses, true, false, userId, providers);
5939        for (int i = providers.size() - 1; i >= 0; i--) {
5940            removeDyingProviderLocked(null, providers.get(i), true);
5941        }
5942
5943        // Clean-up disabled broadcast receivers.
5944        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5945            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5946                    packageName, disabledClasses, userId, true);
5947        }
5948
5949    }
5950
5951    final boolean forceStopPackageLocked(String packageName, int appId,
5952            boolean callerWillRestart, boolean purgeCache, boolean doit,
5953            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5954        int i;
5955
5956        if (userId == UserHandle.USER_ALL && packageName == null) {
5957            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5958        }
5959
5960        if (appId < 0 && packageName != null) {
5961            try {
5962                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5963                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5964            } catch (RemoteException e) {
5965            }
5966        }
5967
5968        if (doit) {
5969            if (packageName != null) {
5970                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5971                        + " user=" + userId + ": " + reason);
5972            } else {
5973                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5974            }
5975
5976            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5977        }
5978
5979        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5980                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5981                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5982
5983        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5984                packageName, null, doit, evenPersistent, userId)) {
5985            if (!doit) {
5986                return true;
5987            }
5988            didSomething = true;
5989        }
5990
5991        if (mServices.bringDownDisabledPackageServicesLocked(
5992                packageName, null, userId, evenPersistent, true, doit)) {
5993            if (!doit) {
5994                return true;
5995            }
5996            didSomething = true;
5997        }
5998
5999        if (packageName == null) {
6000            // Remove all sticky broadcasts from this user.
6001            mStickyBroadcasts.remove(userId);
6002        }
6003
6004        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6005        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6006                userId, providers)) {
6007            if (!doit) {
6008                return true;
6009            }
6010            didSomething = true;
6011        }
6012        for (i = providers.size() - 1; i >= 0; i--) {
6013            removeDyingProviderLocked(null, providers.get(i), true);
6014        }
6015
6016        // Remove transient permissions granted from/to this package/user
6017        removeUriPermissionsForPackageLocked(packageName, userId, false);
6018
6019        if (doit) {
6020            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                        packageName, null, userId, doit);
6023            }
6024        }
6025
6026        if (packageName == null || uninstalling) {
6027            // Remove pending intents.  For now we only do this when force
6028            // stopping users, because we have some problems when doing this
6029            // for packages -- app widgets are not currently cleaned up for
6030            // such packages, so they can be left with bad pending intents.
6031            if (mIntentSenderRecords.size() > 0) {
6032                Iterator<WeakReference<PendingIntentRecord>> it
6033                        = mIntentSenderRecords.values().iterator();
6034                while (it.hasNext()) {
6035                    WeakReference<PendingIntentRecord> wpir = it.next();
6036                    if (wpir == null) {
6037                        it.remove();
6038                        continue;
6039                    }
6040                    PendingIntentRecord pir = wpir.get();
6041                    if (pir == null) {
6042                        it.remove();
6043                        continue;
6044                    }
6045                    if (packageName == null) {
6046                        // Stopping user, remove all objects for the user.
6047                        if (pir.key.userId != userId) {
6048                            // Not the same user, skip it.
6049                            continue;
6050                        }
6051                    } else {
6052                        if (UserHandle.getAppId(pir.uid) != appId) {
6053                            // Different app id, skip it.
6054                            continue;
6055                        }
6056                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6057                            // Different user, skip it.
6058                            continue;
6059                        }
6060                        if (!pir.key.packageName.equals(packageName)) {
6061                            // Different package, skip it.
6062                            continue;
6063                        }
6064                    }
6065                    if (!doit) {
6066                        return true;
6067                    }
6068                    didSomething = true;
6069                    it.remove();
6070                    pir.canceled = true;
6071                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6072                        pir.key.activity.pendingResults.remove(pir.ref);
6073                    }
6074                }
6075            }
6076        }
6077
6078        if (doit) {
6079            if (purgeCache && packageName != null) {
6080                AttributeCache ac = AttributeCache.instance();
6081                if (ac != null) {
6082                    ac.removePackage(packageName);
6083                }
6084            }
6085            if (mBooted) {
6086                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6087                mStackSupervisor.scheduleIdleLocked();
6088            }
6089        }
6090
6091        return didSomething;
6092    }
6093
6094    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6095        ProcessRecord old = mProcessNames.remove(name, uid);
6096        if (old != null) {
6097            old.uidRecord.numProcs--;
6098            if (old.uidRecord.numProcs == 0) {
6099                // No more processes using this uid, tell clients it is gone.
6100                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6101                        "No more processes in " + old.uidRecord);
6102                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6103                mActiveUids.remove(uid);
6104                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6105            }
6106            old.uidRecord = null;
6107        }
6108        mIsolatedProcesses.remove(uid);
6109        return old;
6110    }
6111
6112    private final void addProcessNameLocked(ProcessRecord proc) {
6113        // We shouldn't already have a process under this name, but just in case we
6114        // need to clean up whatever may be there now.
6115        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6116        if (old == proc && proc.persistent) {
6117            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6118            Slog.w(TAG, "Re-adding persistent process " + proc);
6119        } else if (old != null) {
6120            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6121        }
6122        UidRecord uidRec = mActiveUids.get(proc.uid);
6123        if (uidRec == null) {
6124            uidRec = new UidRecord(proc.uid);
6125            // This is the first appearance of the uid, report it now!
6126            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6127                    "Creating new process uid: " + uidRec);
6128            mActiveUids.put(proc.uid, uidRec);
6129            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6130            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6131        }
6132        proc.uidRecord = uidRec;
6133        uidRec.numProcs++;
6134        mProcessNames.put(proc.processName, proc.uid, proc);
6135        if (proc.isolated) {
6136            mIsolatedProcesses.put(proc.uid, proc);
6137        }
6138    }
6139
6140    boolean removeProcessLocked(ProcessRecord app,
6141            boolean callerWillRestart, boolean allowRestart, String reason) {
6142        final String name = app.processName;
6143        final int uid = app.uid;
6144        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6145            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6146
6147        removeProcessNameLocked(name, uid);
6148        if (mHeavyWeightProcess == app) {
6149            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6150                    mHeavyWeightProcess.userId, 0));
6151            mHeavyWeightProcess = null;
6152        }
6153        boolean needRestart = false;
6154        if (app.pid > 0 && app.pid != MY_PID) {
6155            int pid = app.pid;
6156            synchronized (mPidsSelfLocked) {
6157                mPidsSelfLocked.remove(pid);
6158                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6159            }
6160            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6161            if (app.isolated) {
6162                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6163            }
6164            boolean willRestart = false;
6165            if (app.persistent && !app.isolated) {
6166                if (!callerWillRestart) {
6167                    willRestart = true;
6168                } else {
6169                    needRestart = true;
6170                }
6171            }
6172            app.kill(reason, true);
6173            handleAppDiedLocked(app, willRestart, allowRestart);
6174            if (willRestart) {
6175                removeLruProcessLocked(app);
6176                addAppLocked(app.info, false, null /* ABI override */);
6177            }
6178        } else {
6179            mRemovedProcesses.add(app);
6180        }
6181
6182        return needRestart;
6183    }
6184
6185    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6186        cleanupAppInLaunchingProvidersLocked(app, true);
6187        removeProcessLocked(app, false, true, "timeout publishing content providers");
6188    }
6189
6190    private final void processStartTimedOutLocked(ProcessRecord app) {
6191        final int pid = app.pid;
6192        boolean gone = false;
6193        synchronized (mPidsSelfLocked) {
6194            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6195            if (knownApp != null && knownApp.thread == null) {
6196                mPidsSelfLocked.remove(pid);
6197                gone = true;
6198            }
6199        }
6200
6201        if (gone) {
6202            Slog.w(TAG, "Process " + app + " failed to attach");
6203            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6204                    pid, app.uid, app.processName);
6205            removeProcessNameLocked(app.processName, app.uid);
6206            if (mHeavyWeightProcess == app) {
6207                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6208                        mHeavyWeightProcess.userId, 0));
6209                mHeavyWeightProcess = null;
6210            }
6211            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6212            if (app.isolated) {
6213                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6214            }
6215            // Take care of any launching providers waiting for this process.
6216            cleanupAppInLaunchingProvidersLocked(app, true);
6217            // Take care of any services that are waiting for the process.
6218            mServices.processStartTimedOutLocked(app);
6219            app.kill("start timeout", true);
6220            removeLruProcessLocked(app);
6221            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6222                Slog.w(TAG, "Unattached app died before backup, skipping");
6223                try {
6224                    IBackupManager bm = IBackupManager.Stub.asInterface(
6225                            ServiceManager.getService(Context.BACKUP_SERVICE));
6226                    bm.agentDisconnected(app.info.packageName);
6227                } catch (RemoteException e) {
6228                    // Can't happen; the backup manager is local
6229                }
6230            }
6231            if (isPendingBroadcastProcessLocked(pid)) {
6232                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6233                skipPendingBroadcastLocked(pid);
6234            }
6235        } else {
6236            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6237        }
6238    }
6239
6240    private final boolean attachApplicationLocked(IApplicationThread thread,
6241            int pid) {
6242
6243        // Find the application record that is being attached...  either via
6244        // the pid if we are running in multiple processes, or just pull the
6245        // next app record if we are emulating process with anonymous threads.
6246        ProcessRecord app;
6247        if (pid != MY_PID && pid >= 0) {
6248            synchronized (mPidsSelfLocked) {
6249                app = mPidsSelfLocked.get(pid);
6250            }
6251        } else {
6252            app = null;
6253        }
6254
6255        if (app == null) {
6256            Slog.w(TAG, "No pending application record for pid " + pid
6257                    + " (IApplicationThread " + thread + "); dropping process");
6258            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6259            if (pid > 0 && pid != MY_PID) {
6260                Process.killProcessQuiet(pid);
6261                //TODO: killProcessGroup(app.info.uid, pid);
6262            } else {
6263                try {
6264                    thread.scheduleExit();
6265                } catch (Exception e) {
6266                    // Ignore exceptions.
6267                }
6268            }
6269            return false;
6270        }
6271
6272        // If this application record is still attached to a previous
6273        // process, clean it up now.
6274        if (app.thread != null) {
6275            handleAppDiedLocked(app, true, true);
6276        }
6277
6278        // Tell the process all about itself.
6279
6280        if (DEBUG_ALL) Slog.v(
6281                TAG, "Binding process pid " + pid + " to record " + app);
6282
6283        final String processName = app.processName;
6284        try {
6285            AppDeathRecipient adr = new AppDeathRecipient(
6286                    app, pid, thread);
6287            thread.asBinder().linkToDeath(adr, 0);
6288            app.deathRecipient = adr;
6289        } catch (RemoteException e) {
6290            app.resetPackageList(mProcessStats);
6291            startProcessLocked(app, "link fail", processName);
6292            return false;
6293        }
6294
6295        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6296
6297        app.makeActive(thread, mProcessStats);
6298        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6299        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6300        app.forcingToForeground = null;
6301        updateProcessForegroundLocked(app, false, false);
6302        app.hasShownUi = false;
6303        app.debugging = false;
6304        app.cached = false;
6305        app.killedByAm = false;
6306
6307        // We carefully use the same state that PackageManager uses for
6308        // filtering, since we use this flag to decide if we need to install
6309        // providers when user is unlocked later
6310        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6311
6312        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6313
6314        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6315        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6316
6317        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6318            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6319            msg.obj = app;
6320            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6321        }
6322
6323        if (!normalMode) {
6324            Slog.i(TAG, "Launching preboot mode app: " + app);
6325        }
6326
6327        if (DEBUG_ALL) Slog.v(
6328            TAG, "New app record " + app
6329            + " thread=" + thread.asBinder() + " pid=" + pid);
6330        try {
6331            int testMode = IApplicationThread.DEBUG_OFF;
6332            if (mDebugApp != null && mDebugApp.equals(processName)) {
6333                testMode = mWaitForDebugger
6334                    ? IApplicationThread.DEBUG_WAIT
6335                    : IApplicationThread.DEBUG_ON;
6336                app.debugging = true;
6337                if (mDebugTransient) {
6338                    mDebugApp = mOrigDebugApp;
6339                    mWaitForDebugger = mOrigWaitForDebugger;
6340                }
6341            }
6342            String profileFile = app.instrumentationProfileFile;
6343            ParcelFileDescriptor profileFd = null;
6344            int samplingInterval = 0;
6345            boolean profileAutoStop = false;
6346            if (mProfileApp != null && mProfileApp.equals(processName)) {
6347                mProfileProc = app;
6348                profileFile = mProfileFile;
6349                profileFd = mProfileFd;
6350                samplingInterval = mSamplingInterval;
6351                profileAutoStop = mAutoStopProfiler;
6352            }
6353            boolean enableTrackAllocation = false;
6354            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6355                enableTrackAllocation = true;
6356                mTrackAllocationApp = null;
6357            }
6358
6359            // If the app is being launched for restore or full backup, set it up specially
6360            boolean isRestrictedBackupMode = false;
6361            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6362                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6363                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6364                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6365                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6366            }
6367
6368            if (app.instrumentationClass != null) {
6369                notifyPackageUse(app.instrumentationClass.getPackageName(),
6370                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6371            }
6372            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6373                    + processName + " with config " + mConfiguration);
6374            ApplicationInfo appInfo = app.instrumentationInfo != null
6375                    ? app.instrumentationInfo : app.info;
6376            app.compat = compatibilityInfoForPackageLocked(appInfo);
6377            if (profileFd != null) {
6378                profileFd = profileFd.dup();
6379            }
6380            ProfilerInfo profilerInfo = profileFile == null ? null
6381                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6382            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6383                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6384                    app.instrumentationUiAutomationConnection, testMode,
6385                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6386                    isRestrictedBackupMode || !normalMode, app.persistent,
6387                    new Configuration(mConfiguration), app.compat,
6388                    getCommonServicesLocked(app.isolated),
6389                    mCoreSettingsObserver.getCoreSettingsLocked());
6390            updateLruProcessLocked(app, false, null);
6391            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6392        } catch (Exception e) {
6393            // todo: Yikes!  What should we do?  For now we will try to
6394            // start another process, but that could easily get us in
6395            // an infinite loop of restarting processes...
6396            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6397
6398            app.resetPackageList(mProcessStats);
6399            app.unlinkDeathRecipient();
6400            startProcessLocked(app, "bind fail", processName);
6401            return false;
6402        }
6403
6404        // Remove this record from the list of starting applications.
6405        mPersistentStartingProcesses.remove(app);
6406        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6407                "Attach application locked removing on hold: " + app);
6408        mProcessesOnHold.remove(app);
6409
6410        boolean badApp = false;
6411        boolean didSomething = false;
6412
6413        // See if the top visible activity is waiting to run in this process...
6414        if (normalMode) {
6415            try {
6416                if (mStackSupervisor.attachApplicationLocked(app)) {
6417                    didSomething = true;
6418                }
6419            } catch (Exception e) {
6420                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6421                badApp = true;
6422            }
6423        }
6424
6425        // Find any services that should be running in this process...
6426        if (!badApp) {
6427            try {
6428                didSomething |= mServices.attachApplicationLocked(app, processName);
6429            } catch (Exception e) {
6430                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6431                badApp = true;
6432            }
6433        }
6434
6435        // Check if a next-broadcast receiver is in this process...
6436        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6437            try {
6438                didSomething |= sendPendingBroadcastsLocked(app);
6439            } catch (Exception e) {
6440                // If the app died trying to launch the receiver we declare it 'bad'
6441                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6442                badApp = true;
6443            }
6444        }
6445
6446        // Check whether the next backup agent is in this process...
6447        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6448            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6449                    "New app is backup target, launching agent for " + app);
6450            notifyPackageUse(mBackupTarget.appInfo.packageName,
6451                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6452            try {
6453                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6454                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6455                        mBackupTarget.backupMode);
6456            } catch (Exception e) {
6457                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6458                badApp = true;
6459            }
6460        }
6461
6462        if (badApp) {
6463            app.kill("error during init", true);
6464            handleAppDiedLocked(app, false, true);
6465            return false;
6466        }
6467
6468        if (!didSomething) {
6469            updateOomAdjLocked();
6470        }
6471
6472        return true;
6473    }
6474
6475    @Override
6476    public final void attachApplication(IApplicationThread thread) {
6477        synchronized (this) {
6478            int callingPid = Binder.getCallingPid();
6479            final long origId = Binder.clearCallingIdentity();
6480            attachApplicationLocked(thread, callingPid);
6481            Binder.restoreCallingIdentity(origId);
6482        }
6483    }
6484
6485    @Override
6486    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6487        final long origId = Binder.clearCallingIdentity();
6488        synchronized (this) {
6489            ActivityStack stack = ActivityRecord.getStackLocked(token);
6490            if (stack != null) {
6491                ActivityRecord r =
6492                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6493                if (stopProfiling) {
6494                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6495                        try {
6496                            mProfileFd.close();
6497                        } catch (IOException e) {
6498                        }
6499                        clearProfilerLocked();
6500                    }
6501                }
6502            }
6503        }
6504        Binder.restoreCallingIdentity(origId);
6505    }
6506
6507    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6508        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6509                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6510    }
6511
6512    void enableScreenAfterBoot() {
6513        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6514                SystemClock.uptimeMillis());
6515        mWindowManager.enableScreenAfterBoot();
6516
6517        synchronized (this) {
6518            updateEventDispatchingLocked();
6519        }
6520    }
6521
6522    @Override
6523    public void showBootMessage(final CharSequence msg, final boolean always) {
6524        if (Binder.getCallingUid() != Process.myUid()) {
6525            // These days only the core system can call this, so apps can't get in
6526            // the way of what we show about running them.
6527        }
6528        mWindowManager.showBootMessage(msg, always);
6529    }
6530
6531    @Override
6532    public void keyguardWaitingForActivityDrawn() {
6533        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6534        final long token = Binder.clearCallingIdentity();
6535        try {
6536            synchronized (this) {
6537                if (DEBUG_LOCKSCREEN) logLockScreen("");
6538                mWindowManager.keyguardWaitingForActivityDrawn();
6539                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6540                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6541                    updateSleepIfNeededLocked();
6542                }
6543            }
6544        } finally {
6545            Binder.restoreCallingIdentity(token);
6546        }
6547    }
6548
6549    @Override
6550    public void keyguardGoingAway(int flags) {
6551        enforceNotIsolatedCaller("keyguardGoingAway");
6552        final long token = Binder.clearCallingIdentity();
6553        try {
6554            synchronized (this) {
6555                if (DEBUG_LOCKSCREEN) logLockScreen("");
6556                mWindowManager.keyguardGoingAway(flags);
6557                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6558                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6559                    updateSleepIfNeededLocked();
6560
6561                    // Some stack visibility might change (e.g. docked stack)
6562                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6563                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6564                }
6565            }
6566        } finally {
6567            Binder.restoreCallingIdentity(token);
6568        }
6569    }
6570
6571    final void finishBooting() {
6572        synchronized (this) {
6573            if (!mBootAnimationComplete) {
6574                mCallFinishBooting = true;
6575                return;
6576            }
6577            mCallFinishBooting = false;
6578        }
6579
6580        ArraySet<String> completedIsas = new ArraySet<String>();
6581        for (String abi : Build.SUPPORTED_ABIS) {
6582            Process.establishZygoteConnectionForAbi(abi);
6583            final String instructionSet = VMRuntime.getInstructionSet(abi);
6584            if (!completedIsas.contains(instructionSet)) {
6585                try {
6586                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6587                } catch (InstallerException e) {
6588                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6589                }
6590                completedIsas.add(instructionSet);
6591            }
6592        }
6593
6594        IntentFilter pkgFilter = new IntentFilter();
6595        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6596        pkgFilter.addDataScheme("package");
6597        mContext.registerReceiver(new BroadcastReceiver() {
6598            @Override
6599            public void onReceive(Context context, Intent intent) {
6600                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6601                if (pkgs != null) {
6602                    for (String pkg : pkgs) {
6603                        synchronized (ActivityManagerService.this) {
6604                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6605                                    0, "query restart")) {
6606                                setResultCode(Activity.RESULT_OK);
6607                                return;
6608                            }
6609                        }
6610                    }
6611                }
6612            }
6613        }, pkgFilter);
6614
6615        IntentFilter dumpheapFilter = new IntentFilter();
6616        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6617        mContext.registerReceiver(new BroadcastReceiver() {
6618            @Override
6619            public void onReceive(Context context, Intent intent) {
6620                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6621                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6622                } else {
6623                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6624                }
6625            }
6626        }, dumpheapFilter);
6627
6628        // Let system services know.
6629        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6630
6631        synchronized (this) {
6632            // Ensure that any processes we had put on hold are now started
6633            // up.
6634            final int NP = mProcessesOnHold.size();
6635            if (NP > 0) {
6636                ArrayList<ProcessRecord> procs =
6637                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6638                for (int ip=0; ip<NP; ip++) {
6639                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6640                            + procs.get(ip));
6641                    startProcessLocked(procs.get(ip), "on-hold", null);
6642                }
6643            }
6644
6645            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6646                // Start looking for apps that are abusing wake locks.
6647                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6648                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6649                // Tell anyone interested that we are done booting!
6650                SystemProperties.set("sys.boot_completed", "1");
6651
6652                // And trigger dev.bootcomplete if we are not showing encryption progress
6653                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6654                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6655                    SystemProperties.set("dev.bootcomplete", "1");
6656                }
6657                mUserController.sendBootCompletedLocked(
6658                        new IIntentReceiver.Stub() {
6659                            @Override
6660                            public void performReceive(Intent intent, int resultCode,
6661                                    String data, Bundle extras, boolean ordered,
6662                                    boolean sticky, int sendingUser) {
6663                                synchronized (ActivityManagerService.this) {
6664                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6665                                            true, false);
6666                                }
6667                            }
6668                        });
6669                scheduleStartProfilesLocked();
6670            }
6671        }
6672    }
6673
6674    @Override
6675    public void bootAnimationComplete() {
6676        final boolean callFinishBooting;
6677        synchronized (this) {
6678            callFinishBooting = mCallFinishBooting;
6679            mBootAnimationComplete = true;
6680        }
6681        if (callFinishBooting) {
6682            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6683            finishBooting();
6684            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6685        }
6686    }
6687
6688    final void ensureBootCompleted() {
6689        boolean booting;
6690        boolean enableScreen;
6691        synchronized (this) {
6692            booting = mBooting;
6693            mBooting = false;
6694            enableScreen = !mBooted;
6695            mBooted = true;
6696        }
6697
6698        if (booting) {
6699            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6700            finishBooting();
6701            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6702        }
6703
6704        if (enableScreen) {
6705            enableScreenAfterBoot();
6706        }
6707    }
6708
6709    @Override
6710    public final void activityResumed(IBinder token) {
6711        final long origId = Binder.clearCallingIdentity();
6712        synchronized(this) {
6713            ActivityStack stack = ActivityRecord.getStackLocked(token);
6714            if (stack != null) {
6715                stack.activityResumedLocked(token);
6716            }
6717        }
6718        Binder.restoreCallingIdentity(origId);
6719    }
6720
6721    @Override
6722    public final void activityPaused(IBinder token) {
6723        final long origId = Binder.clearCallingIdentity();
6724        synchronized(this) {
6725            ActivityStack stack = ActivityRecord.getStackLocked(token);
6726            if (stack != null) {
6727                stack.activityPausedLocked(token, false);
6728            }
6729        }
6730        Binder.restoreCallingIdentity(origId);
6731    }
6732
6733    @Override
6734    public final void activityStopped(IBinder token, Bundle icicle,
6735            PersistableBundle persistentState, CharSequence description) {
6736        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6737
6738        // Refuse possible leaked file descriptors
6739        if (icicle != null && icicle.hasFileDescriptors()) {
6740            throw new IllegalArgumentException("File descriptors passed in Bundle");
6741        }
6742
6743        final long origId = Binder.clearCallingIdentity();
6744
6745        synchronized (this) {
6746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6747            if (r != null) {
6748                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6749            }
6750        }
6751
6752        trimApplications();
6753
6754        Binder.restoreCallingIdentity(origId);
6755    }
6756
6757    @Override
6758    public final void activityDestroyed(IBinder token) {
6759        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6760        synchronized (this) {
6761            ActivityStack stack = ActivityRecord.getStackLocked(token);
6762            if (stack != null) {
6763                stack.activityDestroyedLocked(token, "activityDestroyed");
6764            }
6765        }
6766    }
6767
6768    @Override
6769    public final void activityRelaunched(IBinder token) {
6770        final long origId = Binder.clearCallingIdentity();
6771        synchronized (this) {
6772            mStackSupervisor.activityRelaunchedLocked(token);
6773        }
6774        Binder.restoreCallingIdentity(origId);
6775    }
6776
6777    @Override
6778    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6779            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6780        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6781                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6782        synchronized (this) {
6783            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6784            if (record == null) {
6785                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6786                        + "found for: " + token);
6787            }
6788            record.setSizeConfigurations(horizontalSizeConfiguration,
6789                    verticalSizeConfigurations, smallestSizeConfigurations);
6790        }
6791    }
6792
6793    @Override
6794    public final void backgroundResourcesReleased(IBinder token) {
6795        final long origId = Binder.clearCallingIdentity();
6796        try {
6797            synchronized (this) {
6798                ActivityStack stack = ActivityRecord.getStackLocked(token);
6799                if (stack != null) {
6800                    stack.backgroundResourcesReleased();
6801                }
6802            }
6803        } finally {
6804            Binder.restoreCallingIdentity(origId);
6805        }
6806    }
6807
6808    @Override
6809    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6810        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6811    }
6812
6813    @Override
6814    public final void notifyEnterAnimationComplete(IBinder token) {
6815        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6816    }
6817
6818    @Override
6819    public String getCallingPackage(IBinder token) {
6820        synchronized (this) {
6821            ActivityRecord r = getCallingRecordLocked(token);
6822            return r != null ? r.info.packageName : null;
6823        }
6824    }
6825
6826    @Override
6827    public ComponentName getCallingActivity(IBinder token) {
6828        synchronized (this) {
6829            ActivityRecord r = getCallingRecordLocked(token);
6830            return r != null ? r.intent.getComponent() : null;
6831        }
6832    }
6833
6834    private ActivityRecord getCallingRecordLocked(IBinder token) {
6835        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6836        if (r == null) {
6837            return null;
6838        }
6839        return r.resultTo;
6840    }
6841
6842    @Override
6843    public ComponentName getActivityClassForToken(IBinder token) {
6844        synchronized(this) {
6845            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6846            if (r == null) {
6847                return null;
6848            }
6849            return r.intent.getComponent();
6850        }
6851    }
6852
6853    @Override
6854    public String getPackageForToken(IBinder token) {
6855        synchronized(this) {
6856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6857            if (r == null) {
6858                return null;
6859            }
6860            return r.packageName;
6861        }
6862    }
6863
6864    @Override
6865    public boolean isRootVoiceInteraction(IBinder token) {
6866        synchronized(this) {
6867            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6868            if (r == null) {
6869                return false;
6870            }
6871            return r.rootVoiceInteraction;
6872        }
6873    }
6874
6875    @Override
6876    public IIntentSender getIntentSender(int type,
6877            String packageName, IBinder token, String resultWho,
6878            int requestCode, Intent[] intents, String[] resolvedTypes,
6879            int flags, Bundle bOptions, int userId) {
6880        enforceNotIsolatedCaller("getIntentSender");
6881        // Refuse possible leaked file descriptors
6882        if (intents != null) {
6883            if (intents.length < 1) {
6884                throw new IllegalArgumentException("Intents array length must be >= 1");
6885            }
6886            for (int i=0; i<intents.length; i++) {
6887                Intent intent = intents[i];
6888                if (intent != null) {
6889                    if (intent.hasFileDescriptors()) {
6890                        throw new IllegalArgumentException("File descriptors passed in Intent");
6891                    }
6892                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6893                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6894                        throw new IllegalArgumentException(
6895                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6896                    }
6897                    intents[i] = new Intent(intent);
6898                }
6899            }
6900            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6901                throw new IllegalArgumentException(
6902                        "Intent array length does not match resolvedTypes length");
6903            }
6904        }
6905        if (bOptions != null) {
6906            if (bOptions.hasFileDescriptors()) {
6907                throw new IllegalArgumentException("File descriptors passed in options");
6908            }
6909        }
6910
6911        synchronized(this) {
6912            int callingUid = Binder.getCallingUid();
6913            int origUserId = userId;
6914            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6915                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6916                    ALLOW_NON_FULL, "getIntentSender", null);
6917            if (origUserId == UserHandle.USER_CURRENT) {
6918                // We don't want to evaluate this until the pending intent is
6919                // actually executed.  However, we do want to always do the
6920                // security checking for it above.
6921                userId = UserHandle.USER_CURRENT;
6922            }
6923            try {
6924                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6925                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6926                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6927                    if (!UserHandle.isSameApp(callingUid, uid)) {
6928                        String msg = "Permission Denial: getIntentSender() from pid="
6929                            + Binder.getCallingPid()
6930                            + ", uid=" + Binder.getCallingUid()
6931                            + ", (need uid=" + uid + ")"
6932                            + " is not allowed to send as package " + packageName;
6933                        Slog.w(TAG, msg);
6934                        throw new SecurityException(msg);
6935                    }
6936                }
6937
6938                return getIntentSenderLocked(type, packageName, callingUid, userId,
6939                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6940
6941            } catch (RemoteException e) {
6942                throw new SecurityException(e);
6943            }
6944        }
6945    }
6946
6947    IIntentSender getIntentSenderLocked(int type, String packageName,
6948            int callingUid, int userId, IBinder token, String resultWho,
6949            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6950            Bundle bOptions) {
6951        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6952        ActivityRecord activity = null;
6953        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6954            activity = ActivityRecord.isInStackLocked(token);
6955            if (activity == null) {
6956                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6957                return null;
6958            }
6959            if (activity.finishing) {
6960                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6961                return null;
6962            }
6963        }
6964
6965        // We're going to be splicing together extras before sending, so we're
6966        // okay poking into any contained extras.
6967        if (intents != null) {
6968            for (int i = 0; i < intents.length; i++) {
6969                intents[i].setDefusable(true);
6970            }
6971        }
6972        Bundle.setDefusable(bOptions, true);
6973
6974        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6975        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6976        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6977        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6978                |PendingIntent.FLAG_UPDATE_CURRENT);
6979
6980        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6981                type, packageName, activity, resultWho,
6982                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6983        WeakReference<PendingIntentRecord> ref;
6984        ref = mIntentSenderRecords.get(key);
6985        PendingIntentRecord rec = ref != null ? ref.get() : null;
6986        if (rec != null) {
6987            if (!cancelCurrent) {
6988                if (updateCurrent) {
6989                    if (rec.key.requestIntent != null) {
6990                        rec.key.requestIntent.replaceExtras(intents != null ?
6991                                intents[intents.length - 1] : null);
6992                    }
6993                    if (intents != null) {
6994                        intents[intents.length-1] = rec.key.requestIntent;
6995                        rec.key.allIntents = intents;
6996                        rec.key.allResolvedTypes = resolvedTypes;
6997                    } else {
6998                        rec.key.allIntents = null;
6999                        rec.key.allResolvedTypes = null;
7000                    }
7001                }
7002                return rec;
7003            }
7004            rec.canceled = true;
7005            mIntentSenderRecords.remove(key);
7006        }
7007        if (noCreate) {
7008            return rec;
7009        }
7010        rec = new PendingIntentRecord(this, key, callingUid);
7011        mIntentSenderRecords.put(key, rec.ref);
7012        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7013            if (activity.pendingResults == null) {
7014                activity.pendingResults
7015                        = new HashSet<WeakReference<PendingIntentRecord>>();
7016            }
7017            activity.pendingResults.add(rec.ref);
7018        }
7019        return rec;
7020    }
7021
7022    @Override
7023    public void cancelIntentSender(IIntentSender sender) {
7024        if (!(sender instanceof PendingIntentRecord)) {
7025            return;
7026        }
7027        synchronized(this) {
7028            PendingIntentRecord rec = (PendingIntentRecord)sender;
7029            try {
7030                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7031                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7032                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7033                    String msg = "Permission Denial: cancelIntentSender() from pid="
7034                        + Binder.getCallingPid()
7035                        + ", uid=" + Binder.getCallingUid()
7036                        + " is not allowed to cancel packges "
7037                        + rec.key.packageName;
7038                    Slog.w(TAG, msg);
7039                    throw new SecurityException(msg);
7040                }
7041            } catch (RemoteException e) {
7042                throw new SecurityException(e);
7043            }
7044            cancelIntentSenderLocked(rec, true);
7045        }
7046    }
7047
7048    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7049        rec.canceled = true;
7050        mIntentSenderRecords.remove(rec.key);
7051        if (cleanActivity && rec.key.activity != null) {
7052            rec.key.activity.pendingResults.remove(rec.ref);
7053        }
7054    }
7055
7056    @Override
7057    public String getPackageForIntentSender(IIntentSender pendingResult) {
7058        if (!(pendingResult instanceof PendingIntentRecord)) {
7059            return null;
7060        }
7061        try {
7062            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7063            return res.key.packageName;
7064        } catch (ClassCastException e) {
7065        }
7066        return null;
7067    }
7068
7069    @Override
7070    public int getUidForIntentSender(IIntentSender sender) {
7071        if (sender instanceof PendingIntentRecord) {
7072            try {
7073                PendingIntentRecord res = (PendingIntentRecord)sender;
7074                return res.uid;
7075            } catch (ClassCastException e) {
7076            }
7077        }
7078        return -1;
7079    }
7080
7081    @Override
7082    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7083        if (!(pendingResult instanceof PendingIntentRecord)) {
7084            return false;
7085        }
7086        try {
7087            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7088            if (res.key.allIntents == null) {
7089                return false;
7090            }
7091            for (int i=0; i<res.key.allIntents.length; i++) {
7092                Intent intent = res.key.allIntents[i];
7093                if (intent.getPackage() != null && intent.getComponent() != null) {
7094                    return false;
7095                }
7096            }
7097            return true;
7098        } catch (ClassCastException e) {
7099        }
7100        return false;
7101    }
7102
7103    @Override
7104    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7105        if (!(pendingResult instanceof PendingIntentRecord)) {
7106            return false;
7107        }
7108        try {
7109            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7110            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7111                return true;
7112            }
7113            return false;
7114        } catch (ClassCastException e) {
7115        }
7116        return false;
7117    }
7118
7119    @Override
7120    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7121        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7122                "getIntentForIntentSender()");
7123        if (!(pendingResult instanceof PendingIntentRecord)) {
7124            return null;
7125        }
7126        try {
7127            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7128            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7129        } catch (ClassCastException e) {
7130        }
7131        return null;
7132    }
7133
7134    @Override
7135    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7136        if (!(pendingResult instanceof PendingIntentRecord)) {
7137            return null;
7138        }
7139        try {
7140            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7141            synchronized (this) {
7142                return getTagForIntentSenderLocked(res, prefix);
7143            }
7144        } catch (ClassCastException e) {
7145        }
7146        return null;
7147    }
7148
7149    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7150        final Intent intent = res.key.requestIntent;
7151        if (intent != null) {
7152            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7153                    || res.lastTagPrefix.equals(prefix))) {
7154                return res.lastTag;
7155            }
7156            res.lastTagPrefix = prefix;
7157            final StringBuilder sb = new StringBuilder(128);
7158            if (prefix != null) {
7159                sb.append(prefix);
7160            }
7161            if (intent.getAction() != null) {
7162                sb.append(intent.getAction());
7163            } else if (intent.getComponent() != null) {
7164                intent.getComponent().appendShortString(sb);
7165            } else {
7166                sb.append("?");
7167            }
7168            return res.lastTag = sb.toString();
7169        }
7170        return null;
7171    }
7172
7173    @Override
7174    public void setProcessLimit(int max) {
7175        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7176                "setProcessLimit()");
7177        synchronized (this) {
7178            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7179            mProcessLimitOverride = max;
7180        }
7181        trimApplications();
7182    }
7183
7184    @Override
7185    public int getProcessLimit() {
7186        synchronized (this) {
7187            return mProcessLimitOverride;
7188        }
7189    }
7190
7191    void foregroundTokenDied(ForegroundToken token) {
7192        synchronized (ActivityManagerService.this) {
7193            synchronized (mPidsSelfLocked) {
7194                ForegroundToken cur
7195                    = mForegroundProcesses.get(token.pid);
7196                if (cur != token) {
7197                    return;
7198                }
7199                mForegroundProcesses.remove(token.pid);
7200                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7201                if (pr == null) {
7202                    return;
7203                }
7204                pr.forcingToForeground = null;
7205                updateProcessForegroundLocked(pr, false, false);
7206            }
7207            updateOomAdjLocked();
7208        }
7209    }
7210
7211    @Override
7212    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7213        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7214                "setProcessForeground()");
7215        synchronized(this) {
7216            boolean changed = false;
7217
7218            synchronized (mPidsSelfLocked) {
7219                ProcessRecord pr = mPidsSelfLocked.get(pid);
7220                if (pr == null && isForeground) {
7221                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7222                    return;
7223                }
7224                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7225                if (oldToken != null) {
7226                    oldToken.token.unlinkToDeath(oldToken, 0);
7227                    mForegroundProcesses.remove(pid);
7228                    if (pr != null) {
7229                        pr.forcingToForeground = null;
7230                    }
7231                    changed = true;
7232                }
7233                if (isForeground && token != null) {
7234                    ForegroundToken newToken = new ForegroundToken() {
7235                        @Override
7236                        public void binderDied() {
7237                            foregroundTokenDied(this);
7238                        }
7239                    };
7240                    newToken.pid = pid;
7241                    newToken.token = token;
7242                    try {
7243                        token.linkToDeath(newToken, 0);
7244                        mForegroundProcesses.put(pid, newToken);
7245                        pr.forcingToForeground = token;
7246                        changed = true;
7247                    } catch (RemoteException e) {
7248                        // If the process died while doing this, we will later
7249                        // do the cleanup with the process death link.
7250                    }
7251                }
7252            }
7253
7254            if (changed) {
7255                updateOomAdjLocked();
7256            }
7257        }
7258    }
7259
7260    @Override
7261    public boolean isAppForeground(int uid) throws RemoteException {
7262        synchronized (this) {
7263            UidRecord uidRec = mActiveUids.get(uid);
7264            if (uidRec == null || uidRec.idle) {
7265                return false;
7266            }
7267            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7268        }
7269    }
7270
7271    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7272    // be guarded by permission checking.
7273    int getUidState(int uid) {
7274        synchronized (this) {
7275            UidRecord uidRec = mActiveUids.get(uid);
7276            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7277        }
7278    }
7279
7280    @Override
7281    public boolean isInMultiWindowMode(IBinder token) {
7282        final long origId = Binder.clearCallingIdentity();
7283        try {
7284            synchronized(this) {
7285                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7286                if (r == null) {
7287                    return false;
7288                }
7289                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7290                return !r.task.mFullscreen;
7291            }
7292        } finally {
7293            Binder.restoreCallingIdentity(origId);
7294        }
7295    }
7296
7297    @Override
7298    public boolean isInPictureInPictureMode(IBinder token) {
7299        final long origId = Binder.clearCallingIdentity();
7300        try {
7301            synchronized(this) {
7302                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7303                if (stack == null) {
7304                    return false;
7305                }
7306                return stack.mStackId == PINNED_STACK_ID;
7307            }
7308        } finally {
7309            Binder.restoreCallingIdentity(origId);
7310        }
7311    }
7312
7313    @Override
7314    public void enterPictureInPictureMode(IBinder token) {
7315        final long origId = Binder.clearCallingIdentity();
7316        try {
7317            synchronized(this) {
7318                if (!mSupportsPictureInPicture) {
7319                    throw new IllegalStateException("enterPictureInPictureMode: "
7320                            + "Device doesn't support picture-in-picture mode.");
7321                }
7322
7323                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7324
7325                if (r == null) {
7326                    throw new IllegalStateException("enterPictureInPictureMode: "
7327                            + "Can't find activity for token=" + token);
7328                }
7329
7330                if (!r.supportsPictureInPicture()) {
7331                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7332                            + "Picture-In-Picture not supported for r=" + r);
7333                }
7334
7335                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7336                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7337                        ? mDefaultPinnedStackBounds : null;
7338
7339                mStackSupervisor.moveActivityToPinnedStackLocked(
7340                        r, "enterPictureInPictureMode", bounds);
7341            }
7342        } finally {
7343            Binder.restoreCallingIdentity(origId);
7344        }
7345    }
7346
7347    // =========================================================
7348    // PROCESS INFO
7349    // =========================================================
7350
7351    static class ProcessInfoService extends IProcessInfoService.Stub {
7352        final ActivityManagerService mActivityManagerService;
7353        ProcessInfoService(ActivityManagerService activityManagerService) {
7354            mActivityManagerService = activityManagerService;
7355        }
7356
7357        @Override
7358        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7359            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7360                    /*in*/ pids, /*out*/ states, null);
7361        }
7362
7363        @Override
7364        public void getProcessStatesAndOomScoresFromPids(
7365                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7366            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7367                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7368        }
7369    }
7370
7371    /**
7372     * For each PID in the given input array, write the current process state
7373     * for that process into the states array, or -1 to indicate that no
7374     * process with the given PID exists. If scores array is provided, write
7375     * the oom score for the process into the scores array, with INVALID_ADJ
7376     * indicating the PID doesn't exist.
7377     */
7378    public void getProcessStatesAndOomScoresForPIDs(
7379            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7380        if (scores != null) {
7381            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7382                    "getProcessStatesAndOomScoresForPIDs()");
7383        }
7384
7385        if (pids == null) {
7386            throw new NullPointerException("pids");
7387        } else if (states == null) {
7388            throw new NullPointerException("states");
7389        } else if (pids.length != states.length) {
7390            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7391        } else if (scores != null && pids.length != scores.length) {
7392            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7393        }
7394
7395        synchronized (mPidsSelfLocked) {
7396            for (int i = 0; i < pids.length; i++) {
7397                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7398                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7399                        pr.curProcState;
7400                if (scores != null) {
7401                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7402                }
7403            }
7404        }
7405    }
7406
7407    // =========================================================
7408    // PERMISSIONS
7409    // =========================================================
7410
7411    static class PermissionController extends IPermissionController.Stub {
7412        ActivityManagerService mActivityManagerService;
7413        PermissionController(ActivityManagerService activityManagerService) {
7414            mActivityManagerService = activityManagerService;
7415        }
7416
7417        @Override
7418        public boolean checkPermission(String permission, int pid, int uid) {
7419            return mActivityManagerService.checkPermission(permission, pid,
7420                    uid) == PackageManager.PERMISSION_GRANTED;
7421        }
7422
7423        @Override
7424        public String[] getPackagesForUid(int uid) {
7425            return mActivityManagerService.mContext.getPackageManager()
7426                    .getPackagesForUid(uid);
7427        }
7428
7429        @Override
7430        public boolean isRuntimePermission(String permission) {
7431            try {
7432                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7433                        .getPermissionInfo(permission, 0);
7434                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7435            } catch (NameNotFoundException nnfe) {
7436                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7437            }
7438            return false;
7439        }
7440    }
7441
7442    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7443        @Override
7444        public int checkComponentPermission(String permission, int pid, int uid,
7445                int owningUid, boolean exported) {
7446            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7447                    owningUid, exported);
7448        }
7449
7450        @Override
7451        public Object getAMSLock() {
7452            return ActivityManagerService.this;
7453        }
7454    }
7455
7456    /**
7457     * This can be called with or without the global lock held.
7458     */
7459    int checkComponentPermission(String permission, int pid, int uid,
7460            int owningUid, boolean exported) {
7461        if (pid == MY_PID) {
7462            return PackageManager.PERMISSION_GRANTED;
7463        }
7464        return ActivityManager.checkComponentPermission(permission, uid,
7465                owningUid, exported);
7466    }
7467
7468    /**
7469     * As the only public entry point for permissions checking, this method
7470     * can enforce the semantic that requesting a check on a null global
7471     * permission is automatically denied.  (Internally a null permission
7472     * string is used when calling {@link #checkComponentPermission} in cases
7473     * when only uid-based security is needed.)
7474     *
7475     * This can be called with or without the global lock held.
7476     */
7477    @Override
7478    public int checkPermission(String permission, int pid, int uid) {
7479        if (permission == null) {
7480            return PackageManager.PERMISSION_DENIED;
7481        }
7482        return checkComponentPermission(permission, pid, uid, -1, true);
7483    }
7484
7485    @Override
7486    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7487        if (permission == null) {
7488            return PackageManager.PERMISSION_DENIED;
7489        }
7490
7491        // We might be performing an operation on behalf of an indirect binder
7492        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7493        // client identity accordingly before proceeding.
7494        Identity tlsIdentity = sCallerIdentity.get();
7495        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7496            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7497                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7498            uid = tlsIdentity.uid;
7499            pid = tlsIdentity.pid;
7500        }
7501
7502        return checkComponentPermission(permission, pid, uid, -1, true);
7503    }
7504
7505    /**
7506     * Binder IPC calls go through the public entry point.
7507     * This can be called with or without the global lock held.
7508     */
7509    int checkCallingPermission(String permission) {
7510        return checkPermission(permission,
7511                Binder.getCallingPid(),
7512                UserHandle.getAppId(Binder.getCallingUid()));
7513    }
7514
7515    /**
7516     * This can be called with or without the global lock held.
7517     */
7518    void enforceCallingPermission(String permission, String func) {
7519        if (checkCallingPermission(permission)
7520                == PackageManager.PERMISSION_GRANTED) {
7521            return;
7522        }
7523
7524        String msg = "Permission Denial: " + func + " from pid="
7525                + Binder.getCallingPid()
7526                + ", uid=" + Binder.getCallingUid()
7527                + " requires " + permission;
7528        Slog.w(TAG, msg);
7529        throw new SecurityException(msg);
7530    }
7531
7532    /**
7533     * Determine if UID is holding permissions required to access {@link Uri} in
7534     * the given {@link ProviderInfo}. Final permission checking is always done
7535     * in {@link ContentProvider}.
7536     */
7537    private final boolean checkHoldingPermissionsLocked(
7538            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7539        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7540                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7541        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7542            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7543                    != PERMISSION_GRANTED) {
7544                return false;
7545            }
7546        }
7547        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7548    }
7549
7550    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7551            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7552        if (pi.applicationInfo.uid == uid) {
7553            return true;
7554        } else if (!pi.exported) {
7555            return false;
7556        }
7557
7558        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7559        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7560        try {
7561            // check if target holds top-level <provider> permissions
7562            if (!readMet && pi.readPermission != null && considerUidPermissions
7563                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7564                readMet = true;
7565            }
7566            if (!writeMet && pi.writePermission != null && considerUidPermissions
7567                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7568                writeMet = true;
7569            }
7570
7571            // track if unprotected read/write is allowed; any denied
7572            // <path-permission> below removes this ability
7573            boolean allowDefaultRead = pi.readPermission == null;
7574            boolean allowDefaultWrite = pi.writePermission == null;
7575
7576            // check if target holds any <path-permission> that match uri
7577            final PathPermission[] pps = pi.pathPermissions;
7578            if (pps != null) {
7579                final String path = grantUri.uri.getPath();
7580                int i = pps.length;
7581                while (i > 0 && (!readMet || !writeMet)) {
7582                    i--;
7583                    PathPermission pp = pps[i];
7584                    if (pp.match(path)) {
7585                        if (!readMet) {
7586                            final String pprperm = pp.getReadPermission();
7587                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7588                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7589                                    + ": match=" + pp.match(path)
7590                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7591                            if (pprperm != null) {
7592                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7593                                        == PERMISSION_GRANTED) {
7594                                    readMet = true;
7595                                } else {
7596                                    allowDefaultRead = false;
7597                                }
7598                            }
7599                        }
7600                        if (!writeMet) {
7601                            final String ppwperm = pp.getWritePermission();
7602                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7603                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7604                                    + ": match=" + pp.match(path)
7605                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7606                            if (ppwperm != null) {
7607                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7608                                        == PERMISSION_GRANTED) {
7609                                    writeMet = true;
7610                                } else {
7611                                    allowDefaultWrite = false;
7612                                }
7613                            }
7614                        }
7615                    }
7616                }
7617            }
7618
7619            // grant unprotected <provider> read/write, if not blocked by
7620            // <path-permission> above
7621            if (allowDefaultRead) readMet = true;
7622            if (allowDefaultWrite) writeMet = true;
7623
7624        } catch (RemoteException e) {
7625            return false;
7626        }
7627
7628        return readMet && writeMet;
7629    }
7630
7631    public int getAppStartMode(int uid, String packageName) {
7632        synchronized (this) {
7633            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7634        }
7635    }
7636
7637    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7638            boolean allowWhenForeground) {
7639        UidRecord uidRec = mActiveUids.get(uid);
7640        if (!mLenientBackgroundCheck) {
7641            if (!allowWhenForeground || uidRec == null
7642                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7643                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7644                        packageName) != AppOpsManager.MODE_ALLOWED) {
7645                    return ActivityManager.APP_START_MODE_DELAYED;
7646                }
7647            }
7648
7649        } else if (uidRec == null || uidRec.idle) {
7650            if (callingPid >= 0) {
7651                ProcessRecord proc;
7652                synchronized (mPidsSelfLocked) {
7653                    proc = mPidsSelfLocked.get(callingPid);
7654                }
7655                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7656                    // Whoever is instigating this is in the foreground, so we will allow it
7657                    // to go through.
7658                    return ActivityManager.APP_START_MODE_NORMAL;
7659                }
7660            }
7661            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7662                    != AppOpsManager.MODE_ALLOWED) {
7663                return ActivityManager.APP_START_MODE_DELAYED;
7664            }
7665        }
7666        return ActivityManager.APP_START_MODE_NORMAL;
7667    }
7668
7669    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7670        ProviderInfo pi = null;
7671        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7672        if (cpr != null) {
7673            pi = cpr.info;
7674        } else {
7675            try {
7676                pi = AppGlobals.getPackageManager().resolveContentProvider(
7677                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7678            } catch (RemoteException ex) {
7679            }
7680        }
7681        return pi;
7682    }
7683
7684    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7685        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7686        if (targetUris != null) {
7687            return targetUris.get(grantUri);
7688        }
7689        return null;
7690    }
7691
7692    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7693            String targetPkg, int targetUid, GrantUri grantUri) {
7694        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7695        if (targetUris == null) {
7696            targetUris = Maps.newArrayMap();
7697            mGrantedUriPermissions.put(targetUid, targetUris);
7698        }
7699
7700        UriPermission perm = targetUris.get(grantUri);
7701        if (perm == null) {
7702            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7703            targetUris.put(grantUri, perm);
7704        }
7705
7706        return perm;
7707    }
7708
7709    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7710            final int modeFlags) {
7711        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7712        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7713                : UriPermission.STRENGTH_OWNED;
7714
7715        // Root gets to do everything.
7716        if (uid == 0) {
7717            return true;
7718        }
7719
7720        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7721        if (perms == null) return false;
7722
7723        // First look for exact match
7724        final UriPermission exactPerm = perms.get(grantUri);
7725        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7726            return true;
7727        }
7728
7729        // No exact match, look for prefixes
7730        final int N = perms.size();
7731        for (int i = 0; i < N; i++) {
7732            final UriPermission perm = perms.valueAt(i);
7733            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7734                    && perm.getStrength(modeFlags) >= minStrength) {
7735                return true;
7736            }
7737        }
7738
7739        return false;
7740    }
7741
7742    /**
7743     * @param uri This uri must NOT contain an embedded userId.
7744     * @param userId The userId in which the uri is to be resolved.
7745     */
7746    @Override
7747    public int checkUriPermission(Uri uri, int pid, int uid,
7748            final int modeFlags, int userId, IBinder callerToken) {
7749        enforceNotIsolatedCaller("checkUriPermission");
7750
7751        // Another redirected-binder-call permissions check as in
7752        // {@link checkPermissionWithToken}.
7753        Identity tlsIdentity = sCallerIdentity.get();
7754        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7755            uid = tlsIdentity.uid;
7756            pid = tlsIdentity.pid;
7757        }
7758
7759        // Our own process gets to do everything.
7760        if (pid == MY_PID) {
7761            return PackageManager.PERMISSION_GRANTED;
7762        }
7763        synchronized (this) {
7764            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7765                    ? PackageManager.PERMISSION_GRANTED
7766                    : PackageManager.PERMISSION_DENIED;
7767        }
7768    }
7769
7770    /**
7771     * Check if the targetPkg can be granted permission to access uri by
7772     * the callingUid using the given modeFlags.  Throws a security exception
7773     * if callingUid is not allowed to do this.  Returns the uid of the target
7774     * if the URI permission grant should be performed; returns -1 if it is not
7775     * needed (for example targetPkg already has permission to access the URI).
7776     * If you already know the uid of the target, you can supply it in
7777     * lastTargetUid else set that to -1.
7778     */
7779    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7780            final int modeFlags, int lastTargetUid) {
7781        if (!Intent.isAccessUriMode(modeFlags)) {
7782            return -1;
7783        }
7784
7785        if (targetPkg != null) {
7786            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7787                    "Checking grant " + targetPkg + " permission to " + grantUri);
7788        }
7789
7790        final IPackageManager pm = AppGlobals.getPackageManager();
7791
7792        // If this is not a content: uri, we can't do anything with it.
7793        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7794            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7795                    "Can't grant URI permission for non-content URI: " + grantUri);
7796            return -1;
7797        }
7798
7799        final String authority = grantUri.uri.getAuthority();
7800        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7801        if (pi == null) {
7802            Slog.w(TAG, "No content provider found for permission check: " +
7803                    grantUri.uri.toSafeString());
7804            return -1;
7805        }
7806
7807        int targetUid = lastTargetUid;
7808        if (targetUid < 0 && targetPkg != null) {
7809            try {
7810                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7811                        UserHandle.getUserId(callingUid));
7812                if (targetUid < 0) {
7813                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7814                            "Can't grant URI permission no uid for: " + targetPkg);
7815                    return -1;
7816                }
7817            } catch (RemoteException ex) {
7818                return -1;
7819            }
7820        }
7821
7822        if (targetUid >= 0) {
7823            // First...  does the target actually need this permission?
7824            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7825                // No need to grant the target this permission.
7826                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7827                        "Target " + targetPkg + " already has full permission to " + grantUri);
7828                return -1;
7829            }
7830        } else {
7831            // First...  there is no target package, so can anyone access it?
7832            boolean allowed = pi.exported;
7833            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7834                if (pi.readPermission != null) {
7835                    allowed = false;
7836                }
7837            }
7838            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7839                if (pi.writePermission != null) {
7840                    allowed = false;
7841                }
7842            }
7843            if (allowed) {
7844                return -1;
7845            }
7846        }
7847
7848        /* There is a special cross user grant if:
7849         * - The target is on another user.
7850         * - Apps on the current user can access the uri without any uid permissions.
7851         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7852         * grant uri permissions.
7853         */
7854        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7855                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7856                modeFlags, false /*without considering the uid permissions*/);
7857
7858        // Second...  is the provider allowing granting of URI permissions?
7859        if (!specialCrossUserGrant) {
7860            if (!pi.grantUriPermissions) {
7861                throw new SecurityException("Provider " + pi.packageName
7862                        + "/" + pi.name
7863                        + " does not allow granting of Uri permissions (uri "
7864                        + grantUri + ")");
7865            }
7866            if (pi.uriPermissionPatterns != null) {
7867                final int N = pi.uriPermissionPatterns.length;
7868                boolean allowed = false;
7869                for (int i=0; i<N; i++) {
7870                    if (pi.uriPermissionPatterns[i] != null
7871                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7872                        allowed = true;
7873                        break;
7874                    }
7875                }
7876                if (!allowed) {
7877                    throw new SecurityException("Provider " + pi.packageName
7878                            + "/" + pi.name
7879                            + " does not allow granting of permission to path of Uri "
7880                            + grantUri);
7881                }
7882            }
7883        }
7884
7885        // Third...  does the caller itself have permission to access
7886        // this uri?
7887        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7888            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7889                // Require they hold a strong enough Uri permission
7890                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7891                    throw new SecurityException("Uid " + callingUid
7892                            + " does not have permission to uri " + grantUri);
7893                }
7894            }
7895        }
7896        return targetUid;
7897    }
7898
7899    /**
7900     * @param uri This uri must NOT contain an embedded userId.
7901     * @param userId The userId in which the uri is to be resolved.
7902     */
7903    @Override
7904    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7905            final int modeFlags, int userId) {
7906        enforceNotIsolatedCaller("checkGrantUriPermission");
7907        synchronized(this) {
7908            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7909                    new GrantUri(userId, uri, false), modeFlags, -1);
7910        }
7911    }
7912
7913    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7914            final int modeFlags, UriPermissionOwner owner) {
7915        if (!Intent.isAccessUriMode(modeFlags)) {
7916            return;
7917        }
7918
7919        // So here we are: the caller has the assumed permission
7920        // to the uri, and the target doesn't.  Let's now give this to
7921        // the target.
7922
7923        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7924                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7925
7926        final String authority = grantUri.uri.getAuthority();
7927        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7928        if (pi == null) {
7929            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7930            return;
7931        }
7932
7933        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7934            grantUri.prefix = true;
7935        }
7936        final UriPermission perm = findOrCreateUriPermissionLocked(
7937                pi.packageName, targetPkg, targetUid, grantUri);
7938        perm.grantModes(modeFlags, owner);
7939    }
7940
7941    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7942            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7943        if (targetPkg == null) {
7944            throw new NullPointerException("targetPkg");
7945        }
7946        int targetUid;
7947        final IPackageManager pm = AppGlobals.getPackageManager();
7948        try {
7949            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7950        } catch (RemoteException ex) {
7951            return;
7952        }
7953
7954        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7955                targetUid);
7956        if (targetUid < 0) {
7957            return;
7958        }
7959
7960        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7961                owner);
7962    }
7963
7964    static class NeededUriGrants extends ArrayList<GrantUri> {
7965        final String targetPkg;
7966        final int targetUid;
7967        final int flags;
7968
7969        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7970            this.targetPkg = targetPkg;
7971            this.targetUid = targetUid;
7972            this.flags = flags;
7973        }
7974    }
7975
7976    /**
7977     * Like checkGrantUriPermissionLocked, but takes an Intent.
7978     */
7979    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7980            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7981        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7983                + " clip=" + (intent != null ? intent.getClipData() : null)
7984                + " from " + intent + "; flags=0x"
7985                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7986
7987        if (targetPkg == null) {
7988            throw new NullPointerException("targetPkg");
7989        }
7990
7991        if (intent == null) {
7992            return null;
7993        }
7994        Uri data = intent.getData();
7995        ClipData clip = intent.getClipData();
7996        if (data == null && clip == null) {
7997            return null;
7998        }
7999        // Default userId for uris in the intent (if they don't specify it themselves)
8000        int contentUserHint = intent.getContentUserHint();
8001        if (contentUserHint == UserHandle.USER_CURRENT) {
8002            contentUserHint = UserHandle.getUserId(callingUid);
8003        }
8004        final IPackageManager pm = AppGlobals.getPackageManager();
8005        int targetUid;
8006        if (needed != null) {
8007            targetUid = needed.targetUid;
8008        } else {
8009            try {
8010                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8011                        targetUserId);
8012            } catch (RemoteException ex) {
8013                return null;
8014            }
8015            if (targetUid < 0) {
8016                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8017                        "Can't grant URI permission no uid for: " + targetPkg
8018                        + " on user " + targetUserId);
8019                return null;
8020            }
8021        }
8022        if (data != null) {
8023            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8024            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8025                    targetUid);
8026            if (targetUid > 0) {
8027                if (needed == null) {
8028                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8029                }
8030                needed.add(grantUri);
8031            }
8032        }
8033        if (clip != null) {
8034            for (int i=0; i<clip.getItemCount(); i++) {
8035                Uri uri = clip.getItemAt(i).getUri();
8036                if (uri != null) {
8037                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8038                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8039                            targetUid);
8040                    if (targetUid > 0) {
8041                        if (needed == null) {
8042                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8043                        }
8044                        needed.add(grantUri);
8045                    }
8046                } else {
8047                    Intent clipIntent = clip.getItemAt(i).getIntent();
8048                    if (clipIntent != null) {
8049                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8050                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8051                        if (newNeeded != null) {
8052                            needed = newNeeded;
8053                        }
8054                    }
8055                }
8056            }
8057        }
8058
8059        return needed;
8060    }
8061
8062    /**
8063     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8064     */
8065    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8066            UriPermissionOwner owner) {
8067        if (needed != null) {
8068            for (int i=0; i<needed.size(); i++) {
8069                GrantUri grantUri = needed.get(i);
8070                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8071                        grantUri, needed.flags, owner);
8072            }
8073        }
8074    }
8075
8076    void grantUriPermissionFromIntentLocked(int callingUid,
8077            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8078        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8079                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8080        if (needed == null) {
8081            return;
8082        }
8083
8084        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8085    }
8086
8087    /**
8088     * @param uri This uri must NOT contain an embedded userId.
8089     * @param userId The userId in which the uri is to be resolved.
8090     */
8091    @Override
8092    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8093            final int modeFlags, int userId) {
8094        enforceNotIsolatedCaller("grantUriPermission");
8095        GrantUri grantUri = new GrantUri(userId, uri, false);
8096        synchronized(this) {
8097            final ProcessRecord r = getRecordForAppLocked(caller);
8098            if (r == null) {
8099                throw new SecurityException("Unable to find app for caller "
8100                        + caller
8101                        + " when granting permission to uri " + grantUri);
8102            }
8103            if (targetPkg == null) {
8104                throw new IllegalArgumentException("null target");
8105            }
8106            if (grantUri == null) {
8107                throw new IllegalArgumentException("null uri");
8108            }
8109
8110            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8111                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8112                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8113                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8114
8115            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8116                    UserHandle.getUserId(r.uid));
8117        }
8118    }
8119
8120    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8121        if (perm.modeFlags == 0) {
8122            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8123                    perm.targetUid);
8124            if (perms != null) {
8125                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8126                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8127
8128                perms.remove(perm.uri);
8129                if (perms.isEmpty()) {
8130                    mGrantedUriPermissions.remove(perm.targetUid);
8131                }
8132            }
8133        }
8134    }
8135
8136    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8137        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8138                "Revoking all granted permissions to " + grantUri);
8139
8140        final IPackageManager pm = AppGlobals.getPackageManager();
8141        final String authority = grantUri.uri.getAuthority();
8142        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8143        if (pi == null) {
8144            Slog.w(TAG, "No content provider found for permission revoke: "
8145                    + grantUri.toSafeString());
8146            return;
8147        }
8148
8149        // Does the caller have this permission on the URI?
8150        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8151            // If they don't have direct access to the URI, then revoke any
8152            // ownerless URI permissions that have been granted to them.
8153            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8154            if (perms != null) {
8155                boolean persistChanged = false;
8156                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8157                    final UriPermission perm = it.next();
8158                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8159                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8160                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8161                                "Revoking non-owned " + perm.targetUid
8162                                + " permission to " + perm.uri);
8163                        persistChanged |= perm.revokeModes(
8164                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8165                        if (perm.modeFlags == 0) {
8166                            it.remove();
8167                        }
8168                    }
8169                }
8170                if (perms.isEmpty()) {
8171                    mGrantedUriPermissions.remove(callingUid);
8172                }
8173                if (persistChanged) {
8174                    schedulePersistUriGrants();
8175                }
8176            }
8177            return;
8178        }
8179
8180        boolean persistChanged = false;
8181
8182        // Go through all of the permissions and remove any that match.
8183        int N = mGrantedUriPermissions.size();
8184        for (int i = 0; i < N; i++) {
8185            final int targetUid = mGrantedUriPermissions.keyAt(i);
8186            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8187
8188            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8189                final UriPermission perm = it.next();
8190                if (perm.uri.sourceUserId == grantUri.sourceUserId
8191                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8192                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8193                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8194                    persistChanged |= perm.revokeModes(
8195                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8196                    if (perm.modeFlags == 0) {
8197                        it.remove();
8198                    }
8199                }
8200            }
8201
8202            if (perms.isEmpty()) {
8203                mGrantedUriPermissions.remove(targetUid);
8204                N--;
8205                i--;
8206            }
8207        }
8208
8209        if (persistChanged) {
8210            schedulePersistUriGrants();
8211        }
8212    }
8213
8214    /**
8215     * @param uri This uri must NOT contain an embedded userId.
8216     * @param userId The userId in which the uri is to be resolved.
8217     */
8218    @Override
8219    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8220            int userId) {
8221        enforceNotIsolatedCaller("revokeUriPermission");
8222        synchronized(this) {
8223            final ProcessRecord r = getRecordForAppLocked(caller);
8224            if (r == null) {
8225                throw new SecurityException("Unable to find app for caller "
8226                        + caller
8227                        + " when revoking permission to uri " + uri);
8228            }
8229            if (uri == null) {
8230                Slog.w(TAG, "revokeUriPermission: null uri");
8231                return;
8232            }
8233
8234            if (!Intent.isAccessUriMode(modeFlags)) {
8235                return;
8236            }
8237
8238            final String authority = uri.getAuthority();
8239            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8240            if (pi == null) {
8241                Slog.w(TAG, "No content provider found for permission revoke: "
8242                        + uri.toSafeString());
8243                return;
8244            }
8245
8246            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8247        }
8248    }
8249
8250    /**
8251     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8252     * given package.
8253     *
8254     * @param packageName Package name to match, or {@code null} to apply to all
8255     *            packages.
8256     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8257     *            to all users.
8258     * @param persistable If persistable grants should be removed.
8259     */
8260    private void removeUriPermissionsForPackageLocked(
8261            String packageName, int userHandle, boolean persistable) {
8262        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8263            throw new IllegalArgumentException("Must narrow by either package or user");
8264        }
8265
8266        boolean persistChanged = false;
8267
8268        int N = mGrantedUriPermissions.size();
8269        for (int i = 0; i < N; i++) {
8270            final int targetUid = mGrantedUriPermissions.keyAt(i);
8271            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8272
8273            // Only inspect grants matching user
8274            if (userHandle == UserHandle.USER_ALL
8275                    || userHandle == UserHandle.getUserId(targetUid)) {
8276                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8277                    final UriPermission perm = it.next();
8278
8279                    // Only inspect grants matching package
8280                    if (packageName == null || perm.sourcePkg.equals(packageName)
8281                            || perm.targetPkg.equals(packageName)) {
8282                        persistChanged |= perm.revokeModes(persistable
8283                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8284
8285                        // Only remove when no modes remain; any persisted grants
8286                        // will keep this alive.
8287                        if (perm.modeFlags == 0) {
8288                            it.remove();
8289                        }
8290                    }
8291                }
8292
8293                if (perms.isEmpty()) {
8294                    mGrantedUriPermissions.remove(targetUid);
8295                    N--;
8296                    i--;
8297                }
8298            }
8299        }
8300
8301        if (persistChanged) {
8302            schedulePersistUriGrants();
8303        }
8304    }
8305
8306    @Override
8307    public IBinder newUriPermissionOwner(String name) {
8308        enforceNotIsolatedCaller("newUriPermissionOwner");
8309        synchronized(this) {
8310            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8311            return owner.getExternalTokenLocked();
8312        }
8313    }
8314
8315    @Override
8316    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8317        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8318        synchronized(this) {
8319            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8320            if (r == null) {
8321                throw new IllegalArgumentException("Activity does not exist; token="
8322                        + activityToken);
8323            }
8324            return r.getUriPermissionsLocked().getExternalTokenLocked();
8325        }
8326    }
8327    /**
8328     * @param uri This uri must NOT contain an embedded userId.
8329     * @param sourceUserId The userId in which the uri is to be resolved.
8330     * @param targetUserId The userId of the app that receives the grant.
8331     */
8332    @Override
8333    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8334            final int modeFlags, int sourceUserId, int targetUserId) {
8335        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8336                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8337                "grantUriPermissionFromOwner", null);
8338        synchronized(this) {
8339            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8340            if (owner == null) {
8341                throw new IllegalArgumentException("Unknown owner: " + token);
8342            }
8343            if (fromUid != Binder.getCallingUid()) {
8344                if (Binder.getCallingUid() != Process.myUid()) {
8345                    // Only system code can grant URI permissions on behalf
8346                    // of other users.
8347                    throw new SecurityException("nice try");
8348                }
8349            }
8350            if (targetPkg == null) {
8351                throw new IllegalArgumentException("null target");
8352            }
8353            if (uri == null) {
8354                throw new IllegalArgumentException("null uri");
8355            }
8356
8357            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8358                    modeFlags, owner, targetUserId);
8359        }
8360    }
8361
8362    /**
8363     * @param uri This uri must NOT contain an embedded userId.
8364     * @param userId The userId in which the uri is to be resolved.
8365     */
8366    @Override
8367    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8368        synchronized(this) {
8369            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8370            if (owner == null) {
8371                throw new IllegalArgumentException("Unknown owner: " + token);
8372            }
8373
8374            if (uri == null) {
8375                owner.removeUriPermissionsLocked(mode);
8376            } else {
8377                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8378            }
8379        }
8380    }
8381
8382    private void schedulePersistUriGrants() {
8383        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8384            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8385                    10 * DateUtils.SECOND_IN_MILLIS);
8386        }
8387    }
8388
8389    private void writeGrantedUriPermissions() {
8390        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8391
8392        // Snapshot permissions so we can persist without lock
8393        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8394        synchronized (this) {
8395            final int size = mGrantedUriPermissions.size();
8396            for (int i = 0; i < size; i++) {
8397                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8398                for (UriPermission perm : perms.values()) {
8399                    if (perm.persistedModeFlags != 0) {
8400                        persist.add(perm.snapshot());
8401                    }
8402                }
8403            }
8404        }
8405
8406        FileOutputStream fos = null;
8407        try {
8408            fos = mGrantFile.startWrite();
8409
8410            XmlSerializer out = new FastXmlSerializer();
8411            out.setOutput(fos, StandardCharsets.UTF_8.name());
8412            out.startDocument(null, true);
8413            out.startTag(null, TAG_URI_GRANTS);
8414            for (UriPermission.Snapshot perm : persist) {
8415                out.startTag(null, TAG_URI_GRANT);
8416                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8417                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8418                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8419                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8420                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8421                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8422                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8423                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8424                out.endTag(null, TAG_URI_GRANT);
8425            }
8426            out.endTag(null, TAG_URI_GRANTS);
8427            out.endDocument();
8428
8429            mGrantFile.finishWrite(fos);
8430        } catch (IOException e) {
8431            if (fos != null) {
8432                mGrantFile.failWrite(fos);
8433            }
8434        }
8435    }
8436
8437    private void readGrantedUriPermissionsLocked() {
8438        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8439
8440        final long now = System.currentTimeMillis();
8441
8442        FileInputStream fis = null;
8443        try {
8444            fis = mGrantFile.openRead();
8445            final XmlPullParser in = Xml.newPullParser();
8446            in.setInput(fis, StandardCharsets.UTF_8.name());
8447
8448            int type;
8449            while ((type = in.next()) != END_DOCUMENT) {
8450                final String tag = in.getName();
8451                if (type == START_TAG) {
8452                    if (TAG_URI_GRANT.equals(tag)) {
8453                        final int sourceUserId;
8454                        final int targetUserId;
8455                        final int userHandle = readIntAttribute(in,
8456                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8457                        if (userHandle != UserHandle.USER_NULL) {
8458                            // For backwards compatibility.
8459                            sourceUserId = userHandle;
8460                            targetUserId = userHandle;
8461                        } else {
8462                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8463                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8464                        }
8465                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8466                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8467                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8468                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8469                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8470                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8471
8472                        // Sanity check that provider still belongs to source package
8473                        final ProviderInfo pi = getProviderInfoLocked(
8474                                uri.getAuthority(), sourceUserId);
8475                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8476                            int targetUid = -1;
8477                            try {
8478                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8479                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8480                            } catch (RemoteException e) {
8481                            }
8482                            if (targetUid != -1) {
8483                                final UriPermission perm = findOrCreateUriPermissionLocked(
8484                                        sourcePkg, targetPkg, targetUid,
8485                                        new GrantUri(sourceUserId, uri, prefix));
8486                                perm.initPersistedModes(modeFlags, createdTime);
8487                            }
8488                        } else {
8489                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8490                                    + " but instead found " + pi);
8491                        }
8492                    }
8493                }
8494            }
8495        } catch (FileNotFoundException e) {
8496            // Missing grants is okay
8497        } catch (IOException e) {
8498            Slog.wtf(TAG, "Failed reading Uri grants", e);
8499        } catch (XmlPullParserException e) {
8500            Slog.wtf(TAG, "Failed reading Uri grants", e);
8501        } finally {
8502            IoUtils.closeQuietly(fis);
8503        }
8504    }
8505
8506    /**
8507     * @param uri This uri must NOT contain an embedded userId.
8508     * @param userId The userId in which the uri is to be resolved.
8509     */
8510    @Override
8511    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8512        enforceNotIsolatedCaller("takePersistableUriPermission");
8513
8514        Preconditions.checkFlagsArgument(modeFlags,
8515                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8516
8517        synchronized (this) {
8518            final int callingUid = Binder.getCallingUid();
8519            boolean persistChanged = false;
8520            GrantUri grantUri = new GrantUri(userId, uri, false);
8521
8522            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8523                    new GrantUri(userId, uri, false));
8524            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8525                    new GrantUri(userId, uri, true));
8526
8527            final boolean exactValid = (exactPerm != null)
8528                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8529            final boolean prefixValid = (prefixPerm != null)
8530                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8531
8532            if (!(exactValid || prefixValid)) {
8533                throw new SecurityException("No persistable permission grants found for UID "
8534                        + callingUid + " and Uri " + grantUri.toSafeString());
8535            }
8536
8537            if (exactValid) {
8538                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8539            }
8540            if (prefixValid) {
8541                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8542            }
8543
8544            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8545
8546            if (persistChanged) {
8547                schedulePersistUriGrants();
8548            }
8549        }
8550    }
8551
8552    /**
8553     * @param uri This uri must NOT contain an embedded userId.
8554     * @param userId The userId in which the uri is to be resolved.
8555     */
8556    @Override
8557    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8558        enforceNotIsolatedCaller("releasePersistableUriPermission");
8559
8560        Preconditions.checkFlagsArgument(modeFlags,
8561                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8562
8563        synchronized (this) {
8564            final int callingUid = Binder.getCallingUid();
8565            boolean persistChanged = false;
8566
8567            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8568                    new GrantUri(userId, uri, false));
8569            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8570                    new GrantUri(userId, uri, true));
8571            if (exactPerm == null && prefixPerm == null) {
8572                throw new SecurityException("No permission grants found for UID " + callingUid
8573                        + " and Uri " + uri.toSafeString());
8574            }
8575
8576            if (exactPerm != null) {
8577                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8578                removeUriPermissionIfNeededLocked(exactPerm);
8579            }
8580            if (prefixPerm != null) {
8581                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8582                removeUriPermissionIfNeededLocked(prefixPerm);
8583            }
8584
8585            if (persistChanged) {
8586                schedulePersistUriGrants();
8587            }
8588        }
8589    }
8590
8591    /**
8592     * Prune any older {@link UriPermission} for the given UID until outstanding
8593     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8594     *
8595     * @return if any mutations occured that require persisting.
8596     */
8597    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8598        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8599        if (perms == null) return false;
8600        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8601
8602        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8603        for (UriPermission perm : perms.values()) {
8604            if (perm.persistedModeFlags != 0) {
8605                persisted.add(perm);
8606            }
8607        }
8608
8609        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8610        if (trimCount <= 0) return false;
8611
8612        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8613        for (int i = 0; i < trimCount; i++) {
8614            final UriPermission perm = persisted.get(i);
8615
8616            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8617                    "Trimming grant created at " + perm.persistedCreateTime);
8618
8619            perm.releasePersistableModes(~0);
8620            removeUriPermissionIfNeededLocked(perm);
8621        }
8622
8623        return true;
8624    }
8625
8626    @Override
8627    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8628            String packageName, boolean incoming) {
8629        enforceNotIsolatedCaller("getPersistedUriPermissions");
8630        Preconditions.checkNotNull(packageName, "packageName");
8631
8632        final int callingUid = Binder.getCallingUid();
8633        final IPackageManager pm = AppGlobals.getPackageManager();
8634        try {
8635            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8636                    UserHandle.getUserId(callingUid));
8637            if (packageUid != callingUid) {
8638                throw new SecurityException(
8639                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8640            }
8641        } catch (RemoteException e) {
8642            throw new SecurityException("Failed to verify package name ownership");
8643        }
8644
8645        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8646        synchronized (this) {
8647            if (incoming) {
8648                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8649                        callingUid);
8650                if (perms == null) {
8651                    Slog.w(TAG, "No permission grants found for " + packageName);
8652                } else {
8653                    for (UriPermission perm : perms.values()) {
8654                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8655                            result.add(perm.buildPersistedPublicApiObject());
8656                        }
8657                    }
8658                }
8659            } else {
8660                final int size = mGrantedUriPermissions.size();
8661                for (int i = 0; i < size; i++) {
8662                    final ArrayMap<GrantUri, UriPermission> perms =
8663                            mGrantedUriPermissions.valueAt(i);
8664                    for (UriPermission perm : perms.values()) {
8665                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8666                            result.add(perm.buildPersistedPublicApiObject());
8667                        }
8668                    }
8669                }
8670            }
8671        }
8672        return new ParceledListSlice<android.content.UriPermission>(result);
8673    }
8674
8675    @Override
8676    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8677            String packageName, int userId) {
8678        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8679                "getGrantedUriPermissions");
8680
8681        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8682        synchronized (this) {
8683            final int size = mGrantedUriPermissions.size();
8684            for (int i = 0; i < size; i++) {
8685                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8686                for (UriPermission perm : perms.values()) {
8687                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8688                            && perm.persistedModeFlags != 0) {
8689                        result.add(perm.buildPersistedPublicApiObject());
8690                    }
8691                }
8692            }
8693        }
8694        return new ParceledListSlice<android.content.UriPermission>(result);
8695    }
8696
8697    @Override
8698    public void clearGrantedUriPermissions(String packageName, int userId) {
8699        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8700                "clearGrantedUriPermissions");
8701        removeUriPermissionsForPackageLocked(packageName, userId, true);
8702    }
8703
8704    @Override
8705    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8706        synchronized (this) {
8707            ProcessRecord app =
8708                who != null ? getRecordForAppLocked(who) : null;
8709            if (app == null) return;
8710
8711            Message msg = Message.obtain();
8712            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8713            msg.obj = app;
8714            msg.arg1 = waiting ? 1 : 0;
8715            mUiHandler.sendMessage(msg);
8716        }
8717    }
8718
8719    @Override
8720    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8721        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8722        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8723        outInfo.availMem = Process.getFreeMemory();
8724        outInfo.totalMem = Process.getTotalMemory();
8725        outInfo.threshold = homeAppMem;
8726        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8727        outInfo.hiddenAppThreshold = cachedAppMem;
8728        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8729                ProcessList.SERVICE_ADJ);
8730        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8731                ProcessList.VISIBLE_APP_ADJ);
8732        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8733                ProcessList.FOREGROUND_APP_ADJ);
8734    }
8735
8736    // =========================================================
8737    // TASK MANAGEMENT
8738    // =========================================================
8739
8740    @Override
8741    public List<IAppTask> getAppTasks(String callingPackage) {
8742        int callingUid = Binder.getCallingUid();
8743        long ident = Binder.clearCallingIdentity();
8744
8745        synchronized(this) {
8746            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8747            try {
8748                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8749
8750                final int N = mRecentTasks.size();
8751                for (int i = 0; i < N; i++) {
8752                    TaskRecord tr = mRecentTasks.get(i);
8753                    // Skip tasks that do not match the caller.  We don't need to verify
8754                    // callingPackage, because we are also limiting to callingUid and know
8755                    // that will limit to the correct security sandbox.
8756                    if (tr.effectiveUid != callingUid) {
8757                        continue;
8758                    }
8759                    Intent intent = tr.getBaseIntent();
8760                    if (intent == null ||
8761                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8762                        continue;
8763                    }
8764                    ActivityManager.RecentTaskInfo taskInfo =
8765                            createRecentTaskInfoFromTaskRecord(tr);
8766                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8767                    list.add(taskImpl);
8768                }
8769            } finally {
8770                Binder.restoreCallingIdentity(ident);
8771            }
8772            return list;
8773        }
8774    }
8775
8776    @Override
8777    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8778        final int callingUid = Binder.getCallingUid();
8779        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8780
8781        synchronized(this) {
8782            if (DEBUG_ALL) Slog.v(
8783                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8784
8785            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8786                    callingUid);
8787
8788            // TODO: Improve with MRU list from all ActivityStacks.
8789            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8790        }
8791
8792        return list;
8793    }
8794
8795    /**
8796     * Creates a new RecentTaskInfo from a TaskRecord.
8797     */
8798    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8799        // Update the task description to reflect any changes in the task stack
8800        tr.updateTaskDescription();
8801
8802        // Compose the recent task info
8803        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8804        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8805        rti.persistentId = tr.taskId;
8806        rti.baseIntent = new Intent(tr.getBaseIntent());
8807        rti.origActivity = tr.origActivity;
8808        rti.realActivity = tr.realActivity;
8809        rti.description = tr.lastDescription;
8810        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8811        rti.userId = tr.userId;
8812        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8813        rti.firstActiveTime = tr.firstActiveTime;
8814        rti.lastActiveTime = tr.lastActiveTime;
8815        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8816        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8817        rti.numActivities = 0;
8818        if (tr.mBounds != null) {
8819            rti.bounds = new Rect(tr.mBounds);
8820        }
8821        rti.isDockable = tr.canGoInDockedStack();
8822        rti.resizeMode = tr.mResizeMode;
8823
8824        ActivityRecord base = null;
8825        ActivityRecord top = null;
8826        ActivityRecord tmp;
8827
8828        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8829            tmp = tr.mActivities.get(i);
8830            if (tmp.finishing) {
8831                continue;
8832            }
8833            base = tmp;
8834            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8835                top = base;
8836            }
8837            rti.numActivities++;
8838        }
8839
8840        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8841        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8842
8843        return rti;
8844    }
8845
8846    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8847        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8848                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8849        if (!allowed) {
8850            if (checkPermission(android.Manifest.permission.GET_TASKS,
8851                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8852                // Temporary compatibility: some existing apps on the system image may
8853                // still be requesting the old permission and not switched to the new
8854                // one; if so, we'll still allow them full access.  This means we need
8855                // to see if they are holding the old permission and are a system app.
8856                try {
8857                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8858                        allowed = true;
8859                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8860                                + " is using old GET_TASKS but privileged; allowing");
8861                    }
8862                } catch (RemoteException e) {
8863                }
8864            }
8865        }
8866        if (!allowed) {
8867            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8868                    + " does not hold REAL_GET_TASKS; limiting output");
8869        }
8870        return allowed;
8871    }
8872
8873    @Override
8874    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8875        final int callingUid = Binder.getCallingUid();
8876        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8877                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8878
8879        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8880        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8881        synchronized (this) {
8882            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8883                    callingUid);
8884            final boolean detailed = checkCallingPermission(
8885                    android.Manifest.permission.GET_DETAILED_TASKS)
8886                    == PackageManager.PERMISSION_GRANTED;
8887
8888            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8889                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8890                return Collections.emptyList();
8891            }
8892            mRecentTasks.loadUserRecentsLocked(userId);
8893
8894            final int recentsCount = mRecentTasks.size();
8895            ArrayList<ActivityManager.RecentTaskInfo> res =
8896                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8897
8898            final Set<Integer> includedUsers;
8899            if (includeProfiles) {
8900                includedUsers = mUserController.getProfileIds(userId);
8901            } else {
8902                includedUsers = new HashSet<>();
8903            }
8904            includedUsers.add(Integer.valueOf(userId));
8905
8906            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8907                TaskRecord tr = mRecentTasks.get(i);
8908                // Only add calling user or related users recent tasks
8909                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8910                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8911                    continue;
8912                }
8913
8914                if (tr.realActivitySuspended) {
8915                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8916                    continue;
8917                }
8918
8919                // Return the entry if desired by the caller.  We always return
8920                // the first entry, because callers always expect this to be the
8921                // foreground app.  We may filter others if the caller has
8922                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8923                // we should exclude the entry.
8924
8925                if (i == 0
8926                        || withExcluded
8927                        || (tr.intent == null)
8928                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8929                                == 0)) {
8930                    if (!allowed) {
8931                        // If the caller doesn't have the GET_TASKS permission, then only
8932                        // allow them to see a small subset of tasks -- their own and home.
8933                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8934                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8935                            continue;
8936                        }
8937                    }
8938                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8939                        if (tr.stack != null && tr.stack.isHomeStack()) {
8940                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8941                                    "Skipping, home stack task: " + tr);
8942                            continue;
8943                        }
8944                    }
8945                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8946                        final ActivityStack stack = tr.stack;
8947                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8948                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8949                                    "Skipping, top task in docked stack: " + tr);
8950                            continue;
8951                        }
8952                    }
8953                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8954                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8955                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8956                                    "Skipping, pinned stack task: " + tr);
8957                            continue;
8958                        }
8959                    }
8960                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8961                        // Don't include auto remove tasks that are finished or finishing.
8962                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8963                                "Skipping, auto-remove without activity: " + tr);
8964                        continue;
8965                    }
8966                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8967                            && !tr.isAvailable) {
8968                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8969                                "Skipping, unavail real act: " + tr);
8970                        continue;
8971                    }
8972
8973                    if (!tr.mUserSetupComplete) {
8974                        // Don't include task launched while user is not done setting-up.
8975                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8976                                "Skipping, user setup not complete: " + tr);
8977                        continue;
8978                    }
8979
8980                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8981                    if (!detailed) {
8982                        rti.baseIntent.replaceExtras((Bundle)null);
8983                    }
8984
8985                    res.add(rti);
8986                    maxNum--;
8987                }
8988            }
8989            return res;
8990        }
8991    }
8992
8993    @Override
8994    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8995        synchronized (this) {
8996            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8997                    "getTaskThumbnail()");
8998            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8999                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9000            if (tr != null) {
9001                return tr.getTaskThumbnailLocked();
9002            }
9003        }
9004        return null;
9005    }
9006
9007    @Override
9008    public int addAppTask(IBinder activityToken, Intent intent,
9009            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9010        final int callingUid = Binder.getCallingUid();
9011        final long callingIdent = Binder.clearCallingIdentity();
9012
9013        try {
9014            synchronized (this) {
9015                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9016                if (r == null) {
9017                    throw new IllegalArgumentException("Activity does not exist; token="
9018                            + activityToken);
9019                }
9020                ComponentName comp = intent.getComponent();
9021                if (comp == null) {
9022                    throw new IllegalArgumentException("Intent " + intent
9023                            + " must specify explicit component");
9024                }
9025                if (thumbnail.getWidth() != mThumbnailWidth
9026                        || thumbnail.getHeight() != mThumbnailHeight) {
9027                    throw new IllegalArgumentException("Bad thumbnail size: got "
9028                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9029                            + mThumbnailWidth + "x" + mThumbnailHeight);
9030                }
9031                if (intent.getSelector() != null) {
9032                    intent.setSelector(null);
9033                }
9034                if (intent.getSourceBounds() != null) {
9035                    intent.setSourceBounds(null);
9036                }
9037                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9038                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9039                        // The caller has added this as an auto-remove task...  that makes no
9040                        // sense, so turn off auto-remove.
9041                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9042                    }
9043                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9044                    // Must be a new task.
9045                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9046                }
9047                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9048                    mLastAddedTaskActivity = null;
9049                }
9050                ActivityInfo ainfo = mLastAddedTaskActivity;
9051                if (ainfo == null) {
9052                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9053                            comp, 0, UserHandle.getUserId(callingUid));
9054                    if (ainfo.applicationInfo.uid != callingUid) {
9055                        throw new SecurityException(
9056                                "Can't add task for another application: target uid="
9057                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9058                    }
9059                }
9060
9061                // Use the full screen as the context for the task thumbnail
9062                final Point displaySize = new Point();
9063                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9064                r.task.stack.getDisplaySize(displaySize);
9065                thumbnailInfo.taskWidth = displaySize.x;
9066                thumbnailInfo.taskHeight = displaySize.y;
9067                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9068
9069                TaskRecord task = new TaskRecord(this,
9070                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9071                        ainfo, intent, description, thumbnailInfo);
9072
9073                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9074                if (trimIdx >= 0) {
9075                    // If this would have caused a trim, then we'll abort because that
9076                    // means it would be added at the end of the list but then just removed.
9077                    return INVALID_TASK_ID;
9078                }
9079
9080                final int N = mRecentTasks.size();
9081                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9082                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9083                    tr.removedFromRecents();
9084                }
9085
9086                task.inRecents = true;
9087                mRecentTasks.add(task);
9088                r.task.stack.addTask(task, false, "addAppTask");
9089
9090                task.setLastThumbnailLocked(thumbnail);
9091                task.freeLastThumbnail();
9092
9093                return task.taskId;
9094            }
9095        } finally {
9096            Binder.restoreCallingIdentity(callingIdent);
9097        }
9098    }
9099
9100    @Override
9101    public Point getAppTaskThumbnailSize() {
9102        synchronized (this) {
9103            return new Point(mThumbnailWidth,  mThumbnailHeight);
9104        }
9105    }
9106
9107    @Override
9108    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9109        synchronized (this) {
9110            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9111            if (r != null) {
9112                r.setTaskDescription(td);
9113                r.task.updateTaskDescription();
9114            }
9115        }
9116    }
9117
9118    @Override
9119    public void setTaskResizeable(int taskId, int resizeableMode) {
9120        synchronized (this) {
9121            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9122                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9123            if (task == null) {
9124                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9125                return;
9126            }
9127            if (task.mResizeMode != resizeableMode) {
9128                task.mResizeMode = resizeableMode;
9129                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9130                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9131                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9132            }
9133        }
9134    }
9135
9136    @Override
9137    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9138        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9139        long ident = Binder.clearCallingIdentity();
9140        try {
9141            synchronized (this) {
9142                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9143                if (task == null) {
9144                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9145                    return;
9146                }
9147                int stackId = task.stack.mStackId;
9148                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9149                // in crop windows resize mode or if the task size is affected by the docked stack
9150                // changing size. No need to update configuration.
9151                if (bounds != null && task.inCropWindowsResizeMode()
9152                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9153                    mWindowManager.scrollTask(task.taskId, bounds);
9154                    return;
9155                }
9156
9157                // Place the task in the right stack if it isn't there already based on
9158                // the requested bounds.
9159                // The stack transition logic is:
9160                // - a null bounds on a freeform task moves that task to fullscreen
9161                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9162                //   that task to freeform
9163                // - otherwise the task is not moved
9164                if (!StackId.isTaskResizeAllowed(stackId)) {
9165                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9166                }
9167                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9168                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9169                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9170                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9171                }
9172                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9173                if (stackId != task.stack.mStackId) {
9174                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9175                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9176                    preserveWindow = false;
9177                }
9178
9179                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9180                        false /* deferResume */);
9181            }
9182        } finally {
9183            Binder.restoreCallingIdentity(ident);
9184        }
9185    }
9186
9187    @Override
9188    public Rect getTaskBounds(int taskId) {
9189        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9190        long ident = Binder.clearCallingIdentity();
9191        Rect rect = new Rect();
9192        try {
9193            synchronized (this) {
9194                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9195                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9196                if (task == null) {
9197                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9198                    return rect;
9199                }
9200                if (task.stack != null) {
9201                    // Return the bounds from window manager since it will be adjusted for various
9202                    // things like the presense of a docked stack for tasks that aren't resizeable.
9203                    mWindowManager.getTaskBounds(task.taskId, rect);
9204                } else {
9205                    // Task isn't in window manager yet since it isn't associated with a stack.
9206                    // Return the persist value from activity manager
9207                    if (task.mBounds != null) {
9208                        rect.set(task.mBounds);
9209                    } else if (task.mLastNonFullscreenBounds != null) {
9210                        rect.set(task.mLastNonFullscreenBounds);
9211                    }
9212                }
9213            }
9214        } finally {
9215            Binder.restoreCallingIdentity(ident);
9216        }
9217        return rect;
9218    }
9219
9220    @Override
9221    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9222        if (userId != UserHandle.getCallingUserId()) {
9223            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9224                    "getTaskDescriptionIcon");
9225        }
9226        final File passedIconFile = new File(filePath);
9227        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9228                passedIconFile.getName());
9229        if (!legitIconFile.getPath().equals(filePath)
9230                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9231            throw new IllegalArgumentException("Bad file path: " + filePath
9232                    + " passed for userId " + userId);
9233        }
9234        return mRecentTasks.getTaskDescriptionIcon(filePath);
9235    }
9236
9237    @Override
9238    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9239            throws RemoteException {
9240        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9241                opts.getCustomInPlaceResId() == 0) {
9242            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9243                    "with valid animation");
9244        }
9245        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9246        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9247                opts.getCustomInPlaceResId());
9248        mWindowManager.executeAppTransition();
9249    }
9250
9251    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9252            boolean removeFromRecents) {
9253        if (removeFromRecents) {
9254            mRecentTasks.remove(tr);
9255            tr.removedFromRecents();
9256        }
9257        ComponentName component = tr.getBaseIntent().getComponent();
9258        if (component == null) {
9259            Slog.w(TAG, "No component for base intent of task: " + tr);
9260            return;
9261        }
9262
9263        // Find any running services associated with this app and stop if needed.
9264        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9265
9266        if (!killProcess) {
9267            return;
9268        }
9269
9270        // Determine if the process(es) for this task should be killed.
9271        final String pkg = component.getPackageName();
9272        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9273        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9274        for (int i = 0; i < pmap.size(); i++) {
9275
9276            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9277            for (int j = 0; j < uids.size(); j++) {
9278                ProcessRecord proc = uids.valueAt(j);
9279                if (proc.userId != tr.userId) {
9280                    // Don't kill process for a different user.
9281                    continue;
9282                }
9283                if (proc == mHomeProcess) {
9284                    // Don't kill the home process along with tasks from the same package.
9285                    continue;
9286                }
9287                if (!proc.pkgList.containsKey(pkg)) {
9288                    // Don't kill process that is not associated with this task.
9289                    continue;
9290                }
9291
9292                for (int k = 0; k < proc.activities.size(); k++) {
9293                    TaskRecord otherTask = proc.activities.get(k).task;
9294                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9295                        // Don't kill process(es) that has an activity in a different task that is
9296                        // also in recents.
9297                        return;
9298                    }
9299                }
9300
9301                if (proc.foregroundServices) {
9302                    // Don't kill process(es) with foreground service.
9303                    return;
9304                }
9305
9306                // Add process to kill list.
9307                procsToKill.add(proc);
9308            }
9309        }
9310
9311        // Kill the running processes.
9312        for (int i = 0; i < procsToKill.size(); i++) {
9313            ProcessRecord pr = procsToKill.get(i);
9314            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9315                    && pr.curReceiver == null) {
9316                pr.kill("remove task", true);
9317            } else {
9318                // We delay killing processes that are not in the background or running a receiver.
9319                pr.waitingToKill = "remove task";
9320            }
9321        }
9322    }
9323
9324    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9325        // Remove all tasks with activities in the specified package from the list of recent tasks
9326        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9327            TaskRecord tr = mRecentTasks.get(i);
9328            if (tr.userId != userId) continue;
9329
9330            ComponentName cn = tr.intent.getComponent();
9331            if (cn != null && cn.getPackageName().equals(packageName)) {
9332                // If the package name matches, remove the task.
9333                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9334            }
9335        }
9336    }
9337
9338    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9339            int userId) {
9340
9341        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9342            TaskRecord tr = mRecentTasks.get(i);
9343            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9344                continue;
9345            }
9346
9347            ComponentName cn = tr.intent.getComponent();
9348            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9349                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9350            if (sameComponent) {
9351                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9352            }
9353        }
9354    }
9355
9356    /**
9357     * Removes the task with the specified task id.
9358     *
9359     * @param taskId Identifier of the task to be removed.
9360     * @param killProcess Kill any process associated with the task if possible.
9361     * @param removeFromRecents Whether to also remove the task from recents.
9362     * @return Returns true if the given task was found and removed.
9363     */
9364    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9365            boolean removeFromRecents) {
9366        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9367                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9368        if (tr != null) {
9369            tr.removeTaskActivitiesLocked();
9370            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9371            if (tr.isPersistable) {
9372                notifyTaskPersisterLocked(null, true);
9373            }
9374            return true;
9375        }
9376        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9377        return false;
9378    }
9379
9380    @Override
9381    public void removeStack(int stackId) {
9382        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9383        if (stackId == HOME_STACK_ID) {
9384            throw new IllegalArgumentException("Removing home stack is not allowed.");
9385        }
9386
9387        synchronized (this) {
9388            final long ident = Binder.clearCallingIdentity();
9389            try {
9390                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9391                if (stack == null) {
9392                    return;
9393                }
9394                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9395                for (int i = tasks.size() - 1; i >= 0; i--) {
9396                    removeTaskByIdLocked(
9397                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9398                }
9399            } finally {
9400                Binder.restoreCallingIdentity(ident);
9401            }
9402        }
9403    }
9404
9405    @Override
9406    public boolean removeTask(int taskId) {
9407        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9408        synchronized (this) {
9409            final long ident = Binder.clearCallingIdentity();
9410            try {
9411                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9412            } finally {
9413                Binder.restoreCallingIdentity(ident);
9414            }
9415        }
9416    }
9417
9418    /**
9419     * TODO: Add mController hook
9420     */
9421    @Override
9422    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9423        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9424
9425        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9426        synchronized(this) {
9427            moveTaskToFrontLocked(taskId, flags, bOptions);
9428        }
9429    }
9430
9431    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9432        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9433
9434        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9435                Binder.getCallingUid(), -1, -1, "Task to front")) {
9436            ActivityOptions.abort(options);
9437            return;
9438        }
9439        final long origId = Binder.clearCallingIdentity();
9440        try {
9441            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9442            if (task == null) {
9443                Slog.d(TAG, "Could not find task for id: "+ taskId);
9444                return;
9445            }
9446            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9447                mStackSupervisor.showLockTaskToast();
9448                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9449                return;
9450            }
9451            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9452            if (prev != null && prev.isRecentsActivity()) {
9453                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9454            }
9455            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9456                    false /* forceNonResizable */);
9457        } finally {
9458            Binder.restoreCallingIdentity(origId);
9459        }
9460        ActivityOptions.abort(options);
9461    }
9462
9463    /**
9464     * Moves an activity, and all of the other activities within the same task, to the bottom
9465     * of the history stack.  The activity's order within the task is unchanged.
9466     *
9467     * @param token A reference to the activity we wish to move
9468     * @param nonRoot If false then this only works if the activity is the root
9469     *                of a task; if true it will work for any activity in a task.
9470     * @return Returns true if the move completed, false if not.
9471     */
9472    @Override
9473    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9474        enforceNotIsolatedCaller("moveActivityTaskToBack");
9475        synchronized(this) {
9476            final long origId = Binder.clearCallingIdentity();
9477            try {
9478                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9479                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9480                if (task != null) {
9481                    if (mStackSupervisor.isLockedTask(task)) {
9482                        mStackSupervisor.showLockTaskToast();
9483                        return false;
9484                    }
9485                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9486                }
9487            } finally {
9488                Binder.restoreCallingIdentity(origId);
9489            }
9490        }
9491        return false;
9492    }
9493
9494    @Override
9495    public void moveTaskBackwards(int task) {
9496        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9497                "moveTaskBackwards()");
9498
9499        synchronized(this) {
9500            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9501                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9502                return;
9503            }
9504            final long origId = Binder.clearCallingIdentity();
9505            moveTaskBackwardsLocked(task);
9506            Binder.restoreCallingIdentity(origId);
9507        }
9508    }
9509
9510    private final void moveTaskBackwardsLocked(int task) {
9511        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9512    }
9513
9514    @Override
9515    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9516            IActivityContainerCallback callback) throws RemoteException {
9517        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9518        synchronized (this) {
9519            if (parentActivityToken == null) {
9520                throw new IllegalArgumentException("parent token must not be null");
9521            }
9522            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9523            if (r == null) {
9524                return null;
9525            }
9526            if (callback == null) {
9527                throw new IllegalArgumentException("callback must not be null");
9528            }
9529            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9530        }
9531    }
9532
9533    @Override
9534    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9535        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9536        synchronized (this) {
9537            mStackSupervisor.deleteActivityContainer(container);
9538        }
9539    }
9540
9541    @Override
9542    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9543        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9544        synchronized (this) {
9545            final int stackId = mStackSupervisor.getNextStackId();
9546            final ActivityStack stack =
9547                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9548            if (stack == null) {
9549                return null;
9550            }
9551            return stack.mActivityContainer;
9552        }
9553    }
9554
9555    @Override
9556    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9557        synchronized (this) {
9558            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9559            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9560                return stack.mActivityContainer.getDisplayId();
9561            }
9562            return Display.DEFAULT_DISPLAY;
9563        }
9564    }
9565
9566    @Override
9567    public int getActivityStackId(IBinder token) throws RemoteException {
9568        synchronized (this) {
9569            ActivityStack stack = ActivityRecord.getStackLocked(token);
9570            if (stack == null) {
9571                return INVALID_STACK_ID;
9572            }
9573            return stack.mStackId;
9574        }
9575    }
9576
9577    @Override
9578    public void exitFreeformMode(IBinder token) throws RemoteException {
9579        synchronized (this) {
9580            long ident = Binder.clearCallingIdentity();
9581            try {
9582                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9583                if (r == null) {
9584                    throw new IllegalArgumentException(
9585                            "exitFreeformMode: No activity record matching token=" + token);
9586                }
9587                final ActivityStack stack = r.getStackLocked(token);
9588                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9589                    throw new IllegalStateException(
9590                            "exitFreeformMode: You can only go fullscreen from freeform.");
9591                }
9592                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9593                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9594                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9595            } finally {
9596                Binder.restoreCallingIdentity(ident);
9597            }
9598        }
9599    }
9600
9601    @Override
9602    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9603        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9604        if (stackId == HOME_STACK_ID) {
9605            throw new IllegalArgumentException(
9606                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9607        }
9608        synchronized (this) {
9609            long ident = Binder.clearCallingIdentity();
9610            try {
9611                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9612                        + " to stackId=" + stackId + " toTop=" + toTop);
9613                if (stackId == DOCKED_STACK_ID) {
9614                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9615                            null /* initialBounds */);
9616                }
9617                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9618                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9619                if (result && stackId == DOCKED_STACK_ID) {
9620                    // If task moved to docked stack - show recents if needed.
9621                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9622                            "moveTaskToDockedStack");
9623                }
9624            } finally {
9625                Binder.restoreCallingIdentity(ident);
9626            }
9627        }
9628    }
9629
9630    @Override
9631    public void swapDockedAndFullscreenStack() throws RemoteException {
9632        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9633        synchronized (this) {
9634            long ident = Binder.clearCallingIdentity();
9635            try {
9636                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9637                        FULLSCREEN_WORKSPACE_STACK_ID);
9638                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9639                        : null;
9640                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9641                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9642                        : null;
9643                if (topTask == null || tasks == null || tasks.size() == 0) {
9644                    Slog.w(TAG,
9645                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9646                    return;
9647                }
9648
9649                // TODO: App transition
9650                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9651
9652                // Defer the resume so resume/pausing while moving stacks is dangerous.
9653                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9654                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9655                        ANIMATE, true /* deferResume */);
9656                final int size = tasks.size();
9657                for (int i = 0; i < size; i++) {
9658                    final int id = tasks.get(i).taskId;
9659                    if (id == topTask.taskId) {
9660                        continue;
9661                    }
9662                    mStackSupervisor.moveTaskToStackLocked(id,
9663                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9664                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9665                }
9666
9667                // Because we deferred the resume, to avoid conflicts with stack switches while
9668                // resuming, we need to do it after all the tasks are moved.
9669                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9670                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9671
9672                mWindowManager.executeAppTransition();
9673            } finally {
9674                Binder.restoreCallingIdentity(ident);
9675            }
9676        }
9677    }
9678
9679    /**
9680     * Moves the input task to the docked stack.
9681     *
9682     * @param taskId Id of task to move.
9683     * @param createMode The mode the docked stack should be created in if it doesn't exist
9684     *                   already. See
9685     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9686     *                   and
9687     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9688     * @param toTop If the task and stack should be moved to the top.
9689     * @param animate Whether we should play an animation for the moving the task
9690     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9691     *                      docked stack. Pass {@code null} to use default bounds.
9692     */
9693    @Override
9694    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9695            Rect initialBounds) {
9696        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9697        synchronized (this) {
9698            long ident = Binder.clearCallingIdentity();
9699            try {
9700                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9701                        + " to createMode=" + createMode + " toTop=" + toTop);
9702                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9703                return mStackSupervisor.moveTaskToStackLocked(
9704                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9705                        "moveTaskToDockedStack", animate);
9706            } finally {
9707                Binder.restoreCallingIdentity(ident);
9708            }
9709        }
9710    }
9711
9712    /**
9713     * Moves the top activity in the input stackId to the pinned stack.
9714     *
9715     * @param stackId Id of stack to move the top activity to pinned stack.
9716     * @param bounds Bounds to use for pinned stack.
9717     *
9718     * @return True if the top activity of the input stack was successfully moved to the pinned
9719     *          stack.
9720     */
9721    @Override
9722    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9723        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9724        synchronized (this) {
9725            if (!mSupportsPictureInPicture) {
9726                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9727                        + "Device doesn't support picture-in-pciture mode");
9728            }
9729
9730            long ident = Binder.clearCallingIdentity();
9731            try {
9732                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9733            } finally {
9734                Binder.restoreCallingIdentity(ident);
9735            }
9736        }
9737    }
9738
9739    @Override
9740    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9741            boolean preserveWindows, boolean animate, int animationDuration) {
9742        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9743        long ident = Binder.clearCallingIdentity();
9744        try {
9745            synchronized (this) {
9746                if (animate) {
9747                    if (stackId == PINNED_STACK_ID) {
9748                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9749                    } else {
9750                        throw new IllegalArgumentException("Stack: " + stackId
9751                                + " doesn't support animated resize.");
9752                    }
9753                } else {
9754                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9755                            null /* tempTaskInsetBounds */, preserveWindows,
9756                            allowResizeInDockedMode, !DEFER_RESUME);
9757                }
9758            }
9759        } finally {
9760            Binder.restoreCallingIdentity(ident);
9761        }
9762    }
9763
9764    @Override
9765    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9766            Rect tempDockedTaskInsetBounds,
9767            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9769                "resizeDockedStack()");
9770        long ident = Binder.clearCallingIdentity();
9771        try {
9772            synchronized (this) {
9773                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9774                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9775                        PRESERVE_WINDOWS);
9776            }
9777        } finally {
9778            Binder.restoreCallingIdentity(ident);
9779        }
9780    }
9781
9782    @Override
9783    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9784        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9785                "resizePinnedStack()");
9786        final long ident = Binder.clearCallingIdentity();
9787        try {
9788            synchronized (this) {
9789                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9790            }
9791        } finally {
9792            Binder.restoreCallingIdentity(ident);
9793        }
9794    }
9795
9796    @Override
9797    public void positionTaskInStack(int taskId, int stackId, int position) {
9798        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9799        if (stackId == HOME_STACK_ID) {
9800            throw new IllegalArgumentException(
9801                    "positionTaskInStack: Attempt to change the position of task "
9802                    + taskId + " in/to home stack");
9803        }
9804        synchronized (this) {
9805            long ident = Binder.clearCallingIdentity();
9806            try {
9807                if (DEBUG_STACK) Slog.d(TAG_STACK,
9808                        "positionTaskInStack: positioning task=" + taskId
9809                        + " in stackId=" + stackId + " at position=" + position);
9810                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9811            } finally {
9812                Binder.restoreCallingIdentity(ident);
9813            }
9814        }
9815    }
9816
9817    @Override
9818    public List<StackInfo> getAllStackInfos() {
9819        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9820        long ident = Binder.clearCallingIdentity();
9821        try {
9822            synchronized (this) {
9823                return mStackSupervisor.getAllStackInfosLocked();
9824            }
9825        } finally {
9826            Binder.restoreCallingIdentity(ident);
9827        }
9828    }
9829
9830    @Override
9831    public StackInfo getStackInfo(int stackId) {
9832        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9833        long ident = Binder.clearCallingIdentity();
9834        try {
9835            synchronized (this) {
9836                return mStackSupervisor.getStackInfoLocked(stackId);
9837            }
9838        } finally {
9839            Binder.restoreCallingIdentity(ident);
9840        }
9841    }
9842
9843    @Override
9844    public boolean isInHomeStack(int taskId) {
9845        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9846        long ident = Binder.clearCallingIdentity();
9847        try {
9848            synchronized (this) {
9849                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9850                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9851                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9852            }
9853        } finally {
9854            Binder.restoreCallingIdentity(ident);
9855        }
9856    }
9857
9858    @Override
9859    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9860        synchronized(this) {
9861            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9862        }
9863    }
9864
9865    @Override
9866    public void updateDeviceOwner(String packageName) {
9867        final int callingUid = Binder.getCallingUid();
9868        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9869            throw new SecurityException("updateDeviceOwner called from non-system process");
9870        }
9871        synchronized (this) {
9872            mDeviceOwnerName = packageName;
9873        }
9874    }
9875
9876    @Override
9877    public void updateLockTaskPackages(int userId, String[] packages) {
9878        final int callingUid = Binder.getCallingUid();
9879        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9880            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9881                    "updateLockTaskPackages()");
9882        }
9883        synchronized (this) {
9884            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9885                    Arrays.toString(packages));
9886            mLockTaskPackages.put(userId, packages);
9887            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9888        }
9889    }
9890
9891
9892    void startLockTaskModeLocked(TaskRecord task) {
9893        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9894        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9895            return;
9896        }
9897
9898        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9899        // is initiated by system after the pinning request was shown and locked mode is initiated
9900        // by an authorized app directly
9901        final int callingUid = Binder.getCallingUid();
9902        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9903        long ident = Binder.clearCallingIdentity();
9904        try {
9905            if (!isSystemInitiated) {
9906                task.mLockTaskUid = callingUid;
9907                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9908                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9909                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9910                    StatusBarManagerInternal statusBarManager =
9911                            LocalServices.getService(StatusBarManagerInternal.class);
9912                    if (statusBarManager != null) {
9913                        statusBarManager.showScreenPinningRequest(task.taskId);
9914                    }
9915                    return;
9916                }
9917
9918                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9919                if (stack == null || task != stack.topTask()) {
9920                    throw new IllegalArgumentException("Invalid task, not in foreground");
9921                }
9922            }
9923            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9924                    "Locking fully");
9925            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9926                    ActivityManager.LOCK_TASK_MODE_PINNED :
9927                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9928                    "startLockTask", true);
9929        } finally {
9930            Binder.restoreCallingIdentity(ident);
9931        }
9932    }
9933
9934    @Override
9935    public void startLockTaskMode(int taskId) {
9936        synchronized (this) {
9937            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9938            if (task != null) {
9939                startLockTaskModeLocked(task);
9940            }
9941        }
9942    }
9943
9944    @Override
9945    public void startLockTaskMode(IBinder token) {
9946        synchronized (this) {
9947            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9948            if (r == null) {
9949                return;
9950            }
9951            final TaskRecord task = r.task;
9952            if (task != null) {
9953                startLockTaskModeLocked(task);
9954            }
9955        }
9956    }
9957
9958    @Override
9959    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9961        // This makes inner call to look as if it was initiated by system.
9962        long ident = Binder.clearCallingIdentity();
9963        try {
9964            synchronized (this) {
9965                startLockTaskMode(taskId);
9966            }
9967        } finally {
9968            Binder.restoreCallingIdentity(ident);
9969        }
9970    }
9971
9972    @Override
9973    public void stopLockTaskMode() {
9974        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9975        if (lockTask == null) {
9976            // Our work here is done.
9977            return;
9978        }
9979
9980        final int callingUid = Binder.getCallingUid();
9981        final int lockTaskUid = lockTask.mLockTaskUid;
9982        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9983        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9984            // Done.
9985            return;
9986        } else {
9987            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9988            // It is possible lockTaskMode was started by the system process because
9989            // android:lockTaskMode is set to a locking value in the application manifest
9990            // instead of the app calling startLockTaskMode. In this case
9991            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9992            // {@link TaskRecord.effectiveUid} instead. Also caller with
9993            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9994            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9995                    && callingUid != lockTaskUid
9996                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9997                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9998                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9999            }
10000        }
10001        long ident = Binder.clearCallingIdentity();
10002        try {
10003            Log.d(TAG, "stopLockTaskMode");
10004            // Stop lock task
10005            synchronized (this) {
10006                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10007                        "stopLockTask", true);
10008            }
10009        } finally {
10010            Binder.restoreCallingIdentity(ident);
10011        }
10012    }
10013
10014    /**
10015     * This API should be called by SystemUI only when user perform certain action to dismiss
10016     * lock task mode. We should only dismiss pinned lock task mode in this case.
10017     */
10018    @Override
10019    public void stopSystemLockTaskMode() throws RemoteException {
10020        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10021            stopLockTaskMode();
10022        } else {
10023            mStackSupervisor.showLockTaskToast();
10024        }
10025    }
10026
10027    @Override
10028    public boolean isInLockTaskMode() {
10029        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10030    }
10031
10032    @Override
10033    public int getLockTaskModeState() {
10034        synchronized (this) {
10035            return mStackSupervisor.getLockTaskModeState();
10036        }
10037    }
10038
10039    @Override
10040    public void showLockTaskEscapeMessage(IBinder token) {
10041        synchronized (this) {
10042            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10043            if (r == null) {
10044                return;
10045            }
10046            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10047        }
10048    }
10049
10050    // =========================================================
10051    // CONTENT PROVIDERS
10052    // =========================================================
10053
10054    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10055        List<ProviderInfo> providers = null;
10056        try {
10057            providers = AppGlobals.getPackageManager()
10058                    .queryContentProviders(app.processName, app.uid,
10059                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10060                                    | MATCH_DEBUG_TRIAGED_MISSING)
10061                    .getList();
10062        } catch (RemoteException ex) {
10063        }
10064        if (DEBUG_MU) Slog.v(TAG_MU,
10065                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10066        int userId = app.userId;
10067        if (providers != null) {
10068            int N = providers.size();
10069            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10070            for (int i=0; i<N; i++) {
10071                ProviderInfo cpi =
10072                    (ProviderInfo)providers.get(i);
10073                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10074                        cpi.name, cpi.flags);
10075                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10076                    // This is a singleton provider, but a user besides the
10077                    // default user is asking to initialize a process it runs
10078                    // in...  well, no, it doesn't actually run in this process,
10079                    // it runs in the process of the default user.  Get rid of it.
10080                    providers.remove(i);
10081                    N--;
10082                    i--;
10083                    continue;
10084                }
10085
10086                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10087                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10088                if (cpr == null) {
10089                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10090                    mProviderMap.putProviderByClass(comp, cpr);
10091                }
10092                if (DEBUG_MU) Slog.v(TAG_MU,
10093                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10094                app.pubProviders.put(cpi.name, cpr);
10095                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10096                    // Don't add this if it is a platform component that is marked
10097                    // to run in multiple processes, because this is actually
10098                    // part of the framework so doesn't make sense to track as a
10099                    // separate apk in the process.
10100                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10101                            mProcessStats);
10102                }
10103                notifyPackageUse(cpi.applicationInfo.packageName,
10104                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10105            }
10106        }
10107        return providers;
10108    }
10109
10110    /**
10111     * Check if {@link ProcessRecord} has a possible chance at accessing the
10112     * given {@link ProviderInfo}. Final permission checking is always done
10113     * in {@link ContentProvider}.
10114     */
10115    private final String checkContentProviderPermissionLocked(
10116            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10117        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10118        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10119        boolean checkedGrants = false;
10120        if (checkUser) {
10121            // Looking for cross-user grants before enforcing the typical cross-users permissions
10122            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10123            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10124                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10125                    return null;
10126                }
10127                checkedGrants = true;
10128            }
10129            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10130                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10131            if (userId != tmpTargetUserId) {
10132                // When we actually went to determine the final targer user ID, this ended
10133                // up different than our initial check for the authority.  This is because
10134                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10135                // SELF.  So we need to re-check the grants again.
10136                checkedGrants = false;
10137            }
10138        }
10139        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10140                cpi.applicationInfo.uid, cpi.exported)
10141                == PackageManager.PERMISSION_GRANTED) {
10142            return null;
10143        }
10144        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10145                cpi.applicationInfo.uid, cpi.exported)
10146                == PackageManager.PERMISSION_GRANTED) {
10147            return null;
10148        }
10149
10150        PathPermission[] pps = cpi.pathPermissions;
10151        if (pps != null) {
10152            int i = pps.length;
10153            while (i > 0) {
10154                i--;
10155                PathPermission pp = pps[i];
10156                String pprperm = pp.getReadPermission();
10157                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10158                        cpi.applicationInfo.uid, cpi.exported)
10159                        == PackageManager.PERMISSION_GRANTED) {
10160                    return null;
10161                }
10162                String ppwperm = pp.getWritePermission();
10163                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10164                        cpi.applicationInfo.uid, cpi.exported)
10165                        == PackageManager.PERMISSION_GRANTED) {
10166                    return null;
10167                }
10168            }
10169        }
10170        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10171            return null;
10172        }
10173
10174        String msg;
10175        if (!cpi.exported) {
10176            msg = "Permission Denial: opening provider " + cpi.name
10177                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10178                    + ", uid=" + callingUid + ") that is not exported from uid "
10179                    + cpi.applicationInfo.uid;
10180        } else {
10181            msg = "Permission Denial: opening provider " + cpi.name
10182                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10183                    + ", uid=" + callingUid + ") requires "
10184                    + cpi.readPermission + " or " + cpi.writePermission;
10185        }
10186        Slog.w(TAG, msg);
10187        return msg;
10188    }
10189
10190    /**
10191     * Returns if the ContentProvider has granted a uri to callingUid
10192     */
10193    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10194        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10195        if (perms != null) {
10196            for (int i=perms.size()-1; i>=0; i--) {
10197                GrantUri grantUri = perms.keyAt(i);
10198                if (grantUri.sourceUserId == userId || !checkUser) {
10199                    if (matchesProvider(grantUri.uri, cpi)) {
10200                        return true;
10201                    }
10202                }
10203            }
10204        }
10205        return false;
10206    }
10207
10208    /**
10209     * Returns true if the uri authority is one of the authorities specified in the provider.
10210     */
10211    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10212        String uriAuth = uri.getAuthority();
10213        String cpiAuth = cpi.authority;
10214        if (cpiAuth.indexOf(';') == -1) {
10215            return cpiAuth.equals(uriAuth);
10216        }
10217        String[] cpiAuths = cpiAuth.split(";");
10218        int length = cpiAuths.length;
10219        for (int i = 0; i < length; i++) {
10220            if (cpiAuths[i].equals(uriAuth)) return true;
10221        }
10222        return false;
10223    }
10224
10225    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10226            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10227        if (r != null) {
10228            for (int i=0; i<r.conProviders.size(); i++) {
10229                ContentProviderConnection conn = r.conProviders.get(i);
10230                if (conn.provider == cpr) {
10231                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10232                            "Adding provider requested by "
10233                            + r.processName + " from process "
10234                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10235                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10236                    if (stable) {
10237                        conn.stableCount++;
10238                        conn.numStableIncs++;
10239                    } else {
10240                        conn.unstableCount++;
10241                        conn.numUnstableIncs++;
10242                    }
10243                    return conn;
10244                }
10245            }
10246            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10247            if (stable) {
10248                conn.stableCount = 1;
10249                conn.numStableIncs = 1;
10250            } else {
10251                conn.unstableCount = 1;
10252                conn.numUnstableIncs = 1;
10253            }
10254            cpr.connections.add(conn);
10255            r.conProviders.add(conn);
10256            startAssociationLocked(r.uid, r.processName, r.curProcState,
10257                    cpr.uid, cpr.name, cpr.info.processName);
10258            return conn;
10259        }
10260        cpr.addExternalProcessHandleLocked(externalProcessToken);
10261        return null;
10262    }
10263
10264    boolean decProviderCountLocked(ContentProviderConnection conn,
10265            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10266        if (conn != null) {
10267            cpr = conn.provider;
10268            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10269                    "Removing provider requested by "
10270                    + conn.client.processName + " from process "
10271                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10272                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10273            if (stable) {
10274                conn.stableCount--;
10275            } else {
10276                conn.unstableCount--;
10277            }
10278            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10279                cpr.connections.remove(conn);
10280                conn.client.conProviders.remove(conn);
10281                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10282                    // The client is more important than last activity -- note the time this
10283                    // is happening, so we keep the old provider process around a bit as last
10284                    // activity to avoid thrashing it.
10285                    if (cpr.proc != null) {
10286                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10287                    }
10288                }
10289                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10290                return true;
10291            }
10292            return false;
10293        }
10294        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10295        return false;
10296    }
10297
10298    private void checkTime(long startTime, String where) {
10299        long now = SystemClock.elapsedRealtime();
10300        if ((now-startTime) > 1000) {
10301            // If we are taking more than a second, log about it.
10302            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10303        }
10304    }
10305
10306    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10307            String name, IBinder token, boolean stable, int userId) {
10308        ContentProviderRecord cpr;
10309        ContentProviderConnection conn = null;
10310        ProviderInfo cpi = null;
10311
10312        synchronized(this) {
10313            long startTime = SystemClock.elapsedRealtime();
10314
10315            ProcessRecord r = null;
10316            if (caller != null) {
10317                r = getRecordForAppLocked(caller);
10318                if (r == null) {
10319                    throw new SecurityException(
10320                            "Unable to find app for caller " + caller
10321                          + " (pid=" + Binder.getCallingPid()
10322                          + ") when getting content provider " + name);
10323                }
10324            }
10325
10326            boolean checkCrossUser = true;
10327
10328            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10329
10330            // First check if this content provider has been published...
10331            cpr = mProviderMap.getProviderByName(name, userId);
10332            // If that didn't work, check if it exists for user 0 and then
10333            // verify that it's a singleton provider before using it.
10334            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10335                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10336                if (cpr != null) {
10337                    cpi = cpr.info;
10338                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10339                            cpi.name, cpi.flags)
10340                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10341                        userId = UserHandle.USER_SYSTEM;
10342                        checkCrossUser = false;
10343                    } else {
10344                        cpr = null;
10345                        cpi = null;
10346                    }
10347                }
10348            }
10349
10350            boolean providerRunning = cpr != null;
10351            if (providerRunning) {
10352                cpi = cpr.info;
10353                String msg;
10354                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10355                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10356                        != null) {
10357                    throw new SecurityException(msg);
10358                }
10359                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10360
10361                if (r != null && cpr.canRunHere(r)) {
10362                    // This provider has been published or is in the process
10363                    // of being published...  but it is also allowed to run
10364                    // in the caller's process, so don't make a connection
10365                    // and just let the caller instantiate its own instance.
10366                    ContentProviderHolder holder = cpr.newHolder(null);
10367                    // don't give caller the provider object, it needs
10368                    // to make its own.
10369                    holder.provider = null;
10370                    return holder;
10371                }
10372
10373                final long origId = Binder.clearCallingIdentity();
10374
10375                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10376
10377                // In this case the provider instance already exists, so we can
10378                // return it right away.
10379                conn = incProviderCountLocked(r, cpr, token, stable);
10380                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10381                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10382                        // If this is a perceptible app accessing the provider,
10383                        // make sure to count it as being accessed and thus
10384                        // back up on the LRU list.  This is good because
10385                        // content providers are often expensive to start.
10386                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10387                        updateLruProcessLocked(cpr.proc, false, null);
10388                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10389                    }
10390                }
10391
10392                if (cpr.proc != null) {
10393                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10394                    boolean success = updateOomAdjLocked(cpr.proc);
10395                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10396                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10397                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10398                    // NOTE: there is still a race here where a signal could be
10399                    // pending on the process even though we managed to update its
10400                    // adj level.  Not sure what to do about this, but at least
10401                    // the race is now smaller.
10402                    if (!success) {
10403                        // Uh oh...  it looks like the provider's process
10404                        // has been killed on us.  We need to wait for a new
10405                        // process to be started, and make sure its death
10406                        // doesn't kill our process.
10407                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10408                                + " is crashing; detaching " + r);
10409                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10410                        checkTime(startTime, "getContentProviderImpl: before appDied");
10411                        appDiedLocked(cpr.proc);
10412                        checkTime(startTime, "getContentProviderImpl: after appDied");
10413                        if (!lastRef) {
10414                            // This wasn't the last ref our process had on
10415                            // the provider...  we have now been killed, bail.
10416                            return null;
10417                        }
10418                        providerRunning = false;
10419                        conn = null;
10420                    }
10421                }
10422
10423                Binder.restoreCallingIdentity(origId);
10424            }
10425
10426            if (!providerRunning) {
10427                try {
10428                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10429                    cpi = AppGlobals.getPackageManager().
10430                        resolveContentProvider(name,
10431                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10432                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10433                } catch (RemoteException ex) {
10434                }
10435                if (cpi == null) {
10436                    return null;
10437                }
10438                // If the provider is a singleton AND
10439                // (it's a call within the same user || the provider is a
10440                // privileged app)
10441                // Then allow connecting to the singleton provider
10442                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10443                        cpi.name, cpi.flags)
10444                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10445                if (singleton) {
10446                    userId = UserHandle.USER_SYSTEM;
10447                }
10448                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10449                checkTime(startTime, "getContentProviderImpl: got app info for user");
10450
10451                String msg;
10452                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10453                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10454                        != null) {
10455                    throw new SecurityException(msg);
10456                }
10457                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10458
10459                if (!mProcessesReady
10460                        && !cpi.processName.equals("system")) {
10461                    // If this content provider does not run in the system
10462                    // process, and the system is not yet ready to run other
10463                    // processes, then fail fast instead of hanging.
10464                    throw new IllegalArgumentException(
10465                            "Attempt to launch content provider before system ready");
10466                }
10467
10468                // Make sure that the user who owns this provider is running.  If not,
10469                // we don't want to allow it to run.
10470                if (!mUserController.isUserRunningLocked(userId, 0)) {
10471                    Slog.w(TAG, "Unable to launch app "
10472                            + cpi.applicationInfo.packageName + "/"
10473                            + cpi.applicationInfo.uid + " for provider "
10474                            + name + ": user " + userId + " is stopped");
10475                    return null;
10476                }
10477
10478                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10479                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10480                cpr = mProviderMap.getProviderByClass(comp, userId);
10481                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10482                final boolean firstClass = cpr == null;
10483                if (firstClass) {
10484                    final long ident = Binder.clearCallingIdentity();
10485
10486                    // If permissions need a review before any of the app components can run,
10487                    // we return no provider and launch a review activity if the calling app
10488                    // is in the foreground.
10489                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10490                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10491                            return null;
10492                        }
10493                    }
10494
10495                    try {
10496                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10497                        ApplicationInfo ai =
10498                            AppGlobals.getPackageManager().
10499                                getApplicationInfo(
10500                                        cpi.applicationInfo.packageName,
10501                                        STOCK_PM_FLAGS, userId);
10502                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10503                        if (ai == null) {
10504                            Slog.w(TAG, "No package info for content provider "
10505                                    + cpi.name);
10506                            return null;
10507                        }
10508                        ai = getAppInfoForUser(ai, userId);
10509                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10510                    } catch (RemoteException ex) {
10511                        // pm is in same process, this will never happen.
10512                    } finally {
10513                        Binder.restoreCallingIdentity(ident);
10514                    }
10515                }
10516
10517                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10518
10519                if (r != null && cpr.canRunHere(r)) {
10520                    // If this is a multiprocess provider, then just return its
10521                    // info and allow the caller to instantiate it.  Only do
10522                    // this if the provider is the same user as the caller's
10523                    // process, or can run as root (so can be in any process).
10524                    return cpr.newHolder(null);
10525                }
10526
10527                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10528                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10529                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10530
10531                // This is single process, and our app is now connecting to it.
10532                // See if we are already in the process of launching this
10533                // provider.
10534                final int N = mLaunchingProviders.size();
10535                int i;
10536                for (i = 0; i < N; i++) {
10537                    if (mLaunchingProviders.get(i) == cpr) {
10538                        break;
10539                    }
10540                }
10541
10542                // If the provider is not already being launched, then get it
10543                // started.
10544                if (i >= N) {
10545                    final long origId = Binder.clearCallingIdentity();
10546
10547                    try {
10548                        // Content provider is now in use, its package can't be stopped.
10549                        try {
10550                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10551                            AppGlobals.getPackageManager().setPackageStoppedState(
10552                                    cpr.appInfo.packageName, false, userId);
10553                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10554                        } catch (RemoteException e) {
10555                        } catch (IllegalArgumentException e) {
10556                            Slog.w(TAG, "Failed trying to unstop package "
10557                                    + cpr.appInfo.packageName + ": " + e);
10558                        }
10559
10560                        // Use existing process if already started
10561                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10562                        ProcessRecord proc = getProcessRecordLocked(
10563                                cpi.processName, cpr.appInfo.uid, false);
10564                        if (proc != null && proc.thread != null) {
10565                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10566                                    "Installing in existing process " + proc);
10567                            if (!proc.pubProviders.containsKey(cpi.name)) {
10568                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10569                                proc.pubProviders.put(cpi.name, cpr);
10570                                try {
10571                                    proc.thread.scheduleInstallProvider(cpi);
10572                                } catch (RemoteException e) {
10573                                }
10574                            }
10575                        } else {
10576                            checkTime(startTime, "getContentProviderImpl: before start process");
10577                            proc = startProcessLocked(cpi.processName,
10578                                    cpr.appInfo, false, 0, "content provider",
10579                                    new ComponentName(cpi.applicationInfo.packageName,
10580                                            cpi.name), false, false, false);
10581                            checkTime(startTime, "getContentProviderImpl: after start process");
10582                            if (proc == null) {
10583                                Slog.w(TAG, "Unable to launch app "
10584                                        + cpi.applicationInfo.packageName + "/"
10585                                        + cpi.applicationInfo.uid + " for provider "
10586                                        + name + ": process is bad");
10587                                return null;
10588                            }
10589                        }
10590                        cpr.launchingApp = proc;
10591                        mLaunchingProviders.add(cpr);
10592                    } finally {
10593                        Binder.restoreCallingIdentity(origId);
10594                    }
10595                }
10596
10597                checkTime(startTime, "getContentProviderImpl: updating data structures");
10598
10599                // Make sure the provider is published (the same provider class
10600                // may be published under multiple names).
10601                if (firstClass) {
10602                    mProviderMap.putProviderByClass(comp, cpr);
10603                }
10604
10605                mProviderMap.putProviderByName(name, cpr);
10606                conn = incProviderCountLocked(r, cpr, token, stable);
10607                if (conn != null) {
10608                    conn.waiting = true;
10609                }
10610            }
10611            checkTime(startTime, "getContentProviderImpl: done!");
10612        }
10613
10614        // Wait for the provider to be published...
10615        synchronized (cpr) {
10616            while (cpr.provider == null) {
10617                if (cpr.launchingApp == null) {
10618                    Slog.w(TAG, "Unable to launch app "
10619                            + cpi.applicationInfo.packageName + "/"
10620                            + cpi.applicationInfo.uid + " for provider "
10621                            + name + ": launching app became null");
10622                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10623                            UserHandle.getUserId(cpi.applicationInfo.uid),
10624                            cpi.applicationInfo.packageName,
10625                            cpi.applicationInfo.uid, name);
10626                    return null;
10627                }
10628                try {
10629                    if (DEBUG_MU) Slog.v(TAG_MU,
10630                            "Waiting to start provider " + cpr
10631                            + " launchingApp=" + cpr.launchingApp);
10632                    if (conn != null) {
10633                        conn.waiting = true;
10634                    }
10635                    cpr.wait();
10636                } catch (InterruptedException ex) {
10637                } finally {
10638                    if (conn != null) {
10639                        conn.waiting = false;
10640                    }
10641                }
10642            }
10643        }
10644        return cpr != null ? cpr.newHolder(conn) : null;
10645    }
10646
10647    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10648            ProcessRecord r, final int userId) {
10649        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10650                cpi.packageName, userId)) {
10651
10652            final boolean callerForeground = r == null || r.setSchedGroup
10653                    != ProcessList.SCHED_GROUP_BACKGROUND;
10654
10655            // Show a permission review UI only for starting from a foreground app
10656            if (!callerForeground) {
10657                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10658                        + cpi.packageName + " requires a permissions review");
10659                return false;
10660            }
10661
10662            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10663            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10664                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10665            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10666
10667            if (DEBUG_PERMISSIONS_REVIEW) {
10668                Slog.i(TAG, "u" + userId + " Launching permission review "
10669                        + "for package " + cpi.packageName);
10670            }
10671
10672            final UserHandle userHandle = new UserHandle(userId);
10673            mHandler.post(new Runnable() {
10674                @Override
10675                public void run() {
10676                    mContext.startActivityAsUser(intent, userHandle);
10677                }
10678            });
10679
10680            return false;
10681        }
10682
10683        return true;
10684    }
10685
10686    PackageManagerInternal getPackageManagerInternalLocked() {
10687        if (mPackageManagerInt == null) {
10688            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10689        }
10690        return mPackageManagerInt;
10691    }
10692
10693    @Override
10694    public final ContentProviderHolder getContentProvider(
10695            IApplicationThread caller, String name, int userId, boolean stable) {
10696        enforceNotIsolatedCaller("getContentProvider");
10697        if (caller == null) {
10698            String msg = "null IApplicationThread when getting content provider "
10699                    + name;
10700            Slog.w(TAG, msg);
10701            throw new SecurityException(msg);
10702        }
10703        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10704        // with cross-user grant.
10705        return getContentProviderImpl(caller, name, null, stable, userId);
10706    }
10707
10708    public ContentProviderHolder getContentProviderExternal(
10709            String name, int userId, IBinder token) {
10710        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10711            "Do not have permission in call getContentProviderExternal()");
10712        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10713                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10714        return getContentProviderExternalUnchecked(name, token, userId);
10715    }
10716
10717    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10718            IBinder token, int userId) {
10719        return getContentProviderImpl(null, name, token, true, userId);
10720    }
10721
10722    /**
10723     * Drop a content provider from a ProcessRecord's bookkeeping
10724     */
10725    public void removeContentProvider(IBinder connection, boolean stable) {
10726        enforceNotIsolatedCaller("removeContentProvider");
10727        long ident = Binder.clearCallingIdentity();
10728        try {
10729            synchronized (this) {
10730                ContentProviderConnection conn;
10731                try {
10732                    conn = (ContentProviderConnection)connection;
10733                } catch (ClassCastException e) {
10734                    String msg ="removeContentProvider: " + connection
10735                            + " not a ContentProviderConnection";
10736                    Slog.w(TAG, msg);
10737                    throw new IllegalArgumentException(msg);
10738                }
10739                if (conn == null) {
10740                    throw new NullPointerException("connection is null");
10741                }
10742                if (decProviderCountLocked(conn, null, null, stable)) {
10743                    updateOomAdjLocked();
10744                }
10745            }
10746        } finally {
10747            Binder.restoreCallingIdentity(ident);
10748        }
10749    }
10750
10751    public void removeContentProviderExternal(String name, IBinder token) {
10752        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10753            "Do not have permission in call removeContentProviderExternal()");
10754        int userId = UserHandle.getCallingUserId();
10755        long ident = Binder.clearCallingIdentity();
10756        try {
10757            removeContentProviderExternalUnchecked(name, token, userId);
10758        } finally {
10759            Binder.restoreCallingIdentity(ident);
10760        }
10761    }
10762
10763    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10764        synchronized (this) {
10765            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10766            if(cpr == null) {
10767                //remove from mProvidersByClass
10768                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10769                return;
10770            }
10771
10772            //update content provider record entry info
10773            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10774            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10775            if (localCpr.hasExternalProcessHandles()) {
10776                if (localCpr.removeExternalProcessHandleLocked(token)) {
10777                    updateOomAdjLocked();
10778                } else {
10779                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10780                            + " with no external reference for token: "
10781                            + token + ".");
10782                }
10783            } else {
10784                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10785                        + " with no external references.");
10786            }
10787        }
10788    }
10789
10790    public final void publishContentProviders(IApplicationThread caller,
10791            List<ContentProviderHolder> providers) {
10792        if (providers == null) {
10793            return;
10794        }
10795
10796        enforceNotIsolatedCaller("publishContentProviders");
10797        synchronized (this) {
10798            final ProcessRecord r = getRecordForAppLocked(caller);
10799            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10800            if (r == null) {
10801                throw new SecurityException(
10802                        "Unable to find app for caller " + caller
10803                      + " (pid=" + Binder.getCallingPid()
10804                      + ") when publishing content providers");
10805            }
10806
10807            final long origId = Binder.clearCallingIdentity();
10808
10809            final int N = providers.size();
10810            for (int i = 0; i < N; i++) {
10811                ContentProviderHolder src = providers.get(i);
10812                if (src == null || src.info == null || src.provider == null) {
10813                    continue;
10814                }
10815                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10816                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10817                if (dst != null) {
10818                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10819                    mProviderMap.putProviderByClass(comp, dst);
10820                    String names[] = dst.info.authority.split(";");
10821                    for (int j = 0; j < names.length; j++) {
10822                        mProviderMap.putProviderByName(names[j], dst);
10823                    }
10824
10825                    int launchingCount = mLaunchingProviders.size();
10826                    int j;
10827                    boolean wasInLaunchingProviders = false;
10828                    for (j = 0; j < launchingCount; j++) {
10829                        if (mLaunchingProviders.get(j) == dst) {
10830                            mLaunchingProviders.remove(j);
10831                            wasInLaunchingProviders = true;
10832                            j--;
10833                            launchingCount--;
10834                        }
10835                    }
10836                    if (wasInLaunchingProviders) {
10837                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10838                    }
10839                    synchronized (dst) {
10840                        dst.provider = src.provider;
10841                        dst.proc = r;
10842                        dst.notifyAll();
10843                    }
10844                    updateOomAdjLocked(r);
10845                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10846                            src.info.authority);
10847                }
10848            }
10849
10850            Binder.restoreCallingIdentity(origId);
10851        }
10852    }
10853
10854    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10855        ContentProviderConnection conn;
10856        try {
10857            conn = (ContentProviderConnection)connection;
10858        } catch (ClassCastException e) {
10859            String msg ="refContentProvider: " + connection
10860                    + " not a ContentProviderConnection";
10861            Slog.w(TAG, msg);
10862            throw new IllegalArgumentException(msg);
10863        }
10864        if (conn == null) {
10865            throw new NullPointerException("connection is null");
10866        }
10867
10868        synchronized (this) {
10869            if (stable > 0) {
10870                conn.numStableIncs += stable;
10871            }
10872            stable = conn.stableCount + stable;
10873            if (stable < 0) {
10874                throw new IllegalStateException("stableCount < 0: " + stable);
10875            }
10876
10877            if (unstable > 0) {
10878                conn.numUnstableIncs += unstable;
10879            }
10880            unstable = conn.unstableCount + unstable;
10881            if (unstable < 0) {
10882                throw new IllegalStateException("unstableCount < 0: " + unstable);
10883            }
10884
10885            if ((stable+unstable) <= 0) {
10886                throw new IllegalStateException("ref counts can't go to zero here: stable="
10887                        + stable + " unstable=" + unstable);
10888            }
10889            conn.stableCount = stable;
10890            conn.unstableCount = unstable;
10891            return !conn.dead;
10892        }
10893    }
10894
10895    public void unstableProviderDied(IBinder connection) {
10896        ContentProviderConnection conn;
10897        try {
10898            conn = (ContentProviderConnection)connection;
10899        } catch (ClassCastException e) {
10900            String msg ="refContentProvider: " + connection
10901                    + " not a ContentProviderConnection";
10902            Slog.w(TAG, msg);
10903            throw new IllegalArgumentException(msg);
10904        }
10905        if (conn == null) {
10906            throw new NullPointerException("connection is null");
10907        }
10908
10909        // Safely retrieve the content provider associated with the connection.
10910        IContentProvider provider;
10911        synchronized (this) {
10912            provider = conn.provider.provider;
10913        }
10914
10915        if (provider == null) {
10916            // Um, yeah, we're way ahead of you.
10917            return;
10918        }
10919
10920        // Make sure the caller is being honest with us.
10921        if (provider.asBinder().pingBinder()) {
10922            // Er, no, still looks good to us.
10923            synchronized (this) {
10924                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10925                        + " says " + conn + " died, but we don't agree");
10926                return;
10927            }
10928        }
10929
10930        // Well look at that!  It's dead!
10931        synchronized (this) {
10932            if (conn.provider.provider != provider) {
10933                // But something changed...  good enough.
10934                return;
10935            }
10936
10937            ProcessRecord proc = conn.provider.proc;
10938            if (proc == null || proc.thread == null) {
10939                // Seems like the process is already cleaned up.
10940                return;
10941            }
10942
10943            // As far as we're concerned, this is just like receiving a
10944            // death notification...  just a bit prematurely.
10945            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10946                    + ") early provider death");
10947            final long ident = Binder.clearCallingIdentity();
10948            try {
10949                appDiedLocked(proc);
10950            } finally {
10951                Binder.restoreCallingIdentity(ident);
10952            }
10953        }
10954    }
10955
10956    @Override
10957    public void appNotRespondingViaProvider(IBinder connection) {
10958        enforceCallingPermission(
10959                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10960
10961        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10962        if (conn == null) {
10963            Slog.w(TAG, "ContentProviderConnection is null");
10964            return;
10965        }
10966
10967        final ProcessRecord host = conn.provider.proc;
10968        if (host == null) {
10969            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10970            return;
10971        }
10972
10973        mHandler.post(new Runnable() {
10974            @Override
10975            public void run() {
10976                mAppErrors.appNotResponding(host, null, null, false,
10977                        "ContentProvider not responding");
10978            }
10979        });
10980    }
10981
10982    public final void installSystemProviders() {
10983        List<ProviderInfo> providers;
10984        synchronized (this) {
10985            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10986            providers = generateApplicationProvidersLocked(app);
10987            if (providers != null) {
10988                for (int i=providers.size()-1; i>=0; i--) {
10989                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10990                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10991                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10992                                + ": not system .apk");
10993                        providers.remove(i);
10994                    }
10995                }
10996            }
10997        }
10998        if (providers != null) {
10999            mSystemThread.installSystemProviders(providers);
11000        }
11001
11002        mCoreSettingsObserver = new CoreSettingsObserver(this);
11003        mFontScaleSettingObserver = new FontScaleSettingObserver();
11004
11005        //mUsageStatsService.monitorPackages();
11006    }
11007
11008    private void startPersistentApps(int matchFlags) {
11009        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11010
11011        synchronized (this) {
11012            try {
11013                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11014                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11015                for (ApplicationInfo app : apps) {
11016                    if (!"android".equals(app.packageName)) {
11017                        addAppLocked(app, false, null /* ABI override */);
11018                    }
11019                }
11020            } catch (RemoteException ex) {
11021            }
11022        }
11023    }
11024
11025    /**
11026     * When a user is unlocked, we need to install encryption-unaware providers
11027     * belonging to any running apps.
11028     */
11029    private void installEncryptionUnawareProviders(int userId) {
11030        // We're only interested in providers that are encryption unaware, and
11031        // we don't care about uninstalled apps, since there's no way they're
11032        // running at this point.
11033        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11034
11035        synchronized (this) {
11036            final int NP = mProcessNames.getMap().size();
11037            for (int ip = 0; ip < NP; ip++) {
11038                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11039                final int NA = apps.size();
11040                for (int ia = 0; ia < NA; ia++) {
11041                    final ProcessRecord app = apps.valueAt(ia);
11042                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11043
11044                    final int NG = app.pkgList.size();
11045                    for (int ig = 0; ig < NG; ig++) {
11046                        try {
11047                            final String pkgName = app.pkgList.keyAt(ig);
11048                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11049                                    .getPackageInfo(pkgName, matchFlags, userId);
11050                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11051                                for (ProviderInfo provInfo : pkgInfo.providers) {
11052                                    Log.v(TAG, "Installing " + provInfo);
11053                                    app.thread.scheduleInstallProvider(provInfo);
11054                                }
11055                            }
11056                        } catch (RemoteException ignored) {
11057                        }
11058                    }
11059                }
11060            }
11061        }
11062    }
11063
11064    /**
11065     * Allows apps to retrieve the MIME type of a URI.
11066     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11067     * users, then it does not need permission to access the ContentProvider.
11068     * Either, it needs cross-user uri grants.
11069     *
11070     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11071     *
11072     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11073     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11074     */
11075    public String getProviderMimeType(Uri uri, int userId) {
11076        enforceNotIsolatedCaller("getProviderMimeType");
11077        final String name = uri.getAuthority();
11078        int callingUid = Binder.getCallingUid();
11079        int callingPid = Binder.getCallingPid();
11080        long ident = 0;
11081        boolean clearedIdentity = false;
11082        synchronized (this) {
11083            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11084        }
11085        if (canClearIdentity(callingPid, callingUid, userId)) {
11086            clearedIdentity = true;
11087            ident = Binder.clearCallingIdentity();
11088        }
11089        ContentProviderHolder holder = null;
11090        try {
11091            holder = getContentProviderExternalUnchecked(name, null, userId);
11092            if (holder != null) {
11093                return holder.provider.getType(uri);
11094            }
11095        } catch (RemoteException e) {
11096            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11097            return null;
11098        } finally {
11099            // We need to clear the identity to call removeContentProviderExternalUnchecked
11100            if (!clearedIdentity) {
11101                ident = Binder.clearCallingIdentity();
11102            }
11103            try {
11104                if (holder != null) {
11105                    removeContentProviderExternalUnchecked(name, null, userId);
11106                }
11107            } finally {
11108                Binder.restoreCallingIdentity(ident);
11109            }
11110        }
11111
11112        return null;
11113    }
11114
11115    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11116        if (UserHandle.getUserId(callingUid) == userId) {
11117            return true;
11118        }
11119        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11120                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11121                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11122                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11123                return true;
11124        }
11125        return false;
11126    }
11127
11128    // =========================================================
11129    // GLOBAL MANAGEMENT
11130    // =========================================================
11131
11132    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11133            boolean isolated, int isolatedUid) {
11134        String proc = customProcess != null ? customProcess : info.processName;
11135        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11136        final int userId = UserHandle.getUserId(info.uid);
11137        int uid = info.uid;
11138        if (isolated) {
11139            if (isolatedUid == 0) {
11140                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11141                while (true) {
11142                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11143                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11144                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11145                    }
11146                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11147                    mNextIsolatedProcessUid++;
11148                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11149                        // No process for this uid, use it.
11150                        break;
11151                    }
11152                    stepsLeft--;
11153                    if (stepsLeft <= 0) {
11154                        return null;
11155                    }
11156                }
11157            } else {
11158                // Special case for startIsolatedProcess (internal only), where
11159                // the uid of the isolated process is specified by the caller.
11160                uid = isolatedUid;
11161            }
11162        }
11163        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11164        if (!mBooted && !mBooting
11165                && userId == UserHandle.USER_SYSTEM
11166                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11167            r.persistent = true;
11168        }
11169        addProcessNameLocked(r);
11170        return r;
11171    }
11172
11173    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11174            String abiOverride) {
11175        ProcessRecord app;
11176        if (!isolated) {
11177            app = getProcessRecordLocked(info.processName, info.uid, true);
11178        } else {
11179            app = null;
11180        }
11181
11182        if (app == null) {
11183            app = newProcessRecordLocked(info, null, isolated, 0);
11184            updateLruProcessLocked(app, false, null);
11185            updateOomAdjLocked();
11186        }
11187
11188        // This package really, really can not be stopped.
11189        try {
11190            AppGlobals.getPackageManager().setPackageStoppedState(
11191                    info.packageName, false, UserHandle.getUserId(app.uid));
11192        } catch (RemoteException e) {
11193        } catch (IllegalArgumentException e) {
11194            Slog.w(TAG, "Failed trying to unstop package "
11195                    + info.packageName + ": " + e);
11196        }
11197
11198        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11199            app.persistent = true;
11200            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11201        }
11202        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11203            mPersistentStartingProcesses.add(app);
11204            startProcessLocked(app, "added application", app.processName, abiOverride,
11205                    null /* entryPoint */, null /* entryPointArgs */);
11206        }
11207
11208        return app;
11209    }
11210
11211    public void unhandledBack() {
11212        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11213                "unhandledBack()");
11214
11215        synchronized(this) {
11216            final long origId = Binder.clearCallingIdentity();
11217            try {
11218                getFocusedStack().unhandledBackLocked();
11219            } finally {
11220                Binder.restoreCallingIdentity(origId);
11221            }
11222        }
11223    }
11224
11225    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11226        enforceNotIsolatedCaller("openContentUri");
11227        final int userId = UserHandle.getCallingUserId();
11228        String name = uri.getAuthority();
11229        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11230        ParcelFileDescriptor pfd = null;
11231        if (cph != null) {
11232            // We record the binder invoker's uid in thread-local storage before
11233            // going to the content provider to open the file.  Later, in the code
11234            // that handles all permissions checks, we look for this uid and use
11235            // that rather than the Activity Manager's own uid.  The effect is that
11236            // we do the check against the caller's permissions even though it looks
11237            // to the content provider like the Activity Manager itself is making
11238            // the request.
11239            Binder token = new Binder();
11240            sCallerIdentity.set(new Identity(
11241                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11242            try {
11243                pfd = cph.provider.openFile(null, uri, "r", null, token);
11244            } catch (FileNotFoundException e) {
11245                // do nothing; pfd will be returned null
11246            } finally {
11247                // Ensure that whatever happens, we clean up the identity state
11248                sCallerIdentity.remove();
11249                // Ensure we're done with the provider.
11250                removeContentProviderExternalUnchecked(name, null, userId);
11251            }
11252        } else {
11253            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11254        }
11255        return pfd;
11256    }
11257
11258    // Actually is sleeping or shutting down or whatever else in the future
11259    // is an inactive state.
11260    public boolean isSleepingOrShuttingDown() {
11261        return isSleeping() || mShuttingDown;
11262    }
11263
11264    public boolean isSleeping() {
11265        return mSleeping;
11266    }
11267
11268    void onWakefulnessChanged(int wakefulness) {
11269        synchronized(this) {
11270            mWakefulness = wakefulness;
11271            updateSleepIfNeededLocked();
11272        }
11273    }
11274
11275    void finishRunningVoiceLocked() {
11276        if (mRunningVoice != null) {
11277            mRunningVoice = null;
11278            mVoiceWakeLock.release();
11279            updateSleepIfNeededLocked();
11280        }
11281    }
11282
11283    void startTimeTrackingFocusedActivityLocked() {
11284        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11285            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11286        }
11287    }
11288
11289    void updateSleepIfNeededLocked() {
11290        if (mSleeping && !shouldSleepLocked()) {
11291            mSleeping = false;
11292            startTimeTrackingFocusedActivityLocked();
11293            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11294            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11295            updateOomAdjLocked();
11296        } else if (!mSleeping && shouldSleepLocked()) {
11297            mSleeping = true;
11298            if (mCurAppTimeTracker != null) {
11299                mCurAppTimeTracker.stop();
11300            }
11301            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11302            mStackSupervisor.goingToSleepLocked();
11303            updateOomAdjLocked();
11304
11305            // Initialize the wake times of all processes.
11306            checkExcessivePowerUsageLocked(false);
11307            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11308            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11309            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11310        }
11311    }
11312
11313    private boolean shouldSleepLocked() {
11314        // Resume applications while running a voice interactor.
11315        if (mRunningVoice != null) {
11316            return false;
11317        }
11318
11319        // TODO: Transform the lock screen state into a sleep token instead.
11320        switch (mWakefulness) {
11321            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11322            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11323            case PowerManagerInternal.WAKEFULNESS_DOZING:
11324                // Pause applications whenever the lock screen is shown or any sleep
11325                // tokens have been acquired.
11326                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11327            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11328            default:
11329                // If we're asleep then pause applications unconditionally.
11330                return true;
11331        }
11332    }
11333
11334    /** Pokes the task persister. */
11335    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11336        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11337    }
11338
11339    /** Notifies all listeners when the task stack has changed. */
11340    void notifyTaskStackChangedLocked() {
11341        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11342        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11343        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11344        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11345    }
11346
11347    /** Notifies all listeners when an Activity is pinned. */
11348    void notifyActivityPinnedLocked() {
11349        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11350        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11351    }
11352
11353    /**
11354     * Notifies all listeners when an attempt was made to start an an activity that is already
11355     * running in the pinned stack and the activity was not actually started, but the task is
11356     * either brought to the front or a new Intent is delivered to it.
11357     */
11358    void notifyPinnedActivityRestartAttemptLocked() {
11359        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11360        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11361    }
11362
11363    /** Notifies all listeners when the pinned stack animation ends. */
11364    @Override
11365    public void notifyPinnedStackAnimationEnded() {
11366        synchronized (this) {
11367            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11368            mHandler.obtainMessage(
11369                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11370        }
11371    }
11372
11373    @Override
11374    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11375        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11376    }
11377
11378    @Override
11379    public boolean shutdown(int timeout) {
11380        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11381                != PackageManager.PERMISSION_GRANTED) {
11382            throw new SecurityException("Requires permission "
11383                    + android.Manifest.permission.SHUTDOWN);
11384        }
11385
11386        boolean timedout = false;
11387
11388        synchronized(this) {
11389            mShuttingDown = true;
11390            updateEventDispatchingLocked();
11391            timedout = mStackSupervisor.shutdownLocked(timeout);
11392        }
11393
11394        mAppOpsService.shutdown();
11395        if (mUsageStatsService != null) {
11396            mUsageStatsService.prepareShutdown();
11397        }
11398        mBatteryStatsService.shutdown();
11399        synchronized (this) {
11400            mProcessStats.shutdownLocked();
11401            notifyTaskPersisterLocked(null, true);
11402        }
11403
11404        return timedout;
11405    }
11406
11407    public final void activitySlept(IBinder token) {
11408        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11409
11410        final long origId = Binder.clearCallingIdentity();
11411
11412        synchronized (this) {
11413            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11414            if (r != null) {
11415                mStackSupervisor.activitySleptLocked(r);
11416            }
11417        }
11418
11419        Binder.restoreCallingIdentity(origId);
11420    }
11421
11422    private String lockScreenShownToString() {
11423        switch (mLockScreenShown) {
11424            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11425            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11426            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11427            default: return "Unknown=" + mLockScreenShown;
11428        }
11429    }
11430
11431    void logLockScreen(String msg) {
11432        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11433                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11434                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11435                + " mSleeping=" + mSleeping);
11436    }
11437
11438    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11439        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11440        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11441        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11442            boolean wasRunningVoice = mRunningVoice != null;
11443            mRunningVoice = session;
11444            if (!wasRunningVoice) {
11445                mVoiceWakeLock.acquire();
11446                updateSleepIfNeededLocked();
11447            }
11448        }
11449    }
11450
11451    private void updateEventDispatchingLocked() {
11452        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11453    }
11454
11455    public void setLockScreenShown(boolean shown) {
11456        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11457                != PackageManager.PERMISSION_GRANTED) {
11458            throw new SecurityException("Requires permission "
11459                    + android.Manifest.permission.DEVICE_POWER);
11460        }
11461
11462        synchronized(this) {
11463            long ident = Binder.clearCallingIdentity();
11464            try {
11465                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11466                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11467                updateSleepIfNeededLocked();
11468            } finally {
11469                Binder.restoreCallingIdentity(ident);
11470            }
11471        }
11472    }
11473
11474    @Override
11475    public void notifyLockedProfile(@UserIdInt int userId) {
11476        try {
11477            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11478                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11479            }
11480        } catch (RemoteException ex) {
11481            throw new SecurityException("Fail to check is caller a privileged app", ex);
11482        }
11483
11484        synchronized (this) {
11485            if (mStackSupervisor.isUserLockedProfile(userId)) {
11486                final long ident = Binder.clearCallingIdentity();
11487                try {
11488                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11489                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11490                        // If there is no device lock, we will show the profile's credential page.
11491                        mActivityStarter.showConfirmDeviceCredential(userId);
11492                    } else {
11493                        // Showing launcher to avoid user entering credential twice.
11494                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11495                    }
11496                } finally {
11497                    Binder.restoreCallingIdentity(ident);
11498                }
11499            }
11500        }
11501    }
11502
11503    @Override
11504    public void startConfirmDeviceCredentialIntent(Intent intent) {
11505        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11506        synchronized (this) {
11507            final long ident = Binder.clearCallingIdentity();
11508            try {
11509                mActivityStarter.startConfirmCredentialIntent(intent);
11510            } finally {
11511                Binder.restoreCallingIdentity(ident);
11512            }
11513        }
11514    }
11515
11516    @Override
11517    public void stopAppSwitches() {
11518        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11519                != PackageManager.PERMISSION_GRANTED) {
11520            throw new SecurityException("viewquires permission "
11521                    + android.Manifest.permission.STOP_APP_SWITCHES);
11522        }
11523
11524        synchronized(this) {
11525            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11526                    + APP_SWITCH_DELAY_TIME;
11527            mDidAppSwitch = false;
11528            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11529            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11530            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11531        }
11532    }
11533
11534    public void resumeAppSwitches() {
11535        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11536                != PackageManager.PERMISSION_GRANTED) {
11537            throw new SecurityException("Requires permission "
11538                    + android.Manifest.permission.STOP_APP_SWITCHES);
11539        }
11540
11541        synchronized(this) {
11542            // Note that we don't execute any pending app switches... we will
11543            // let those wait until either the timeout, or the next start
11544            // activity request.
11545            mAppSwitchesAllowedTime = 0;
11546        }
11547    }
11548
11549    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11550            int callingPid, int callingUid, String name) {
11551        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11552            return true;
11553        }
11554
11555        int perm = checkComponentPermission(
11556                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11557                sourceUid, -1, true);
11558        if (perm == PackageManager.PERMISSION_GRANTED) {
11559            return true;
11560        }
11561
11562        // If the actual IPC caller is different from the logical source, then
11563        // also see if they are allowed to control app switches.
11564        if (callingUid != -1 && callingUid != sourceUid) {
11565            perm = checkComponentPermission(
11566                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11567                    callingUid, -1, true);
11568            if (perm == PackageManager.PERMISSION_GRANTED) {
11569                return true;
11570            }
11571        }
11572
11573        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11574        return false;
11575    }
11576
11577    public void setDebugApp(String packageName, boolean waitForDebugger,
11578            boolean persistent) {
11579        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11580                "setDebugApp()");
11581
11582        long ident = Binder.clearCallingIdentity();
11583        try {
11584            // Note that this is not really thread safe if there are multiple
11585            // callers into it at the same time, but that's not a situation we
11586            // care about.
11587            if (persistent) {
11588                final ContentResolver resolver = mContext.getContentResolver();
11589                Settings.Global.putString(
11590                    resolver, Settings.Global.DEBUG_APP,
11591                    packageName);
11592                Settings.Global.putInt(
11593                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11594                    waitForDebugger ? 1 : 0);
11595            }
11596
11597            synchronized (this) {
11598                if (!persistent) {
11599                    mOrigDebugApp = mDebugApp;
11600                    mOrigWaitForDebugger = mWaitForDebugger;
11601                }
11602                mDebugApp = packageName;
11603                mWaitForDebugger = waitForDebugger;
11604                mDebugTransient = !persistent;
11605                if (packageName != null) {
11606                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11607                            false, UserHandle.USER_ALL, "set debug app");
11608                }
11609            }
11610        } finally {
11611            Binder.restoreCallingIdentity(ident);
11612        }
11613    }
11614
11615    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11616        synchronized (this) {
11617            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11618            if (!isDebuggable) {
11619                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11620                    throw new SecurityException("Process not debuggable: " + app.packageName);
11621                }
11622            }
11623
11624            mTrackAllocationApp = processName;
11625        }
11626    }
11627
11628    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11629        synchronized (this) {
11630            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11631            if (!isDebuggable) {
11632                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11633                    throw new SecurityException("Process not debuggable: " + app.packageName);
11634                }
11635            }
11636            mProfileApp = processName;
11637            mProfileFile = profilerInfo.profileFile;
11638            if (mProfileFd != null) {
11639                try {
11640                    mProfileFd.close();
11641                } catch (IOException e) {
11642                }
11643                mProfileFd = null;
11644            }
11645            mProfileFd = profilerInfo.profileFd;
11646            mSamplingInterval = profilerInfo.samplingInterval;
11647            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11648            mProfileType = 0;
11649        }
11650    }
11651
11652    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11653        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11654        if (!isDebuggable) {
11655            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11656                throw new SecurityException("Process not debuggable: " + app.packageName);
11657            }
11658        }
11659        mNativeDebuggingApp = processName;
11660    }
11661
11662    @Override
11663    public void setAlwaysFinish(boolean enabled) {
11664        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11665                "setAlwaysFinish()");
11666
11667        long ident = Binder.clearCallingIdentity();
11668        try {
11669            Settings.Global.putInt(
11670                    mContext.getContentResolver(),
11671                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11672
11673            synchronized (this) {
11674                mAlwaysFinishActivities = enabled;
11675            }
11676        } finally {
11677            Binder.restoreCallingIdentity(ident);
11678        }
11679    }
11680
11681    @Override
11682    public void setLenientBackgroundCheck(boolean enabled) {
11683        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11684                "setLenientBackgroundCheck()");
11685
11686        long ident = Binder.clearCallingIdentity();
11687        try {
11688            Settings.Global.putInt(
11689                    mContext.getContentResolver(),
11690                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11691
11692            synchronized (this) {
11693                mLenientBackgroundCheck = enabled;
11694            }
11695        } finally {
11696            Binder.restoreCallingIdentity(ident);
11697        }
11698    }
11699
11700    @Override
11701    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11702        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11703                "setActivityController()");
11704        synchronized (this) {
11705            mController = controller;
11706            mControllerIsAMonkey = imAMonkey;
11707            Watchdog.getInstance().setActivityController(controller);
11708        }
11709    }
11710
11711    @Override
11712    public void setUserIsMonkey(boolean userIsMonkey) {
11713        synchronized (this) {
11714            synchronized (mPidsSelfLocked) {
11715                final int callingPid = Binder.getCallingPid();
11716                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11717                if (precessRecord == null) {
11718                    throw new SecurityException("Unknown process: " + callingPid);
11719                }
11720                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11721                    throw new SecurityException("Only an instrumentation process "
11722                            + "with a UiAutomation can call setUserIsMonkey");
11723                }
11724            }
11725            mUserIsMonkey = userIsMonkey;
11726        }
11727    }
11728
11729    @Override
11730    public boolean isUserAMonkey() {
11731        synchronized (this) {
11732            // If there is a controller also implies the user is a monkey.
11733            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11734        }
11735    }
11736
11737    public void requestBugReport(int bugreportType) {
11738        String service = null;
11739        switch (bugreportType) {
11740            case ActivityManager.BUGREPORT_OPTION_FULL:
11741                service = "bugreport";
11742                break;
11743            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11744                service = "bugreportplus";
11745                break;
11746            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11747                service = "bugreportremote";
11748                break;
11749        }
11750        if (service == null) {
11751            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11752                    + bugreportType);
11753        }
11754        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11755        SystemProperties.set("ctl.start", service);
11756    }
11757
11758    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11759        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11760    }
11761
11762    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11763        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11764            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11765        }
11766        return KEY_DISPATCHING_TIMEOUT;
11767    }
11768
11769    @Override
11770    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11771        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11772                != PackageManager.PERMISSION_GRANTED) {
11773            throw new SecurityException("Requires permission "
11774                    + android.Manifest.permission.FILTER_EVENTS);
11775        }
11776        ProcessRecord proc;
11777        long timeout;
11778        synchronized (this) {
11779            synchronized (mPidsSelfLocked) {
11780                proc = mPidsSelfLocked.get(pid);
11781            }
11782            timeout = getInputDispatchingTimeoutLocked(proc);
11783        }
11784
11785        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11786            return -1;
11787        }
11788
11789        return timeout;
11790    }
11791
11792    /**
11793     * Handle input dispatching timeouts.
11794     * Returns whether input dispatching should be aborted or not.
11795     */
11796    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11797            final ActivityRecord activity, final ActivityRecord parent,
11798            final boolean aboveSystem, String reason) {
11799        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11800                != PackageManager.PERMISSION_GRANTED) {
11801            throw new SecurityException("Requires permission "
11802                    + android.Manifest.permission.FILTER_EVENTS);
11803        }
11804
11805        final String annotation;
11806        if (reason == null) {
11807            annotation = "Input dispatching timed out";
11808        } else {
11809            annotation = "Input dispatching timed out (" + reason + ")";
11810        }
11811
11812        if (proc != null) {
11813            synchronized (this) {
11814                if (proc.debugging) {
11815                    return false;
11816                }
11817
11818                if (mDidDexOpt) {
11819                    // Give more time since we were dexopting.
11820                    mDidDexOpt = false;
11821                    return false;
11822                }
11823
11824                if (proc.instrumentationClass != null) {
11825                    Bundle info = new Bundle();
11826                    info.putString("shortMsg", "keyDispatchingTimedOut");
11827                    info.putString("longMsg", annotation);
11828                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11829                    return true;
11830                }
11831            }
11832            mHandler.post(new Runnable() {
11833                @Override
11834                public void run() {
11835                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11836                }
11837            });
11838        }
11839
11840        return true;
11841    }
11842
11843    @Override
11844    public Bundle getAssistContextExtras(int requestType) {
11845        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11846                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11847        if (pae == null) {
11848            return null;
11849        }
11850        synchronized (pae) {
11851            while (!pae.haveResult) {
11852                try {
11853                    pae.wait();
11854                } catch (InterruptedException e) {
11855                }
11856            }
11857        }
11858        synchronized (this) {
11859            buildAssistBundleLocked(pae, pae.result);
11860            mPendingAssistExtras.remove(pae);
11861            mUiHandler.removeCallbacks(pae);
11862        }
11863        return pae.extras;
11864    }
11865
11866    @Override
11867    public boolean isAssistDataAllowedOnCurrentActivity() {
11868        int userId;
11869        synchronized (this) {
11870            userId = mUserController.getCurrentUserIdLocked();
11871            ActivityRecord activity = getFocusedStack().topActivity();
11872            if (activity == null) {
11873                return false;
11874            }
11875            userId = activity.userId;
11876        }
11877        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11878                Context.DEVICE_POLICY_SERVICE);
11879        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11880    }
11881
11882    @Override
11883    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11884        long ident = Binder.clearCallingIdentity();
11885        try {
11886            synchronized (this) {
11887                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11888                ActivityRecord top = getFocusedStack().topActivity();
11889                if (top != caller) {
11890                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11891                            + " is not current top " + top);
11892                    return false;
11893                }
11894                if (!top.nowVisible) {
11895                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11896                            + " is not visible");
11897                    return false;
11898                }
11899            }
11900            AssistUtils utils = new AssistUtils(mContext);
11901            return utils.showSessionForActiveService(args,
11902                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11903        } finally {
11904            Binder.restoreCallingIdentity(ident);
11905        }
11906    }
11907
11908    @Override
11909    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11910            Bundle receiverExtras,
11911            IBinder activityToken, boolean focused) {
11912        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11913                activityToken, focused,
11914                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11915                != null;
11916    }
11917
11918    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11919            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11920            int userHandle, Bundle args, long timeout) {
11921        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11922                "enqueueAssistContext()");
11923        synchronized (this) {
11924            ActivityRecord activity = getFocusedStack().topActivity();
11925            if (activity == null) {
11926                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11927                return null;
11928            }
11929            if (activity.app == null || activity.app.thread == null) {
11930                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11931                return null;
11932            }
11933            if (focused) {
11934                if (activityToken != null) {
11935                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11936                    if (activity != caller) {
11937                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11938                                + " is not current top " + activity);
11939                        return null;
11940                    }
11941                }
11942            } else {
11943                activity = ActivityRecord.forTokenLocked(activityToken);
11944                if (activity == null) {
11945                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11946                            + " couldn't be found");
11947                    return null;
11948                }
11949            }
11950
11951            PendingAssistExtras pae;
11952            Bundle extras = new Bundle();
11953            if (args != null) {
11954                extras.putAll(args);
11955            }
11956            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11957            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11958            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11959                    userHandle);
11960            try {
11961                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11962                        requestType);
11963                mPendingAssistExtras.add(pae);
11964                mUiHandler.postDelayed(pae, timeout);
11965            } catch (RemoteException e) {
11966                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11967                return null;
11968            }
11969            return pae;
11970        }
11971    }
11972
11973    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11974        IResultReceiver receiver;
11975        synchronized (this) {
11976            mPendingAssistExtras.remove(pae);
11977            receiver = pae.receiver;
11978        }
11979        if (receiver != null) {
11980            // Caller wants result sent back to them.
11981            Bundle sendBundle = new Bundle();
11982            // At least return the receiver extras
11983            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
11984                    pae.receiverExtras);
11985            try {
11986                pae.receiver.send(0, sendBundle);
11987            } catch (RemoteException e) {
11988            }
11989        }
11990    }
11991
11992    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11993        if (result != null) {
11994            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11995        }
11996        if (pae.hint != null) {
11997            pae.extras.putBoolean(pae.hint, true);
11998        }
11999    }
12000
12001    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12002            AssistContent content, Uri referrer) {
12003        PendingAssistExtras pae = (PendingAssistExtras)token;
12004        synchronized (pae) {
12005            pae.result = extras;
12006            pae.structure = structure;
12007            pae.content = content;
12008            if (referrer != null) {
12009                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12010            }
12011            pae.haveResult = true;
12012            pae.notifyAll();
12013            if (pae.intent == null && pae.receiver == null) {
12014                // Caller is just waiting for the result.
12015                return;
12016            }
12017        }
12018
12019        // We are now ready to launch the assist activity.
12020        IResultReceiver sendReceiver = null;
12021        Bundle sendBundle = null;
12022        synchronized (this) {
12023            buildAssistBundleLocked(pae, extras);
12024            boolean exists = mPendingAssistExtras.remove(pae);
12025            mUiHandler.removeCallbacks(pae);
12026            if (!exists) {
12027                // Timed out.
12028                return;
12029            }
12030            if ((sendReceiver=pae.receiver) != null) {
12031                // Caller wants result sent back to them.
12032                sendBundle = new Bundle();
12033                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12034                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12035                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12036                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12037                        pae.receiverExtras);
12038            }
12039        }
12040        if (sendReceiver != null) {
12041            try {
12042                sendReceiver.send(0, sendBundle);
12043            } catch (RemoteException e) {
12044            }
12045            return;
12046        }
12047
12048        long ident = Binder.clearCallingIdentity();
12049        try {
12050            pae.intent.replaceExtras(pae.extras);
12051            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12052                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12053                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12054            closeSystemDialogs("assist");
12055            try {
12056                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12057            } catch (ActivityNotFoundException e) {
12058                Slog.w(TAG, "No activity to handle assist action.", e);
12059            }
12060        } finally {
12061            Binder.restoreCallingIdentity(ident);
12062        }
12063    }
12064
12065    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12066            Bundle args) {
12067        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12068                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12069    }
12070
12071    public void registerProcessObserver(IProcessObserver observer) {
12072        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12073                "registerProcessObserver()");
12074        synchronized (this) {
12075            mProcessObservers.register(observer);
12076        }
12077    }
12078
12079    @Override
12080    public void unregisterProcessObserver(IProcessObserver observer) {
12081        synchronized (this) {
12082            mProcessObservers.unregister(observer);
12083        }
12084    }
12085
12086    @Override
12087    public void registerUidObserver(IUidObserver observer, int which) {
12088        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12089                "registerUidObserver()");
12090        synchronized (this) {
12091            mUidObservers.register(observer, which);
12092        }
12093    }
12094
12095    @Override
12096    public void unregisterUidObserver(IUidObserver observer) {
12097        synchronized (this) {
12098            mUidObservers.unregister(observer);
12099        }
12100    }
12101
12102    @Override
12103    public boolean convertFromTranslucent(IBinder token) {
12104        final long origId = Binder.clearCallingIdentity();
12105        try {
12106            synchronized (this) {
12107                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12108                if (r == null) {
12109                    return false;
12110                }
12111                final boolean translucentChanged = r.changeWindowTranslucency(true);
12112                if (translucentChanged) {
12113                    r.task.stack.releaseBackgroundResources(r);
12114                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12115                }
12116                mWindowManager.setAppFullscreen(token, true);
12117                return translucentChanged;
12118            }
12119        } finally {
12120            Binder.restoreCallingIdentity(origId);
12121        }
12122    }
12123
12124    @Override
12125    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12126        final long origId = Binder.clearCallingIdentity();
12127        try {
12128            synchronized (this) {
12129                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12130                if (r == null) {
12131                    return false;
12132                }
12133                int index = r.task.mActivities.lastIndexOf(r);
12134                if (index > 0) {
12135                    ActivityRecord under = r.task.mActivities.get(index - 1);
12136                    under.returningOptions = options;
12137                }
12138                final boolean translucentChanged = r.changeWindowTranslucency(false);
12139                if (translucentChanged) {
12140                    r.task.stack.convertActivityToTranslucent(r);
12141                }
12142                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12143                mWindowManager.setAppFullscreen(token, false);
12144                return translucentChanged;
12145            }
12146        } finally {
12147            Binder.restoreCallingIdentity(origId);
12148        }
12149    }
12150
12151    @Override
12152    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12153        final long origId = Binder.clearCallingIdentity();
12154        try {
12155            synchronized (this) {
12156                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12157                if (r != null) {
12158                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12159                }
12160            }
12161            return false;
12162        } finally {
12163            Binder.restoreCallingIdentity(origId);
12164        }
12165    }
12166
12167    @Override
12168    public boolean isBackgroundVisibleBehind(IBinder token) {
12169        final long origId = Binder.clearCallingIdentity();
12170        try {
12171            synchronized (this) {
12172                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12173                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12174                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12175                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12176                return visible;
12177            }
12178        } finally {
12179            Binder.restoreCallingIdentity(origId);
12180        }
12181    }
12182
12183    @Override
12184    public ActivityOptions getActivityOptions(IBinder token) {
12185        final long origId = Binder.clearCallingIdentity();
12186        try {
12187            synchronized (this) {
12188                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12189                if (r != null) {
12190                    final ActivityOptions activityOptions = r.pendingOptions;
12191                    r.pendingOptions = null;
12192                    return activityOptions;
12193                }
12194                return null;
12195            }
12196        } finally {
12197            Binder.restoreCallingIdentity(origId);
12198        }
12199    }
12200
12201    @Override
12202    public void setImmersive(IBinder token, boolean immersive) {
12203        synchronized(this) {
12204            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12205            if (r == null) {
12206                throw new IllegalArgumentException();
12207            }
12208            r.immersive = immersive;
12209
12210            // update associated state if we're frontmost
12211            if (r == mFocusedActivity) {
12212                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12213                applyUpdateLockStateLocked(r);
12214            }
12215        }
12216    }
12217
12218    @Override
12219    public boolean isImmersive(IBinder token) {
12220        synchronized (this) {
12221            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12222            if (r == null) {
12223                throw new IllegalArgumentException();
12224            }
12225            return r.immersive;
12226        }
12227    }
12228
12229    @Override
12230    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12231        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12232            throw new UnsupportedOperationException("VR mode not supported on this device!");
12233        }
12234
12235        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12236
12237        ActivityRecord r;
12238        synchronized (this) {
12239            r = ActivityRecord.isInStackLocked(token);
12240        }
12241
12242        if (r == null) {
12243            throw new IllegalArgumentException();
12244        }
12245
12246        int err;
12247        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12248                VrManagerInternal.NO_ERROR) {
12249            return err;
12250        }
12251
12252        synchronized(this) {
12253            r.requestedVrComponent = (enabled) ? packageName : null;
12254
12255            // Update associated state if this activity is currently focused
12256            if (r == mFocusedActivity) {
12257                applyUpdateVrModeLocked(r);
12258            }
12259            return 0;
12260        }
12261    }
12262
12263    @Override
12264    public boolean isVrModePackageEnabled(ComponentName packageName) {
12265        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12266            throw new UnsupportedOperationException("VR mode not supported on this device!");
12267        }
12268
12269        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12270
12271        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12272                VrManagerInternal.NO_ERROR;
12273    }
12274
12275    public boolean isTopActivityImmersive() {
12276        enforceNotIsolatedCaller("startActivity");
12277        synchronized (this) {
12278            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12279            return (r != null) ? r.immersive : false;
12280        }
12281    }
12282
12283    @Override
12284    public boolean isTopOfTask(IBinder token) {
12285        synchronized (this) {
12286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12287            if (r == null) {
12288                throw new IllegalArgumentException();
12289            }
12290            return r.task.getTopActivity() == r;
12291        }
12292    }
12293
12294    public final void enterSafeMode() {
12295        synchronized(this) {
12296            // It only makes sense to do this before the system is ready
12297            // and started launching other packages.
12298            if (!mSystemReady) {
12299                try {
12300                    AppGlobals.getPackageManager().enterSafeMode();
12301                } catch (RemoteException e) {
12302                }
12303            }
12304
12305            mSafeMode = true;
12306        }
12307    }
12308
12309    public final void showSafeModeOverlay() {
12310        View v = LayoutInflater.from(mContext).inflate(
12311                com.android.internal.R.layout.safe_mode, null);
12312        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12313        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12314        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12315        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12316        lp.gravity = Gravity.BOTTOM | Gravity.START;
12317        lp.format = v.getBackground().getOpacity();
12318        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12319                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12320        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12321        ((WindowManager)mContext.getSystemService(
12322                Context.WINDOW_SERVICE)).addView(v, lp);
12323    }
12324
12325    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12326        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12327            return;
12328        }
12329        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12330        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12331        synchronized (stats) {
12332            if (mBatteryStatsService.isOnBattery()) {
12333                mBatteryStatsService.enforceCallingPermission();
12334                int MY_UID = Binder.getCallingUid();
12335                final int uid;
12336                if (sender == null) {
12337                    uid = sourceUid;
12338                } else {
12339                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12340                }
12341                BatteryStatsImpl.Uid.Pkg pkg =
12342                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12343                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12344                pkg.noteWakeupAlarmLocked(tag);
12345            }
12346        }
12347    }
12348
12349    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12350        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12351            return;
12352        }
12353        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12354        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12355        synchronized (stats) {
12356            mBatteryStatsService.enforceCallingPermission();
12357            int MY_UID = Binder.getCallingUid();
12358            final int uid;
12359            if (sender == null) {
12360                uid = sourceUid;
12361            } else {
12362                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12363            }
12364            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12365        }
12366    }
12367
12368    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12369        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12370            return;
12371        }
12372        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12373        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12374        synchronized (stats) {
12375            mBatteryStatsService.enforceCallingPermission();
12376            int MY_UID = Binder.getCallingUid();
12377            final int uid;
12378            if (sender == null) {
12379                uid = sourceUid;
12380            } else {
12381                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12382            }
12383            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12384        }
12385    }
12386
12387    public boolean killPids(int[] pids, String pReason, boolean secure) {
12388        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12389            throw new SecurityException("killPids only available to the system");
12390        }
12391        String reason = (pReason == null) ? "Unknown" : pReason;
12392        // XXX Note: don't acquire main activity lock here, because the window
12393        // manager calls in with its locks held.
12394
12395        boolean killed = false;
12396        synchronized (mPidsSelfLocked) {
12397            int worstType = 0;
12398            for (int i=0; i<pids.length; i++) {
12399                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12400                if (proc != null) {
12401                    int type = proc.setAdj;
12402                    if (type > worstType) {
12403                        worstType = type;
12404                    }
12405                }
12406            }
12407
12408            // If the worst oom_adj is somewhere in the cached proc LRU range,
12409            // then constrain it so we will kill all cached procs.
12410            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12411                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12412                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12413            }
12414
12415            // If this is not a secure call, don't let it kill processes that
12416            // are important.
12417            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12418                worstType = ProcessList.SERVICE_ADJ;
12419            }
12420
12421            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12422            for (int i=0; i<pids.length; i++) {
12423                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12424                if (proc == null) {
12425                    continue;
12426                }
12427                int adj = proc.setAdj;
12428                if (adj >= worstType && !proc.killedByAm) {
12429                    proc.kill(reason, true);
12430                    killed = true;
12431                }
12432            }
12433        }
12434        return killed;
12435    }
12436
12437    @Override
12438    public void killUid(int appId, int userId, String reason) {
12439        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12440        synchronized (this) {
12441            final long identity = Binder.clearCallingIdentity();
12442            try {
12443                killPackageProcessesLocked(null, appId, userId,
12444                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12445                        reason != null ? reason : "kill uid");
12446            } finally {
12447                Binder.restoreCallingIdentity(identity);
12448            }
12449        }
12450    }
12451
12452    @Override
12453    public boolean killProcessesBelowForeground(String reason) {
12454        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12455            throw new SecurityException("killProcessesBelowForeground() only available to system");
12456        }
12457
12458        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12459    }
12460
12461    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12462        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12463            throw new SecurityException("killProcessesBelowAdj() only available to system");
12464        }
12465
12466        boolean killed = false;
12467        synchronized (mPidsSelfLocked) {
12468            final int size = mPidsSelfLocked.size();
12469            for (int i = 0; i < size; i++) {
12470                final int pid = mPidsSelfLocked.keyAt(i);
12471                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12472                if (proc == null) continue;
12473
12474                final int adj = proc.setAdj;
12475                if (adj > belowAdj && !proc.killedByAm) {
12476                    proc.kill(reason, true);
12477                    killed = true;
12478                }
12479            }
12480        }
12481        return killed;
12482    }
12483
12484    @Override
12485    public void hang(final IBinder who, boolean allowRestart) {
12486        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12487                != PackageManager.PERMISSION_GRANTED) {
12488            throw new SecurityException("Requires permission "
12489                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12490        }
12491
12492        final IBinder.DeathRecipient death = new DeathRecipient() {
12493            @Override
12494            public void binderDied() {
12495                synchronized (this) {
12496                    notifyAll();
12497                }
12498            }
12499        };
12500
12501        try {
12502            who.linkToDeath(death, 0);
12503        } catch (RemoteException e) {
12504            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12505            return;
12506        }
12507
12508        synchronized (this) {
12509            Watchdog.getInstance().setAllowRestart(allowRestart);
12510            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12511            synchronized (death) {
12512                while (who.isBinderAlive()) {
12513                    try {
12514                        death.wait();
12515                    } catch (InterruptedException e) {
12516                    }
12517                }
12518            }
12519            Watchdog.getInstance().setAllowRestart(true);
12520        }
12521    }
12522
12523    @Override
12524    public void restart() {
12525        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12526                != PackageManager.PERMISSION_GRANTED) {
12527            throw new SecurityException("Requires permission "
12528                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12529        }
12530
12531        Log.i(TAG, "Sending shutdown broadcast...");
12532
12533        BroadcastReceiver br = new BroadcastReceiver() {
12534            @Override public void onReceive(Context context, Intent intent) {
12535                // Now the broadcast is done, finish up the low-level shutdown.
12536                Log.i(TAG, "Shutting down activity manager...");
12537                shutdown(10000);
12538                Log.i(TAG, "Shutdown complete, restarting!");
12539                Process.killProcess(Process.myPid());
12540                System.exit(10);
12541            }
12542        };
12543
12544        // First send the high-level shut down broadcast.
12545        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12546        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12547        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12548        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12549        mContext.sendOrderedBroadcastAsUser(intent,
12550                UserHandle.ALL, null, br, mHandler, 0, null, null);
12551        */
12552        br.onReceive(mContext, intent);
12553    }
12554
12555    private long getLowRamTimeSinceIdle(long now) {
12556        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12557    }
12558
12559    @Override
12560    public void performIdleMaintenance() {
12561        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12562                != PackageManager.PERMISSION_GRANTED) {
12563            throw new SecurityException("Requires permission "
12564                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12565        }
12566
12567        synchronized (this) {
12568            final long now = SystemClock.uptimeMillis();
12569            final long timeSinceLastIdle = now - mLastIdleTime;
12570            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12571            mLastIdleTime = now;
12572            mLowRamTimeSinceLastIdle = 0;
12573            if (mLowRamStartTime != 0) {
12574                mLowRamStartTime = now;
12575            }
12576
12577            StringBuilder sb = new StringBuilder(128);
12578            sb.append("Idle maintenance over ");
12579            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12580            sb.append(" low RAM for ");
12581            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12582            Slog.i(TAG, sb.toString());
12583
12584            // If at least 1/3 of our time since the last idle period has been spent
12585            // with RAM low, then we want to kill processes.
12586            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12587
12588            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12589                ProcessRecord proc = mLruProcesses.get(i);
12590                if (proc.notCachedSinceIdle) {
12591                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12592                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12593                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12594                        if (doKilling && proc.initialIdlePss != 0
12595                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12596                            sb = new StringBuilder(128);
12597                            sb.append("Kill");
12598                            sb.append(proc.processName);
12599                            sb.append(" in idle maint: pss=");
12600                            sb.append(proc.lastPss);
12601                            sb.append(", swapPss=");
12602                            sb.append(proc.lastSwapPss);
12603                            sb.append(", initialPss=");
12604                            sb.append(proc.initialIdlePss);
12605                            sb.append(", period=");
12606                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12607                            sb.append(", lowRamPeriod=");
12608                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12609                            Slog.wtfQuiet(TAG, sb.toString());
12610                            proc.kill("idle maint (pss " + proc.lastPss
12611                                    + " from " + proc.initialIdlePss + ")", true);
12612                        }
12613                    }
12614                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12615                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12616                    proc.notCachedSinceIdle = true;
12617                    proc.initialIdlePss = 0;
12618                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12619                            mTestPssMode, isSleeping(), now);
12620                }
12621            }
12622
12623            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12624            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12625        }
12626    }
12627
12628    private void retrieveSettings() {
12629        final ContentResolver resolver = mContext.getContentResolver();
12630        final boolean freeformWindowManagement =
12631                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12632                        || Settings.Global.getInt(
12633                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12634        final boolean supportsPictureInPicture =
12635                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12636
12637        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12638        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12639        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12640        final boolean alwaysFinishActivities =
12641                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12642        final boolean lenientBackgroundCheck =
12643                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12644        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12645        final boolean forceResizable = Settings.Global.getInt(
12646                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12647        // Transfer any global setting for forcing RTL layout, into a System Property
12648        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12649
12650        final Configuration configuration = new Configuration();
12651        Settings.System.getConfiguration(resolver, configuration);
12652        if (forceRtl) {
12653            // This will take care of setting the correct layout direction flags
12654            configuration.setLayoutDirection(configuration.locale);
12655        }
12656
12657        synchronized (this) {
12658            mDebugApp = mOrigDebugApp = debugApp;
12659            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12660            mAlwaysFinishActivities = alwaysFinishActivities;
12661            mLenientBackgroundCheck = lenientBackgroundCheck;
12662            mForceResizableActivities = forceResizable;
12663            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12664            if (supportsMultiWindow || forceResizable) {
12665                mSupportsMultiWindow = true;
12666                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12667                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12668            } else {
12669                mSupportsMultiWindow = false;
12670                mSupportsFreeformWindowManagement = false;
12671                mSupportsPictureInPicture = false;
12672            }
12673            // This happens before any activities are started, so we can
12674            // change mConfiguration in-place.
12675            updateConfigurationLocked(configuration, null, true);
12676            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12677                    "Initial config: " + mConfiguration);
12678
12679            // Load resources only after the current configuration has been set.
12680            final Resources res = mContext.getResources();
12681            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12682            mThumbnailWidth = res.getDimensionPixelSize(
12683                    com.android.internal.R.dimen.thumbnail_width);
12684            mThumbnailHeight = res.getDimensionPixelSize(
12685                    com.android.internal.R.dimen.thumbnail_height);
12686            mFullscreenThumbnailScale = res.getFraction(
12687                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12688            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12689                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12690            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12691                    com.android.internal.R.string.config_appsNotReportingCrashes));
12692        }
12693    }
12694
12695    public boolean testIsSystemReady() {
12696        // no need to synchronize(this) just to read & return the value
12697        return mSystemReady;
12698    }
12699
12700    public void systemReady(final Runnable goingCallback) {
12701        synchronized(this) {
12702            if (mSystemReady) {
12703                // If we're done calling all the receivers, run the next "boot phase" passed in
12704                // by the SystemServer
12705                if (goingCallback != null) {
12706                    goingCallback.run();
12707                }
12708                return;
12709            }
12710
12711            mLocalDeviceIdleController
12712                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12713
12714            // Make sure we have the current profile info, since it is needed for security checks.
12715            mUserController.onSystemReady();
12716            mRecentTasks.onSystemReadyLocked();
12717            mAppOpsService.systemReady();
12718            mSystemReady = true;
12719        }
12720
12721        ArrayList<ProcessRecord> procsToKill = null;
12722        synchronized(mPidsSelfLocked) {
12723            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12724                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12725                if (!isAllowedWhileBooting(proc.info)){
12726                    if (procsToKill == null) {
12727                        procsToKill = new ArrayList<ProcessRecord>();
12728                    }
12729                    procsToKill.add(proc);
12730                }
12731            }
12732        }
12733
12734        synchronized(this) {
12735            if (procsToKill != null) {
12736                for (int i=procsToKill.size()-1; i>=0; i--) {
12737                    ProcessRecord proc = procsToKill.get(i);
12738                    Slog.i(TAG, "Removing system update proc: " + proc);
12739                    removeProcessLocked(proc, true, false, "system update done");
12740                }
12741            }
12742
12743            // Now that we have cleaned up any update processes, we
12744            // are ready to start launching real processes and know that
12745            // we won't trample on them any more.
12746            mProcessesReady = true;
12747        }
12748
12749        Slog.i(TAG, "System now ready");
12750        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12751            SystemClock.uptimeMillis());
12752
12753        synchronized(this) {
12754            // Make sure we have no pre-ready processes sitting around.
12755
12756            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12757                ResolveInfo ri = mContext.getPackageManager()
12758                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12759                                STOCK_PM_FLAGS);
12760                CharSequence errorMsg = null;
12761                if (ri != null) {
12762                    ActivityInfo ai = ri.activityInfo;
12763                    ApplicationInfo app = ai.applicationInfo;
12764                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12765                        mTopAction = Intent.ACTION_FACTORY_TEST;
12766                        mTopData = null;
12767                        mTopComponent = new ComponentName(app.packageName,
12768                                ai.name);
12769                    } else {
12770                        errorMsg = mContext.getResources().getText(
12771                                com.android.internal.R.string.factorytest_not_system);
12772                    }
12773                } else {
12774                    errorMsg = mContext.getResources().getText(
12775                            com.android.internal.R.string.factorytest_no_action);
12776                }
12777                if (errorMsg != null) {
12778                    mTopAction = null;
12779                    mTopData = null;
12780                    mTopComponent = null;
12781                    Message msg = Message.obtain();
12782                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12783                    msg.getData().putCharSequence("msg", errorMsg);
12784                    mUiHandler.sendMessage(msg);
12785                }
12786            }
12787        }
12788
12789        retrieveSettings();
12790        final int currentUserId;
12791        synchronized (this) {
12792            currentUserId = mUserController.getCurrentUserIdLocked();
12793            readGrantedUriPermissionsLocked();
12794        }
12795
12796        if (goingCallback != null) goingCallback.run();
12797
12798        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12799                Integer.toString(currentUserId), currentUserId);
12800        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12801                Integer.toString(currentUserId), currentUserId);
12802        mSystemServiceManager.startUser(currentUserId);
12803
12804        synchronized (this) {
12805            // Only start up encryption-aware persistent apps; once user is
12806            // unlocked we'll come back around and start unaware apps
12807            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12808
12809            // Start up initial activity.
12810            mBooting = true;
12811            // Enable home activity for system user, so that the system can always boot
12812            if (UserManager.isSplitSystemUser()) {
12813                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12814                try {
12815                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12816                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12817                            UserHandle.USER_SYSTEM);
12818                } catch (RemoteException e) {
12819                    throw e.rethrowAsRuntimeException();
12820                }
12821            }
12822            startHomeActivityLocked(currentUserId, "systemReady");
12823
12824            try {
12825                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12826                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12827                            + " data partition or your device will be unstable.");
12828                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12829                }
12830            } catch (RemoteException e) {
12831            }
12832
12833            if (!Build.isBuildConsistent()) {
12834                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12835                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12836            }
12837
12838            long ident = Binder.clearCallingIdentity();
12839            try {
12840                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12841                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12842                        | Intent.FLAG_RECEIVER_FOREGROUND);
12843                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12844                broadcastIntentLocked(null, null, intent,
12845                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12846                        null, false, false, MY_PID, Process.SYSTEM_UID,
12847                        currentUserId);
12848                intent = new Intent(Intent.ACTION_USER_STARTING);
12849                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12850                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12851                broadcastIntentLocked(null, null, intent,
12852                        null, new IIntentReceiver.Stub() {
12853                            @Override
12854                            public void performReceive(Intent intent, int resultCode, String data,
12855                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12856                                    throws RemoteException {
12857                            }
12858                        }, 0, null, null,
12859                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12860                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12861            } catch (Throwable t) {
12862                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12863            } finally {
12864                Binder.restoreCallingIdentity(ident);
12865            }
12866            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12867            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12868        }
12869    }
12870
12871    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12872        synchronized (this) {
12873            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12874        }
12875    }
12876
12877    void skipCurrentReceiverLocked(ProcessRecord app) {
12878        for (BroadcastQueue queue : mBroadcastQueues) {
12879            queue.skipCurrentReceiverLocked(app);
12880        }
12881    }
12882
12883    /**
12884     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12885     * The application process will exit immediately after this call returns.
12886     * @param app object of the crashing app, null for the system server
12887     * @param crashInfo describing the exception
12888     */
12889    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12890        ProcessRecord r = findAppProcess(app, "Crash");
12891        final String processName = app == null ? "system_server"
12892                : (r == null ? "unknown" : r.processName);
12893
12894        handleApplicationCrashInner("crash", r, processName, crashInfo);
12895    }
12896
12897    /* Native crash reporting uses this inner version because it needs to be somewhat
12898     * decoupled from the AM-managed cleanup lifecycle
12899     */
12900    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12901            ApplicationErrorReport.CrashInfo crashInfo) {
12902        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12903                UserHandle.getUserId(Binder.getCallingUid()), processName,
12904                r == null ? -1 : r.info.flags,
12905                crashInfo.exceptionClassName,
12906                crashInfo.exceptionMessage,
12907                crashInfo.throwFileName,
12908                crashInfo.throwLineNumber);
12909
12910        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12911
12912        mAppErrors.crashApplication(r, crashInfo);
12913    }
12914
12915    public void handleApplicationStrictModeViolation(
12916            IBinder app,
12917            int violationMask,
12918            StrictMode.ViolationInfo info) {
12919        ProcessRecord r = findAppProcess(app, "StrictMode");
12920        if (r == null) {
12921            return;
12922        }
12923
12924        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12925            Integer stackFingerprint = info.hashCode();
12926            boolean logIt = true;
12927            synchronized (mAlreadyLoggedViolatedStacks) {
12928                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12929                    logIt = false;
12930                    // TODO: sub-sample into EventLog for these, with
12931                    // the info.durationMillis?  Then we'd get
12932                    // the relative pain numbers, without logging all
12933                    // the stack traces repeatedly.  We'd want to do
12934                    // likewise in the client code, which also does
12935                    // dup suppression, before the Binder call.
12936                } else {
12937                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12938                        mAlreadyLoggedViolatedStacks.clear();
12939                    }
12940                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12941                }
12942            }
12943            if (logIt) {
12944                logStrictModeViolationToDropBox(r, info);
12945            }
12946        }
12947
12948        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12949            AppErrorResult result = new AppErrorResult();
12950            synchronized (this) {
12951                final long origId = Binder.clearCallingIdentity();
12952
12953                Message msg = Message.obtain();
12954                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12955                HashMap<String, Object> data = new HashMap<String, Object>();
12956                data.put("result", result);
12957                data.put("app", r);
12958                data.put("violationMask", violationMask);
12959                data.put("info", info);
12960                msg.obj = data;
12961                mUiHandler.sendMessage(msg);
12962
12963                Binder.restoreCallingIdentity(origId);
12964            }
12965            int res = result.get();
12966            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12967        }
12968    }
12969
12970    // Depending on the policy in effect, there could be a bunch of
12971    // these in quick succession so we try to batch these together to
12972    // minimize disk writes, number of dropbox entries, and maximize
12973    // compression, by having more fewer, larger records.
12974    private void logStrictModeViolationToDropBox(
12975            ProcessRecord process,
12976            StrictMode.ViolationInfo info) {
12977        if (info == null) {
12978            return;
12979        }
12980        final boolean isSystemApp = process == null ||
12981                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12982                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12983        final String processName = process == null ? "unknown" : process.processName;
12984        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12985        final DropBoxManager dbox = (DropBoxManager)
12986                mContext.getSystemService(Context.DROPBOX_SERVICE);
12987
12988        // Exit early if the dropbox isn't configured to accept this report type.
12989        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12990
12991        boolean bufferWasEmpty;
12992        boolean needsFlush;
12993        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12994        synchronized (sb) {
12995            bufferWasEmpty = sb.length() == 0;
12996            appendDropBoxProcessHeaders(process, processName, sb);
12997            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12998            sb.append("System-App: ").append(isSystemApp).append("\n");
12999            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13000            if (info.violationNumThisLoop != 0) {
13001                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13002            }
13003            if (info.numAnimationsRunning != 0) {
13004                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13005            }
13006            if (info.broadcastIntentAction != null) {
13007                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13008            }
13009            if (info.durationMillis != -1) {
13010                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13011            }
13012            if (info.numInstances != -1) {
13013                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13014            }
13015            if (info.tags != null) {
13016                for (String tag : info.tags) {
13017                    sb.append("Span-Tag: ").append(tag).append("\n");
13018                }
13019            }
13020            sb.append("\n");
13021            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13022                sb.append(info.crashInfo.stackTrace);
13023                sb.append("\n");
13024            }
13025            if (info.message != null) {
13026                sb.append(info.message);
13027                sb.append("\n");
13028            }
13029
13030            // Only buffer up to ~64k.  Various logging bits truncate
13031            // things at 128k.
13032            needsFlush = (sb.length() > 64 * 1024);
13033        }
13034
13035        // Flush immediately if the buffer's grown too large, or this
13036        // is a non-system app.  Non-system apps are isolated with a
13037        // different tag & policy and not batched.
13038        //
13039        // Batching is useful during internal testing with
13040        // StrictMode settings turned up high.  Without batching,
13041        // thousands of separate files could be created on boot.
13042        if (!isSystemApp || needsFlush) {
13043            new Thread("Error dump: " + dropboxTag) {
13044                @Override
13045                public void run() {
13046                    String report;
13047                    synchronized (sb) {
13048                        report = sb.toString();
13049                        sb.delete(0, sb.length());
13050                        sb.trimToSize();
13051                    }
13052                    if (report.length() != 0) {
13053                        dbox.addText(dropboxTag, report);
13054                    }
13055                }
13056            }.start();
13057            return;
13058        }
13059
13060        // System app batching:
13061        if (!bufferWasEmpty) {
13062            // An existing dropbox-writing thread is outstanding, so
13063            // we don't need to start it up.  The existing thread will
13064            // catch the buffer appends we just did.
13065            return;
13066        }
13067
13068        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13069        // (After this point, we shouldn't access AMS internal data structures.)
13070        new Thread("Error dump: " + dropboxTag) {
13071            @Override
13072            public void run() {
13073                // 5 second sleep to let stacks arrive and be batched together
13074                try {
13075                    Thread.sleep(5000);  // 5 seconds
13076                } catch (InterruptedException e) {}
13077
13078                String errorReport;
13079                synchronized (mStrictModeBuffer) {
13080                    errorReport = mStrictModeBuffer.toString();
13081                    if (errorReport.length() == 0) {
13082                        return;
13083                    }
13084                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13085                    mStrictModeBuffer.trimToSize();
13086                }
13087                dbox.addText(dropboxTag, errorReport);
13088            }
13089        }.start();
13090    }
13091
13092    /**
13093     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13094     * @param app object of the crashing app, null for the system server
13095     * @param tag reported by the caller
13096     * @param system whether this wtf is coming from the system
13097     * @param crashInfo describing the context of the error
13098     * @return true if the process should exit immediately (WTF is fatal)
13099     */
13100    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13101            final ApplicationErrorReport.CrashInfo crashInfo) {
13102        final int callingUid = Binder.getCallingUid();
13103        final int callingPid = Binder.getCallingPid();
13104
13105        if (system) {
13106            // If this is coming from the system, we could very well have low-level
13107            // system locks held, so we want to do this all asynchronously.  And we
13108            // never want this to become fatal, so there is that too.
13109            mHandler.post(new Runnable() {
13110                @Override public void run() {
13111                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13112                }
13113            });
13114            return false;
13115        }
13116
13117        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13118                crashInfo);
13119
13120        if (r != null && r.pid != Process.myPid() &&
13121                Settings.Global.getInt(mContext.getContentResolver(),
13122                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13123            mAppErrors.crashApplication(r, crashInfo);
13124            return true;
13125        } else {
13126            return false;
13127        }
13128    }
13129
13130    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13131            final ApplicationErrorReport.CrashInfo crashInfo) {
13132        final ProcessRecord r = findAppProcess(app, "WTF");
13133        final String processName = app == null ? "system_server"
13134                : (r == null ? "unknown" : r.processName);
13135
13136        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13137                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13138
13139        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13140
13141        return r;
13142    }
13143
13144    /**
13145     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13146     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13147     */
13148    private ProcessRecord findAppProcess(IBinder app, String reason) {
13149        if (app == null) {
13150            return null;
13151        }
13152
13153        synchronized (this) {
13154            final int NP = mProcessNames.getMap().size();
13155            for (int ip=0; ip<NP; ip++) {
13156                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13157                final int NA = apps.size();
13158                for (int ia=0; ia<NA; ia++) {
13159                    ProcessRecord p = apps.valueAt(ia);
13160                    if (p.thread != null && p.thread.asBinder() == app) {
13161                        return p;
13162                    }
13163                }
13164            }
13165
13166            Slog.w(TAG, "Can't find mystery application for " + reason
13167                    + " from pid=" + Binder.getCallingPid()
13168                    + " uid=" + Binder.getCallingUid() + ": " + app);
13169            return null;
13170        }
13171    }
13172
13173    /**
13174     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13175     * to append various headers to the dropbox log text.
13176     */
13177    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13178            StringBuilder sb) {
13179        // Watchdog thread ends up invoking this function (with
13180        // a null ProcessRecord) to add the stack file to dropbox.
13181        // Do not acquire a lock on this (am) in such cases, as it
13182        // could cause a potential deadlock, if and when watchdog
13183        // is invoked due to unavailability of lock on am and it
13184        // would prevent watchdog from killing system_server.
13185        if (process == null) {
13186            sb.append("Process: ").append(processName).append("\n");
13187            return;
13188        }
13189        // Note: ProcessRecord 'process' is guarded by the service
13190        // instance.  (notably process.pkgList, which could otherwise change
13191        // concurrently during execution of this method)
13192        synchronized (this) {
13193            sb.append("Process: ").append(processName).append("\n");
13194            int flags = process.info.flags;
13195            IPackageManager pm = AppGlobals.getPackageManager();
13196            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13197            for (int ip=0; ip<process.pkgList.size(); ip++) {
13198                String pkg = process.pkgList.keyAt(ip);
13199                sb.append("Package: ").append(pkg);
13200                try {
13201                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13202                    if (pi != null) {
13203                        sb.append(" v").append(pi.versionCode);
13204                        if (pi.versionName != null) {
13205                            sb.append(" (").append(pi.versionName).append(")");
13206                        }
13207                    }
13208                } catch (RemoteException e) {
13209                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13210                }
13211                sb.append("\n");
13212            }
13213        }
13214    }
13215
13216    private static String processClass(ProcessRecord process) {
13217        if (process == null || process.pid == MY_PID) {
13218            return "system_server";
13219        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13220            return "system_app";
13221        } else {
13222            return "data_app";
13223        }
13224    }
13225
13226    private volatile long mWtfClusterStart;
13227    private volatile int mWtfClusterCount;
13228
13229    /**
13230     * Write a description of an error (crash, WTF, ANR) to the drop box.
13231     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13232     * @param process which caused the error, null means the system server
13233     * @param activity which triggered the error, null if unknown
13234     * @param parent activity related to the error, null if unknown
13235     * @param subject line related to the error, null if absent
13236     * @param report in long form describing the error, null if absent
13237     * @param logFile to include in the report, null if none
13238     * @param crashInfo giving an application stack trace, null if absent
13239     */
13240    public void addErrorToDropBox(String eventType,
13241            ProcessRecord process, String processName, ActivityRecord activity,
13242            ActivityRecord parent, String subject,
13243            final String report, final File logFile,
13244            final ApplicationErrorReport.CrashInfo crashInfo) {
13245        // NOTE -- this must never acquire the ActivityManagerService lock,
13246        // otherwise the watchdog may be prevented from resetting the system.
13247
13248        final String dropboxTag = processClass(process) + "_" + eventType;
13249        final DropBoxManager dbox = (DropBoxManager)
13250                mContext.getSystemService(Context.DROPBOX_SERVICE);
13251
13252        // Exit early if the dropbox isn't configured to accept this report type.
13253        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13254
13255        // Rate-limit how often we're willing to do the heavy lifting below to
13256        // collect and record logs; currently 5 logs per 10 second period.
13257        final long now = SystemClock.elapsedRealtime();
13258        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13259            mWtfClusterStart = now;
13260            mWtfClusterCount = 1;
13261        } else {
13262            if (mWtfClusterCount++ >= 5) return;
13263        }
13264
13265        final StringBuilder sb = new StringBuilder(1024);
13266        appendDropBoxProcessHeaders(process, processName, sb);
13267        if (process != null) {
13268            sb.append("Foreground: ")
13269                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13270                    .append("\n");
13271        }
13272        if (activity != null) {
13273            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13274        }
13275        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13276            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13277        }
13278        if (parent != null && parent != activity) {
13279            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13280        }
13281        if (subject != null) {
13282            sb.append("Subject: ").append(subject).append("\n");
13283        }
13284        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13285        if (Debug.isDebuggerConnected()) {
13286            sb.append("Debugger: Connected\n");
13287        }
13288        sb.append("\n");
13289
13290        // Do the rest in a worker thread to avoid blocking the caller on I/O
13291        // (After this point, we shouldn't access AMS internal data structures.)
13292        Thread worker = new Thread("Error dump: " + dropboxTag) {
13293            @Override
13294            public void run() {
13295                if (report != null) {
13296                    sb.append(report);
13297                }
13298                if (logFile != null) {
13299                    try {
13300                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13301                                    "\n\n[[TRUNCATED]]"));
13302                    } catch (IOException e) {
13303                        Slog.e(TAG, "Error reading " + logFile, e);
13304                    }
13305                }
13306                if (crashInfo != null && crashInfo.stackTrace != null) {
13307                    sb.append(crashInfo.stackTrace);
13308                }
13309
13310                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13311                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13312                if (lines > 0) {
13313                    sb.append("\n");
13314
13315                    // Merge several logcat streams, and take the last N lines
13316                    InputStreamReader input = null;
13317                    try {
13318                        java.lang.Process logcat = new ProcessBuilder(
13319                                "/system/bin/timeout", "-k", "15s", "10s",
13320                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13321                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13322                                        .redirectErrorStream(true).start();
13323
13324                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13325                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13326                        input = new InputStreamReader(logcat.getInputStream());
13327
13328                        int num;
13329                        char[] buf = new char[8192];
13330                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13331                    } catch (IOException e) {
13332                        Slog.e(TAG, "Error running logcat", e);
13333                    } finally {
13334                        if (input != null) try { input.close(); } catch (IOException e) {}
13335                    }
13336                }
13337
13338                dbox.addText(dropboxTag, sb.toString());
13339            }
13340        };
13341
13342        if (process == null) {
13343            // If process is null, we are being called from some internal code
13344            // and may be about to die -- run this synchronously.
13345            worker.run();
13346        } else {
13347            worker.start();
13348        }
13349    }
13350
13351    @Override
13352    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13353        enforceNotIsolatedCaller("getProcessesInErrorState");
13354        // assume our apps are happy - lazy create the list
13355        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13356
13357        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13358                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13359        int userId = UserHandle.getUserId(Binder.getCallingUid());
13360
13361        synchronized (this) {
13362
13363            // iterate across all processes
13364            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13365                ProcessRecord app = mLruProcesses.get(i);
13366                if (!allUsers && app.userId != userId) {
13367                    continue;
13368                }
13369                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13370                    // This one's in trouble, so we'll generate a report for it
13371                    // crashes are higher priority (in case there's a crash *and* an anr)
13372                    ActivityManager.ProcessErrorStateInfo report = null;
13373                    if (app.crashing) {
13374                        report = app.crashingReport;
13375                    } else if (app.notResponding) {
13376                        report = app.notRespondingReport;
13377                    }
13378
13379                    if (report != null) {
13380                        if (errList == null) {
13381                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13382                        }
13383                        errList.add(report);
13384                    } else {
13385                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13386                                " crashing = " + app.crashing +
13387                                " notResponding = " + app.notResponding);
13388                    }
13389                }
13390            }
13391        }
13392
13393        return errList;
13394    }
13395
13396    static int procStateToImportance(int procState, int memAdj,
13397            ActivityManager.RunningAppProcessInfo currApp) {
13398        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13399        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13400            currApp.lru = memAdj;
13401        } else {
13402            currApp.lru = 0;
13403        }
13404        return imp;
13405    }
13406
13407    private void fillInProcMemInfo(ProcessRecord app,
13408            ActivityManager.RunningAppProcessInfo outInfo) {
13409        outInfo.pid = app.pid;
13410        outInfo.uid = app.info.uid;
13411        if (mHeavyWeightProcess == app) {
13412            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13413        }
13414        if (app.persistent) {
13415            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13416        }
13417        if (app.activities.size() > 0) {
13418            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13419        }
13420        outInfo.lastTrimLevel = app.trimMemoryLevel;
13421        int adj = app.curAdj;
13422        int procState = app.curProcState;
13423        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13424        outInfo.importanceReasonCode = app.adjTypeCode;
13425        outInfo.processState = app.curProcState;
13426    }
13427
13428    @Override
13429    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13430        enforceNotIsolatedCaller("getRunningAppProcesses");
13431
13432        final int callingUid = Binder.getCallingUid();
13433
13434        // Lazy instantiation of list
13435        List<ActivityManager.RunningAppProcessInfo> runList = null;
13436        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13437                callingUid) == PackageManager.PERMISSION_GRANTED;
13438        final int userId = UserHandle.getUserId(callingUid);
13439        final boolean allUids = isGetTasksAllowed(
13440                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13441
13442        synchronized (this) {
13443            // Iterate across all processes
13444            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13445                ProcessRecord app = mLruProcesses.get(i);
13446                if ((!allUsers && app.userId != userId)
13447                        || (!allUids && app.uid != callingUid)) {
13448                    continue;
13449                }
13450                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13451                    // Generate process state info for running application
13452                    ActivityManager.RunningAppProcessInfo currApp =
13453                        new ActivityManager.RunningAppProcessInfo(app.processName,
13454                                app.pid, app.getPackageList());
13455                    fillInProcMemInfo(app, currApp);
13456                    if (app.adjSource instanceof ProcessRecord) {
13457                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13458                        currApp.importanceReasonImportance =
13459                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13460                                        app.adjSourceProcState);
13461                    } else if (app.adjSource instanceof ActivityRecord) {
13462                        ActivityRecord r = (ActivityRecord)app.adjSource;
13463                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13464                    }
13465                    if (app.adjTarget instanceof ComponentName) {
13466                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13467                    }
13468                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13469                    //        + " lru=" + currApp.lru);
13470                    if (runList == null) {
13471                        runList = new ArrayList<>();
13472                    }
13473                    runList.add(currApp);
13474                }
13475            }
13476        }
13477        return runList;
13478    }
13479
13480    @Override
13481    public List<ApplicationInfo> getRunningExternalApplications() {
13482        enforceNotIsolatedCaller("getRunningExternalApplications");
13483        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13484        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13485        if (runningApps != null && runningApps.size() > 0) {
13486            Set<String> extList = new HashSet<String>();
13487            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13488                if (app.pkgList != null) {
13489                    for (String pkg : app.pkgList) {
13490                        extList.add(pkg);
13491                    }
13492                }
13493            }
13494            IPackageManager pm = AppGlobals.getPackageManager();
13495            for (String pkg : extList) {
13496                try {
13497                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13498                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13499                        retList.add(info);
13500                    }
13501                } catch (RemoteException e) {
13502                }
13503            }
13504        }
13505        return retList;
13506    }
13507
13508    @Override
13509    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13510        enforceNotIsolatedCaller("getMyMemoryState");
13511        synchronized (this) {
13512            ProcessRecord proc;
13513            synchronized (mPidsSelfLocked) {
13514                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13515            }
13516            fillInProcMemInfo(proc, outInfo);
13517        }
13518    }
13519
13520    @Override
13521    public int getMemoryTrimLevel() {
13522        enforceNotIsolatedCaller("getMyMemoryState");
13523        synchronized (this) {
13524            return mLastMemoryLevel;
13525        }
13526    }
13527
13528    @Override
13529    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13530            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13531        (new ActivityManagerShellCommand(this, false)).exec(
13532                this, in, out, err, args, resultReceiver);
13533    }
13534
13535    @Override
13536    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13537        if (checkCallingPermission(android.Manifest.permission.DUMP)
13538                != PackageManager.PERMISSION_GRANTED) {
13539            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13540                    + Binder.getCallingPid()
13541                    + ", uid=" + Binder.getCallingUid()
13542                    + " without permission "
13543                    + android.Manifest.permission.DUMP);
13544            return;
13545        }
13546
13547        boolean dumpAll = false;
13548        boolean dumpClient = false;
13549        String dumpPackage = null;
13550
13551        int opti = 0;
13552        while (opti < args.length) {
13553            String opt = args[opti];
13554            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13555                break;
13556            }
13557            opti++;
13558            if ("-a".equals(opt)) {
13559                dumpAll = true;
13560            } else if ("-c".equals(opt)) {
13561                dumpClient = true;
13562            } else if ("-p".equals(opt)) {
13563                if (opti < args.length) {
13564                    dumpPackage = args[opti];
13565                    opti++;
13566                } else {
13567                    pw.println("Error: -p option requires package argument");
13568                    return;
13569                }
13570                dumpClient = true;
13571            } else if ("-h".equals(opt)) {
13572                ActivityManagerShellCommand.dumpHelp(pw, true);
13573                return;
13574            } else {
13575                pw.println("Unknown argument: " + opt + "; use -h for help");
13576            }
13577        }
13578
13579        long origId = Binder.clearCallingIdentity();
13580        boolean more = false;
13581        // Is the caller requesting to dump a particular piece of data?
13582        if (opti < args.length) {
13583            String cmd = args[opti];
13584            opti++;
13585            if ("activities".equals(cmd) || "a".equals(cmd)) {
13586                synchronized (this) {
13587                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13588                }
13589            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13590                synchronized (this) {
13591                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13592                }
13593            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13594                String[] newArgs;
13595                String name;
13596                if (opti >= args.length) {
13597                    name = null;
13598                    newArgs = EMPTY_STRING_ARRAY;
13599                } else {
13600                    dumpPackage = args[opti];
13601                    opti++;
13602                    newArgs = new String[args.length - opti];
13603                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13604                            args.length - opti);
13605                }
13606                synchronized (this) {
13607                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13608                }
13609            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13610                String[] newArgs;
13611                String name;
13612                if (opti >= args.length) {
13613                    name = null;
13614                    newArgs = EMPTY_STRING_ARRAY;
13615                } else {
13616                    dumpPackage = args[opti];
13617                    opti++;
13618                    newArgs = new String[args.length - opti];
13619                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13620                            args.length - opti);
13621                }
13622                synchronized (this) {
13623                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13624                }
13625            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13626                String[] newArgs;
13627                String name;
13628                if (opti >= args.length) {
13629                    name = null;
13630                    newArgs = EMPTY_STRING_ARRAY;
13631                } else {
13632                    dumpPackage = args[opti];
13633                    opti++;
13634                    newArgs = new String[args.length - opti];
13635                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13636                            args.length - opti);
13637                }
13638                synchronized (this) {
13639                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13640                }
13641            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13642                synchronized (this) {
13643                    dumpOomLocked(fd, pw, args, opti, true);
13644                }
13645            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13646                synchronized (this) {
13647                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13648                }
13649            } else if ("provider".equals(cmd)) {
13650                String[] newArgs;
13651                String name;
13652                if (opti >= args.length) {
13653                    name = null;
13654                    newArgs = EMPTY_STRING_ARRAY;
13655                } else {
13656                    name = args[opti];
13657                    opti++;
13658                    newArgs = new String[args.length - opti];
13659                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13660                }
13661                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13662                    pw.println("No providers match: " + name);
13663                    pw.println("Use -h for help.");
13664                }
13665            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13666                synchronized (this) {
13667                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13668                }
13669            } else if ("service".equals(cmd)) {
13670                String[] newArgs;
13671                String name;
13672                if (opti >= args.length) {
13673                    name = null;
13674                    newArgs = EMPTY_STRING_ARRAY;
13675                } else {
13676                    name = args[opti];
13677                    opti++;
13678                    newArgs = new String[args.length - opti];
13679                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13680                            args.length - opti);
13681                }
13682                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13683                    pw.println("No services match: " + name);
13684                    pw.println("Use -h for help.");
13685                }
13686            } else if ("package".equals(cmd)) {
13687                String[] newArgs;
13688                if (opti >= args.length) {
13689                    pw.println("package: no package name specified");
13690                    pw.println("Use -h for help.");
13691                } else {
13692                    dumpPackage = args[opti];
13693                    opti++;
13694                    newArgs = new String[args.length - opti];
13695                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13696                            args.length - opti);
13697                    args = newArgs;
13698                    opti = 0;
13699                    more = true;
13700                }
13701            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13702                synchronized (this) {
13703                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13704                }
13705            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13706                synchronized (this) {
13707                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13708                }
13709            } else if ("locks".equals(cmd)) {
13710                LockGuard.dump(fd, pw, args);
13711            } else {
13712                // Dumping a single activity?
13713                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13714                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13715                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13716                    if (res < 0) {
13717                        pw.println("Bad activity command, or no activities match: " + cmd);
13718                        pw.println("Use -h for help.");
13719                    }
13720                }
13721            }
13722            if (!more) {
13723                Binder.restoreCallingIdentity(origId);
13724                return;
13725            }
13726        }
13727
13728        // No piece of data specified, dump everything.
13729        synchronized (this) {
13730            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13731            pw.println();
13732            if (dumpAll) {
13733                pw.println("-------------------------------------------------------------------------------");
13734            }
13735            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13736            pw.println();
13737            if (dumpAll) {
13738                pw.println("-------------------------------------------------------------------------------");
13739            }
13740            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13741            pw.println();
13742            if (dumpAll) {
13743                pw.println("-------------------------------------------------------------------------------");
13744            }
13745            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13746            pw.println();
13747            if (dumpAll) {
13748                pw.println("-------------------------------------------------------------------------------");
13749            }
13750            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13751            pw.println();
13752            if (dumpAll) {
13753                pw.println("-------------------------------------------------------------------------------");
13754            }
13755            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13756            pw.println();
13757            if (dumpAll) {
13758                pw.println("-------------------------------------------------------------------------------");
13759            }
13760            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13761            if (mAssociations.size() > 0) {
13762                pw.println();
13763                if (dumpAll) {
13764                    pw.println("-------------------------------------------------------------------------------");
13765                }
13766                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13767            }
13768            pw.println();
13769            if (dumpAll) {
13770                pw.println("-------------------------------------------------------------------------------");
13771            }
13772            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13773        }
13774        Binder.restoreCallingIdentity(origId);
13775    }
13776
13777    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13778            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13779        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13780
13781        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13782                dumpPackage);
13783        boolean needSep = printedAnything;
13784
13785        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13786                dumpPackage, needSep, "  mFocusedActivity: ");
13787        if (printed) {
13788            printedAnything = true;
13789            needSep = false;
13790        }
13791
13792        if (dumpPackage == null) {
13793            if (needSep) {
13794                pw.println();
13795            }
13796            needSep = true;
13797            printedAnything = true;
13798            mStackSupervisor.dump(pw, "  ");
13799        }
13800
13801        if (!printedAnything) {
13802            pw.println("  (nothing)");
13803        }
13804    }
13805
13806    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13807            int opti, boolean dumpAll, String dumpPackage) {
13808        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13809
13810        boolean printedAnything = false;
13811
13812        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13813            boolean printedHeader = false;
13814
13815            final int N = mRecentTasks.size();
13816            for (int i=0; i<N; i++) {
13817                TaskRecord tr = mRecentTasks.get(i);
13818                if (dumpPackage != null) {
13819                    if (tr.realActivity == null ||
13820                            !dumpPackage.equals(tr.realActivity)) {
13821                        continue;
13822                    }
13823                }
13824                if (!printedHeader) {
13825                    pw.println("  Recent tasks:");
13826                    printedHeader = true;
13827                    printedAnything = true;
13828                }
13829                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13830                        pw.println(tr);
13831                if (dumpAll) {
13832                    mRecentTasks.get(i).dump(pw, "    ");
13833                }
13834            }
13835        }
13836
13837        if (!printedAnything) {
13838            pw.println("  (nothing)");
13839        }
13840    }
13841
13842    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13843            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13844        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13845
13846        int dumpUid = 0;
13847        if (dumpPackage != null) {
13848            IPackageManager pm = AppGlobals.getPackageManager();
13849            try {
13850                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13851            } catch (RemoteException e) {
13852            }
13853        }
13854
13855        boolean printedAnything = false;
13856
13857        final long now = SystemClock.uptimeMillis();
13858
13859        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13860            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13861                    = mAssociations.valueAt(i1);
13862            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13863                SparseArray<ArrayMap<String, Association>> sourceUids
13864                        = targetComponents.valueAt(i2);
13865                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13866                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13867                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13868                        Association ass = sourceProcesses.valueAt(i4);
13869                        if (dumpPackage != null) {
13870                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13871                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13872                                continue;
13873                            }
13874                        }
13875                        printedAnything = true;
13876                        pw.print("  ");
13877                        pw.print(ass.mTargetProcess);
13878                        pw.print("/");
13879                        UserHandle.formatUid(pw, ass.mTargetUid);
13880                        pw.print(" <- ");
13881                        pw.print(ass.mSourceProcess);
13882                        pw.print("/");
13883                        UserHandle.formatUid(pw, ass.mSourceUid);
13884                        pw.println();
13885                        pw.print("    via ");
13886                        pw.print(ass.mTargetComponent.flattenToShortString());
13887                        pw.println();
13888                        pw.print("    ");
13889                        long dur = ass.mTime;
13890                        if (ass.mNesting > 0) {
13891                            dur += now - ass.mStartTime;
13892                        }
13893                        TimeUtils.formatDuration(dur, pw);
13894                        pw.print(" (");
13895                        pw.print(ass.mCount);
13896                        pw.print(" times)");
13897                        pw.print("  ");
13898                        for (int i=0; i<ass.mStateTimes.length; i++) {
13899                            long amt = ass.mStateTimes[i];
13900                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13901                                amt += now - ass.mLastStateUptime;
13902                            }
13903                            if (amt != 0) {
13904                                pw.print(" ");
13905                                pw.print(ProcessList.makeProcStateString(
13906                                            i + ActivityManager.MIN_PROCESS_STATE));
13907                                pw.print("=");
13908                                TimeUtils.formatDuration(amt, pw);
13909                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13910                                    pw.print("*");
13911                                }
13912                            }
13913                        }
13914                        pw.println();
13915                        if (ass.mNesting > 0) {
13916                            pw.print("    Currently active: ");
13917                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13918                            pw.println();
13919                        }
13920                    }
13921                }
13922            }
13923
13924        }
13925
13926        if (!printedAnything) {
13927            pw.println("  (nothing)");
13928        }
13929    }
13930
13931    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13932            String header, boolean needSep) {
13933        boolean printed = false;
13934        int whichAppId = -1;
13935        if (dumpPackage != null) {
13936            try {
13937                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13938                        dumpPackage, 0);
13939                whichAppId = UserHandle.getAppId(info.uid);
13940            } catch (NameNotFoundException e) {
13941                e.printStackTrace();
13942            }
13943        }
13944        for (int i=0; i<uids.size(); i++) {
13945            UidRecord uidRec = uids.valueAt(i);
13946            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13947                continue;
13948            }
13949            if (!printed) {
13950                printed = true;
13951                if (needSep) {
13952                    pw.println();
13953                }
13954                pw.print("  ");
13955                pw.println(header);
13956                needSep = true;
13957            }
13958            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13959            pw.print(": "); pw.println(uidRec);
13960        }
13961        return printed;
13962    }
13963
13964    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13965            int opti, boolean dumpAll, String dumpPackage) {
13966        boolean needSep = false;
13967        boolean printedAnything = false;
13968        int numPers = 0;
13969
13970        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13971
13972        if (dumpAll) {
13973            final int NP = mProcessNames.getMap().size();
13974            for (int ip=0; ip<NP; ip++) {
13975                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13976                final int NA = procs.size();
13977                for (int ia=0; ia<NA; ia++) {
13978                    ProcessRecord r = procs.valueAt(ia);
13979                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13980                        continue;
13981                    }
13982                    if (!needSep) {
13983                        pw.println("  All known processes:");
13984                        needSep = true;
13985                        printedAnything = true;
13986                    }
13987                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13988                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13989                        pw.print(" "); pw.println(r);
13990                    r.dump(pw, "    ");
13991                    if (r.persistent) {
13992                        numPers++;
13993                    }
13994                }
13995            }
13996        }
13997
13998        if (mIsolatedProcesses.size() > 0) {
13999            boolean printed = false;
14000            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14001                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14002                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14003                    continue;
14004                }
14005                if (!printed) {
14006                    if (needSep) {
14007                        pw.println();
14008                    }
14009                    pw.println("  Isolated process list (sorted by uid):");
14010                    printedAnything = true;
14011                    printed = true;
14012                    needSep = true;
14013                }
14014                pw.println(String.format("%sIsolated #%2d: %s",
14015                        "    ", i, r.toString()));
14016            }
14017        }
14018
14019        if (mActiveUids.size() > 0) {
14020            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14021                printedAnything = needSep = true;
14022            }
14023        }
14024        if (mValidateUids.size() > 0) {
14025            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14026                printedAnything = needSep = true;
14027            }
14028        }
14029
14030        if (mLruProcesses.size() > 0) {
14031            if (needSep) {
14032                pw.println();
14033            }
14034            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14035                    pw.print(" total, non-act at ");
14036                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14037                    pw.print(", non-svc at ");
14038                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14039                    pw.println("):");
14040            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14041            needSep = true;
14042            printedAnything = true;
14043        }
14044
14045        if (dumpAll || dumpPackage != null) {
14046            synchronized (mPidsSelfLocked) {
14047                boolean printed = false;
14048                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14049                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14050                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14051                        continue;
14052                    }
14053                    if (!printed) {
14054                        if (needSep) pw.println();
14055                        needSep = true;
14056                        pw.println("  PID mappings:");
14057                        printed = true;
14058                        printedAnything = true;
14059                    }
14060                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14061                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14062                }
14063            }
14064        }
14065
14066        if (mForegroundProcesses.size() > 0) {
14067            synchronized (mPidsSelfLocked) {
14068                boolean printed = false;
14069                for (int i=0; i<mForegroundProcesses.size(); i++) {
14070                    ProcessRecord r = mPidsSelfLocked.get(
14071                            mForegroundProcesses.valueAt(i).pid);
14072                    if (dumpPackage != null && (r == null
14073                            || !r.pkgList.containsKey(dumpPackage))) {
14074                        continue;
14075                    }
14076                    if (!printed) {
14077                        if (needSep) pw.println();
14078                        needSep = true;
14079                        pw.println("  Foreground Processes:");
14080                        printed = true;
14081                        printedAnything = true;
14082                    }
14083                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14084                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14085                }
14086            }
14087        }
14088
14089        if (mPersistentStartingProcesses.size() > 0) {
14090            if (needSep) pw.println();
14091            needSep = true;
14092            printedAnything = true;
14093            pw.println("  Persisent processes that are starting:");
14094            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14095                    "Starting Norm", "Restarting PERS", dumpPackage);
14096        }
14097
14098        if (mRemovedProcesses.size() > 0) {
14099            if (needSep) pw.println();
14100            needSep = true;
14101            printedAnything = true;
14102            pw.println("  Processes that are being removed:");
14103            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14104                    "Removed Norm", "Removed PERS", dumpPackage);
14105        }
14106
14107        if (mProcessesOnHold.size() > 0) {
14108            if (needSep) pw.println();
14109            needSep = true;
14110            printedAnything = true;
14111            pw.println("  Processes that are on old until the system is ready:");
14112            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14113                    "OnHold Norm", "OnHold PERS", dumpPackage);
14114        }
14115
14116        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14117
14118        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14119        if (needSep) {
14120            printedAnything = true;
14121        }
14122
14123        if (dumpPackage == null) {
14124            pw.println();
14125            needSep = false;
14126            mUserController.dump(pw, dumpAll);
14127        }
14128        if (mHomeProcess != null && (dumpPackage == null
14129                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14130            if (needSep) {
14131                pw.println();
14132                needSep = false;
14133            }
14134            pw.println("  mHomeProcess: " + mHomeProcess);
14135        }
14136        if (mPreviousProcess != null && (dumpPackage == null
14137                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14138            if (needSep) {
14139                pw.println();
14140                needSep = false;
14141            }
14142            pw.println("  mPreviousProcess: " + mPreviousProcess);
14143        }
14144        if (dumpAll) {
14145            StringBuilder sb = new StringBuilder(128);
14146            sb.append("  mPreviousProcessVisibleTime: ");
14147            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14148            pw.println(sb);
14149        }
14150        if (mHeavyWeightProcess != null && (dumpPackage == null
14151                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14152            if (needSep) {
14153                pw.println();
14154                needSep = false;
14155            }
14156            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14157        }
14158        if (dumpPackage == null) {
14159            pw.println("  mConfiguration: " + mConfiguration);
14160        }
14161        if (dumpAll) {
14162            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14163            if (mCompatModePackages.getPackages().size() > 0) {
14164                boolean printed = false;
14165                for (Map.Entry<String, Integer> entry
14166                        : mCompatModePackages.getPackages().entrySet()) {
14167                    String pkg = entry.getKey();
14168                    int mode = entry.getValue();
14169                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14170                        continue;
14171                    }
14172                    if (!printed) {
14173                        pw.println("  mScreenCompatPackages:");
14174                        printed = true;
14175                    }
14176                    pw.print("    "); pw.print(pkg); pw.print(": ");
14177                            pw.print(mode); pw.println();
14178                }
14179            }
14180        }
14181        if (dumpPackage == null) {
14182            pw.println("  mWakefulness="
14183                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14184            pw.println("  mSleepTokens=" + mSleepTokens);
14185            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14186                    + lockScreenShownToString());
14187            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14188            if (mRunningVoice != null) {
14189                pw.println("  mRunningVoice=" + mRunningVoice);
14190                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14191            }
14192        }
14193        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14194                || mOrigWaitForDebugger) {
14195            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14196                    || dumpPackage.equals(mOrigDebugApp)) {
14197                if (needSep) {
14198                    pw.println();
14199                    needSep = false;
14200                }
14201                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14202                        + " mDebugTransient=" + mDebugTransient
14203                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14204            }
14205        }
14206        if (mCurAppTimeTracker != null) {
14207            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14208        }
14209        if (mMemWatchProcesses.getMap().size() > 0) {
14210            pw.println("  Mem watch processes:");
14211            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14212                    = mMemWatchProcesses.getMap();
14213            for (int i=0; i<procs.size(); i++) {
14214                final String proc = procs.keyAt(i);
14215                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14216                for (int j=0; j<uids.size(); j++) {
14217                    if (needSep) {
14218                        pw.println();
14219                        needSep = false;
14220                    }
14221                    StringBuilder sb = new StringBuilder();
14222                    sb.append("    ").append(proc).append('/');
14223                    UserHandle.formatUid(sb, uids.keyAt(j));
14224                    Pair<Long, String> val = uids.valueAt(j);
14225                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14226                    if (val.second != null) {
14227                        sb.append(", report to ").append(val.second);
14228                    }
14229                    pw.println(sb.toString());
14230                }
14231            }
14232            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14233            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14234            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14235                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14236        }
14237        if (mTrackAllocationApp != null) {
14238            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14239                if (needSep) {
14240                    pw.println();
14241                    needSep = false;
14242                }
14243                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14244            }
14245        }
14246        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14247                || mProfileFd != null) {
14248            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14249                if (needSep) {
14250                    pw.println();
14251                    needSep = false;
14252                }
14253                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14254                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14255                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14256                        + mAutoStopProfiler);
14257                pw.println("  mProfileType=" + mProfileType);
14258            }
14259        }
14260        if (mNativeDebuggingApp != null) {
14261            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14262                if (needSep) {
14263                    pw.println();
14264                    needSep = false;
14265                }
14266                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14267            }
14268        }
14269        if (dumpPackage == null) {
14270            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14271                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14272                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14273            }
14274            if (mController != null) {
14275                pw.println("  mController=" + mController
14276                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14277            }
14278            if (dumpAll) {
14279                pw.println("  Total persistent processes: " + numPers);
14280                pw.println("  mProcessesReady=" + mProcessesReady
14281                        + " mSystemReady=" + mSystemReady
14282                        + " mBooted=" + mBooted
14283                        + " mFactoryTest=" + mFactoryTest);
14284                pw.println("  mBooting=" + mBooting
14285                        + " mCallFinishBooting=" + mCallFinishBooting
14286                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14287                pw.print("  mLastPowerCheckRealtime=");
14288                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14289                        pw.println("");
14290                pw.print("  mLastPowerCheckUptime=");
14291                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14292                        pw.println("");
14293                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14294                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14295                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14296                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14297                        + " (" + mLruProcesses.size() + " total)"
14298                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14299                        + " mNumServiceProcs=" + mNumServiceProcs
14300                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14301                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14302                        + " mLastMemoryLevel=" + mLastMemoryLevel
14303                        + " mLastNumProcesses=" + mLastNumProcesses);
14304                long now = SystemClock.uptimeMillis();
14305                pw.print("  mLastIdleTime=");
14306                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14307                        pw.print(" mLowRamSinceLastIdle=");
14308                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14309                        pw.println();
14310            }
14311        }
14312
14313        if (!printedAnything) {
14314            pw.println("  (nothing)");
14315        }
14316    }
14317
14318    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14319            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14320        if (mProcessesToGc.size() > 0) {
14321            boolean printed = false;
14322            long now = SystemClock.uptimeMillis();
14323            for (int i=0; i<mProcessesToGc.size(); i++) {
14324                ProcessRecord proc = mProcessesToGc.get(i);
14325                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14326                    continue;
14327                }
14328                if (!printed) {
14329                    if (needSep) pw.println();
14330                    needSep = true;
14331                    pw.println("  Processes that are waiting to GC:");
14332                    printed = true;
14333                }
14334                pw.print("    Process "); pw.println(proc);
14335                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14336                        pw.print(", last gced=");
14337                        pw.print(now-proc.lastRequestedGc);
14338                        pw.print(" ms ago, last lowMem=");
14339                        pw.print(now-proc.lastLowMemory);
14340                        pw.println(" ms ago");
14341
14342            }
14343        }
14344        return needSep;
14345    }
14346
14347    void printOomLevel(PrintWriter pw, String name, int adj) {
14348        pw.print("    ");
14349        if (adj >= 0) {
14350            pw.print(' ');
14351            if (adj < 10) pw.print(' ');
14352        } else {
14353            if (adj > -10) pw.print(' ');
14354        }
14355        pw.print(adj);
14356        pw.print(": ");
14357        pw.print(name);
14358        pw.print(" (");
14359        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14360        pw.println(")");
14361    }
14362
14363    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14364            int opti, boolean dumpAll) {
14365        boolean needSep = false;
14366
14367        if (mLruProcesses.size() > 0) {
14368            if (needSep) pw.println();
14369            needSep = true;
14370            pw.println("  OOM levels:");
14371            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14372            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14373            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14374            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14375            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14376            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14377            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14378            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14379            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14380            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14381            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14382            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14383            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14384            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14385
14386            if (needSep) pw.println();
14387            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14388                    pw.print(" total, non-act at ");
14389                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14390                    pw.print(", non-svc at ");
14391                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14392                    pw.println("):");
14393            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14394            needSep = true;
14395        }
14396
14397        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14398
14399        pw.println();
14400        pw.println("  mHomeProcess: " + mHomeProcess);
14401        pw.println("  mPreviousProcess: " + mPreviousProcess);
14402        if (mHeavyWeightProcess != null) {
14403            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14404        }
14405
14406        return true;
14407    }
14408
14409    /**
14410     * There are three ways to call this:
14411     *  - no provider specified: dump all the providers
14412     *  - a flattened component name that matched an existing provider was specified as the
14413     *    first arg: dump that one provider
14414     *  - the first arg isn't the flattened component name of an existing provider:
14415     *    dump all providers whose component contains the first arg as a substring
14416     */
14417    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14418            int opti, boolean dumpAll) {
14419        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14420    }
14421
14422    static class ItemMatcher {
14423        ArrayList<ComponentName> components;
14424        ArrayList<String> strings;
14425        ArrayList<Integer> objects;
14426        boolean all;
14427
14428        ItemMatcher() {
14429            all = true;
14430        }
14431
14432        void build(String name) {
14433            ComponentName componentName = ComponentName.unflattenFromString(name);
14434            if (componentName != null) {
14435                if (components == null) {
14436                    components = new ArrayList<ComponentName>();
14437                }
14438                components.add(componentName);
14439                all = false;
14440            } else {
14441                int objectId = 0;
14442                // Not a '/' separated full component name; maybe an object ID?
14443                try {
14444                    objectId = Integer.parseInt(name, 16);
14445                    if (objects == null) {
14446                        objects = new ArrayList<Integer>();
14447                    }
14448                    objects.add(objectId);
14449                    all = false;
14450                } catch (RuntimeException e) {
14451                    // Not an integer; just do string match.
14452                    if (strings == null) {
14453                        strings = new ArrayList<String>();
14454                    }
14455                    strings.add(name);
14456                    all = false;
14457                }
14458            }
14459        }
14460
14461        int build(String[] args, int opti) {
14462            for (; opti<args.length; opti++) {
14463                String name = args[opti];
14464                if ("--".equals(name)) {
14465                    return opti+1;
14466                }
14467                build(name);
14468            }
14469            return opti;
14470        }
14471
14472        boolean match(Object object, ComponentName comp) {
14473            if (all) {
14474                return true;
14475            }
14476            if (components != null) {
14477                for (int i=0; i<components.size(); i++) {
14478                    if (components.get(i).equals(comp)) {
14479                        return true;
14480                    }
14481                }
14482            }
14483            if (objects != null) {
14484                for (int i=0; i<objects.size(); i++) {
14485                    if (System.identityHashCode(object) == objects.get(i)) {
14486                        return true;
14487                    }
14488                }
14489            }
14490            if (strings != null) {
14491                String flat = comp.flattenToString();
14492                for (int i=0; i<strings.size(); i++) {
14493                    if (flat.contains(strings.get(i))) {
14494                        return true;
14495                    }
14496                }
14497            }
14498            return false;
14499        }
14500    }
14501
14502    /**
14503     * There are three things that cmd can be:
14504     *  - a flattened component name that matches an existing activity
14505     *  - the cmd arg isn't the flattened component name of an existing activity:
14506     *    dump all activity whose component contains the cmd as a substring
14507     *  - A hex number of the ActivityRecord object instance.
14508     */
14509    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14510            int opti, boolean dumpAll) {
14511        ArrayList<ActivityRecord> activities;
14512
14513        synchronized (this) {
14514            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14515        }
14516
14517        if (activities.size() <= 0) {
14518            return false;
14519        }
14520
14521        String[] newArgs = new String[args.length - opti];
14522        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14523
14524        TaskRecord lastTask = null;
14525        boolean needSep = false;
14526        for (int i=activities.size()-1; i>=0; i--) {
14527            ActivityRecord r = activities.get(i);
14528            if (needSep) {
14529                pw.println();
14530            }
14531            needSep = true;
14532            synchronized (this) {
14533                if (lastTask != r.task) {
14534                    lastTask = r.task;
14535                    pw.print("TASK "); pw.print(lastTask.affinity);
14536                            pw.print(" id="); pw.println(lastTask.taskId);
14537                    if (dumpAll) {
14538                        lastTask.dump(pw, "  ");
14539                    }
14540                }
14541            }
14542            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14543        }
14544        return true;
14545    }
14546
14547    /**
14548     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14549     * there is a thread associated with the activity.
14550     */
14551    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14552            final ActivityRecord r, String[] args, boolean dumpAll) {
14553        String innerPrefix = prefix + "  ";
14554        synchronized (this) {
14555            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14556                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14557                    pw.print(" pid=");
14558                    if (r.app != null) pw.println(r.app.pid);
14559                    else pw.println("(not running)");
14560            if (dumpAll) {
14561                r.dump(pw, innerPrefix);
14562            }
14563        }
14564        if (r.app != null && r.app.thread != null) {
14565            // flush anything that is already in the PrintWriter since the thread is going
14566            // to write to the file descriptor directly
14567            pw.flush();
14568            try {
14569                TransferPipe tp = new TransferPipe();
14570                try {
14571                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14572                            r.appToken, innerPrefix, args);
14573                    tp.go(fd);
14574                } finally {
14575                    tp.kill();
14576                }
14577            } catch (IOException e) {
14578                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14579            } catch (RemoteException e) {
14580                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14581            }
14582        }
14583    }
14584
14585    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14586            int opti, boolean dumpAll, String dumpPackage) {
14587        boolean needSep = false;
14588        boolean onlyHistory = false;
14589        boolean printedAnything = false;
14590
14591        if ("history".equals(dumpPackage)) {
14592            if (opti < args.length && "-s".equals(args[opti])) {
14593                dumpAll = false;
14594            }
14595            onlyHistory = true;
14596            dumpPackage = null;
14597        }
14598
14599        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14600        if (!onlyHistory && dumpAll) {
14601            if (mRegisteredReceivers.size() > 0) {
14602                boolean printed = false;
14603                Iterator it = mRegisteredReceivers.values().iterator();
14604                while (it.hasNext()) {
14605                    ReceiverList r = (ReceiverList)it.next();
14606                    if (dumpPackage != null && (r.app == null ||
14607                            !dumpPackage.equals(r.app.info.packageName))) {
14608                        continue;
14609                    }
14610                    if (!printed) {
14611                        pw.println("  Registered Receivers:");
14612                        needSep = true;
14613                        printed = true;
14614                        printedAnything = true;
14615                    }
14616                    pw.print("  * "); pw.println(r);
14617                    r.dump(pw, "    ");
14618                }
14619            }
14620
14621            if (mReceiverResolver.dump(pw, needSep ?
14622                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14623                    "    ", dumpPackage, false, false)) {
14624                needSep = true;
14625                printedAnything = true;
14626            }
14627        }
14628
14629        for (BroadcastQueue q : mBroadcastQueues) {
14630            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14631            printedAnything |= needSep;
14632        }
14633
14634        needSep = true;
14635
14636        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14637            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14638                if (needSep) {
14639                    pw.println();
14640                }
14641                needSep = true;
14642                printedAnything = true;
14643                pw.print("  Sticky broadcasts for user ");
14644                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14645                StringBuilder sb = new StringBuilder(128);
14646                for (Map.Entry<String, ArrayList<Intent>> ent
14647                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14648                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14649                    if (dumpAll) {
14650                        pw.println(":");
14651                        ArrayList<Intent> intents = ent.getValue();
14652                        final int N = intents.size();
14653                        for (int i=0; i<N; i++) {
14654                            sb.setLength(0);
14655                            sb.append("    Intent: ");
14656                            intents.get(i).toShortString(sb, false, true, false, false);
14657                            pw.println(sb.toString());
14658                            Bundle bundle = intents.get(i).getExtras();
14659                            if (bundle != null) {
14660                                pw.print("      ");
14661                                pw.println(bundle.toString());
14662                            }
14663                        }
14664                    } else {
14665                        pw.println("");
14666                    }
14667                }
14668            }
14669        }
14670
14671        if (!onlyHistory && dumpAll) {
14672            pw.println();
14673            for (BroadcastQueue queue : mBroadcastQueues) {
14674                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14675                        + queue.mBroadcastsScheduled);
14676            }
14677            pw.println("  mHandler:");
14678            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14679            needSep = true;
14680            printedAnything = true;
14681        }
14682
14683        if (!printedAnything) {
14684            pw.println("  (nothing)");
14685        }
14686    }
14687
14688    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14689            int opti, boolean dumpAll, String dumpPackage) {
14690        boolean needSep;
14691        boolean printedAnything = false;
14692
14693        ItemMatcher matcher = new ItemMatcher();
14694        matcher.build(args, opti);
14695
14696        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14697
14698        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14699        printedAnything |= needSep;
14700
14701        if (mLaunchingProviders.size() > 0) {
14702            boolean printed = false;
14703            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14704                ContentProviderRecord r = mLaunchingProviders.get(i);
14705                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14706                    continue;
14707                }
14708                if (!printed) {
14709                    if (needSep) pw.println();
14710                    needSep = true;
14711                    pw.println("  Launching content providers:");
14712                    printed = true;
14713                    printedAnything = true;
14714                }
14715                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14716                        pw.println(r);
14717            }
14718        }
14719
14720        if (!printedAnything) {
14721            pw.println("  (nothing)");
14722        }
14723    }
14724
14725    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14726            int opti, boolean dumpAll, String dumpPackage) {
14727        boolean needSep = false;
14728        boolean printedAnything = false;
14729
14730        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14731
14732        if (mGrantedUriPermissions.size() > 0) {
14733            boolean printed = false;
14734            int dumpUid = -2;
14735            if (dumpPackage != null) {
14736                try {
14737                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14738                            MATCH_UNINSTALLED_PACKAGES, 0);
14739                } catch (NameNotFoundException e) {
14740                    dumpUid = -1;
14741                }
14742            }
14743            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14744                int uid = mGrantedUriPermissions.keyAt(i);
14745                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14746                    continue;
14747                }
14748                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14749                if (!printed) {
14750                    if (needSep) pw.println();
14751                    needSep = true;
14752                    pw.println("  Granted Uri Permissions:");
14753                    printed = true;
14754                    printedAnything = true;
14755                }
14756                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14757                for (UriPermission perm : perms.values()) {
14758                    pw.print("    "); pw.println(perm);
14759                    if (dumpAll) {
14760                        perm.dump(pw, "      ");
14761                    }
14762                }
14763            }
14764        }
14765
14766        if (!printedAnything) {
14767            pw.println("  (nothing)");
14768        }
14769    }
14770
14771    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14772            int opti, boolean dumpAll, String dumpPackage) {
14773        boolean printed = false;
14774
14775        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14776
14777        if (mIntentSenderRecords.size() > 0) {
14778            Iterator<WeakReference<PendingIntentRecord>> it
14779                    = mIntentSenderRecords.values().iterator();
14780            while (it.hasNext()) {
14781                WeakReference<PendingIntentRecord> ref = it.next();
14782                PendingIntentRecord rec = ref != null ? ref.get(): null;
14783                if (dumpPackage != null && (rec == null
14784                        || !dumpPackage.equals(rec.key.packageName))) {
14785                    continue;
14786                }
14787                printed = true;
14788                if (rec != null) {
14789                    pw.print("  * "); pw.println(rec);
14790                    if (dumpAll) {
14791                        rec.dump(pw, "    ");
14792                    }
14793                } else {
14794                    pw.print("  * "); pw.println(ref);
14795                }
14796            }
14797        }
14798
14799        if (!printed) {
14800            pw.println("  (nothing)");
14801        }
14802    }
14803
14804    private static final int dumpProcessList(PrintWriter pw,
14805            ActivityManagerService service, List list,
14806            String prefix, String normalLabel, String persistentLabel,
14807            String dumpPackage) {
14808        int numPers = 0;
14809        final int N = list.size()-1;
14810        for (int i=N; i>=0; i--) {
14811            ProcessRecord r = (ProcessRecord)list.get(i);
14812            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14813                continue;
14814            }
14815            pw.println(String.format("%s%s #%2d: %s",
14816                    prefix, (r.persistent ? persistentLabel : normalLabel),
14817                    i, r.toString()));
14818            if (r.persistent) {
14819                numPers++;
14820            }
14821        }
14822        return numPers;
14823    }
14824
14825    private static final boolean dumpProcessOomList(PrintWriter pw,
14826            ActivityManagerService service, List<ProcessRecord> origList,
14827            String prefix, String normalLabel, String persistentLabel,
14828            boolean inclDetails, String dumpPackage) {
14829
14830        ArrayList<Pair<ProcessRecord, Integer>> list
14831                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14832        for (int i=0; i<origList.size(); i++) {
14833            ProcessRecord r = origList.get(i);
14834            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14835                continue;
14836            }
14837            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14838        }
14839
14840        if (list.size() <= 0) {
14841            return false;
14842        }
14843
14844        Comparator<Pair<ProcessRecord, Integer>> comparator
14845                = new Comparator<Pair<ProcessRecord, Integer>>() {
14846            @Override
14847            public int compare(Pair<ProcessRecord, Integer> object1,
14848                    Pair<ProcessRecord, Integer> object2) {
14849                if (object1.first.setAdj != object2.first.setAdj) {
14850                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14851                }
14852                if (object1.first.setProcState != object2.first.setProcState) {
14853                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14854                }
14855                if (object1.second.intValue() != object2.second.intValue()) {
14856                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14857                }
14858                return 0;
14859            }
14860        };
14861
14862        Collections.sort(list, comparator);
14863
14864        final long curRealtime = SystemClock.elapsedRealtime();
14865        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14866        final long curUptime = SystemClock.uptimeMillis();
14867        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14868
14869        for (int i=list.size()-1; i>=0; i--) {
14870            ProcessRecord r = list.get(i).first;
14871            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14872            char schedGroup;
14873            switch (r.setSchedGroup) {
14874                case ProcessList.SCHED_GROUP_BACKGROUND:
14875                    schedGroup = 'B';
14876                    break;
14877                case ProcessList.SCHED_GROUP_DEFAULT:
14878                    schedGroup = 'F';
14879                    break;
14880                case ProcessList.SCHED_GROUP_TOP_APP:
14881                    schedGroup = 'T';
14882                    break;
14883                default:
14884                    schedGroup = '?';
14885                    break;
14886            }
14887            char foreground;
14888            if (r.foregroundActivities) {
14889                foreground = 'A';
14890            } else if (r.foregroundServices) {
14891                foreground = 'S';
14892            } else {
14893                foreground = ' ';
14894            }
14895            String procState = ProcessList.makeProcStateString(r.curProcState);
14896            pw.print(prefix);
14897            pw.print(r.persistent ? persistentLabel : normalLabel);
14898            pw.print(" #");
14899            int num = (origList.size()-1)-list.get(i).second;
14900            if (num < 10) pw.print(' ');
14901            pw.print(num);
14902            pw.print(": ");
14903            pw.print(oomAdj);
14904            pw.print(' ');
14905            pw.print(schedGroup);
14906            pw.print('/');
14907            pw.print(foreground);
14908            pw.print('/');
14909            pw.print(procState);
14910            pw.print(" trm:");
14911            if (r.trimMemoryLevel < 10) pw.print(' ');
14912            pw.print(r.trimMemoryLevel);
14913            pw.print(' ');
14914            pw.print(r.toShortString());
14915            pw.print(" (");
14916            pw.print(r.adjType);
14917            pw.println(')');
14918            if (r.adjSource != null || r.adjTarget != null) {
14919                pw.print(prefix);
14920                pw.print("    ");
14921                if (r.adjTarget instanceof ComponentName) {
14922                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14923                } else if (r.adjTarget != null) {
14924                    pw.print(r.adjTarget.toString());
14925                } else {
14926                    pw.print("{null}");
14927                }
14928                pw.print("<=");
14929                if (r.adjSource instanceof ProcessRecord) {
14930                    pw.print("Proc{");
14931                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14932                    pw.println("}");
14933                } else if (r.adjSource != null) {
14934                    pw.println(r.adjSource.toString());
14935                } else {
14936                    pw.println("{null}");
14937                }
14938            }
14939            if (inclDetails) {
14940                pw.print(prefix);
14941                pw.print("    ");
14942                pw.print("oom: max="); pw.print(r.maxAdj);
14943                pw.print(" curRaw="); pw.print(r.curRawAdj);
14944                pw.print(" setRaw="); pw.print(r.setRawAdj);
14945                pw.print(" cur="); pw.print(r.curAdj);
14946                pw.print(" set="); pw.println(r.setAdj);
14947                pw.print(prefix);
14948                pw.print("    ");
14949                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14950                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14951                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14952                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14953                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14954                pw.println();
14955                pw.print(prefix);
14956                pw.print("    ");
14957                pw.print("cached="); pw.print(r.cached);
14958                pw.print(" empty="); pw.print(r.empty);
14959                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14960
14961                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14962                    if (r.lastWakeTime != 0) {
14963                        long wtime;
14964                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14965                        synchronized (stats) {
14966                            wtime = stats.getProcessWakeTime(r.info.uid,
14967                                    r.pid, curRealtime);
14968                        }
14969                        long timeUsed = wtime - r.lastWakeTime;
14970                        pw.print(prefix);
14971                        pw.print("    ");
14972                        pw.print("keep awake over ");
14973                        TimeUtils.formatDuration(realtimeSince, pw);
14974                        pw.print(" used ");
14975                        TimeUtils.formatDuration(timeUsed, pw);
14976                        pw.print(" (");
14977                        pw.print((timeUsed*100)/realtimeSince);
14978                        pw.println("%)");
14979                    }
14980                    if (r.lastCpuTime != 0) {
14981                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14982                        pw.print(prefix);
14983                        pw.print("    ");
14984                        pw.print("run cpu over ");
14985                        TimeUtils.formatDuration(uptimeSince, pw);
14986                        pw.print(" used ");
14987                        TimeUtils.formatDuration(timeUsed, pw);
14988                        pw.print(" (");
14989                        pw.print((timeUsed*100)/uptimeSince);
14990                        pw.println("%)");
14991                    }
14992                }
14993            }
14994        }
14995        return true;
14996    }
14997
14998    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14999            String[] args) {
15000        ArrayList<ProcessRecord> procs;
15001        synchronized (this) {
15002            if (args != null && args.length > start
15003                    && args[start].charAt(0) != '-') {
15004                procs = new ArrayList<ProcessRecord>();
15005                int pid = -1;
15006                try {
15007                    pid = Integer.parseInt(args[start]);
15008                } catch (NumberFormatException e) {
15009                }
15010                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15011                    ProcessRecord proc = mLruProcesses.get(i);
15012                    if (proc.pid == pid) {
15013                        procs.add(proc);
15014                    } else if (allPkgs && proc.pkgList != null
15015                            && proc.pkgList.containsKey(args[start])) {
15016                        procs.add(proc);
15017                    } else if (proc.processName.equals(args[start])) {
15018                        procs.add(proc);
15019                    }
15020                }
15021                if (procs.size() <= 0) {
15022                    return null;
15023                }
15024            } else {
15025                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15026            }
15027        }
15028        return procs;
15029    }
15030
15031    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15032            PrintWriter pw, String[] args) {
15033        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15034        if (procs == null) {
15035            pw.println("No process found for: " + args[0]);
15036            return;
15037        }
15038
15039        long uptime = SystemClock.uptimeMillis();
15040        long realtime = SystemClock.elapsedRealtime();
15041        pw.println("Applications Graphics Acceleration Info:");
15042        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15043
15044        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15045            ProcessRecord r = procs.get(i);
15046            if (r.thread != null) {
15047                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15048                pw.flush();
15049                try {
15050                    TransferPipe tp = new TransferPipe();
15051                    try {
15052                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15053                        tp.go(fd);
15054                    } finally {
15055                        tp.kill();
15056                    }
15057                } catch (IOException e) {
15058                    pw.println("Failure while dumping the app: " + r);
15059                    pw.flush();
15060                } catch (RemoteException e) {
15061                    pw.println("Got a RemoteException while dumping the app " + r);
15062                    pw.flush();
15063                }
15064            }
15065        }
15066    }
15067
15068    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15069        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15070        if (procs == null) {
15071            pw.println("No process found for: " + args[0]);
15072            return;
15073        }
15074
15075        pw.println("Applications Database Info:");
15076
15077        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15078            ProcessRecord r = procs.get(i);
15079            if (r.thread != null) {
15080                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15081                pw.flush();
15082                try {
15083                    TransferPipe tp = new TransferPipe();
15084                    try {
15085                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15086                        tp.go(fd);
15087                    } finally {
15088                        tp.kill();
15089                    }
15090                } catch (IOException e) {
15091                    pw.println("Failure while dumping the app: " + r);
15092                    pw.flush();
15093                } catch (RemoteException e) {
15094                    pw.println("Got a RemoteException while dumping the app " + r);
15095                    pw.flush();
15096                }
15097            }
15098        }
15099    }
15100
15101    final static class MemItem {
15102        final boolean isProc;
15103        final String label;
15104        final String shortLabel;
15105        final long pss;
15106        final long swapPss;
15107        final int id;
15108        final boolean hasActivities;
15109        ArrayList<MemItem> subitems;
15110
15111        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15112                boolean _hasActivities) {
15113            isProc = true;
15114            label = _label;
15115            shortLabel = _shortLabel;
15116            pss = _pss;
15117            swapPss = _swapPss;
15118            id = _id;
15119            hasActivities = _hasActivities;
15120        }
15121
15122        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15123            isProc = false;
15124            label = _label;
15125            shortLabel = _shortLabel;
15126            pss = _pss;
15127            swapPss = _swapPss;
15128            id = _id;
15129            hasActivities = false;
15130        }
15131    }
15132
15133    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15134            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15135        if (sort && !isCompact) {
15136            Collections.sort(items, new Comparator<MemItem>() {
15137                @Override
15138                public int compare(MemItem lhs, MemItem rhs) {
15139                    if (lhs.pss < rhs.pss) {
15140                        return 1;
15141                    } else if (lhs.pss > rhs.pss) {
15142                        return -1;
15143                    }
15144                    return 0;
15145                }
15146            });
15147        }
15148
15149        for (int i=0; i<items.size(); i++) {
15150            MemItem mi = items.get(i);
15151            if (!isCompact) {
15152                if (dumpSwapPss) {
15153                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15154                            mi.label, stringifyKBSize(mi.swapPss));
15155                } else {
15156                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15157                }
15158            } else if (mi.isProc) {
15159                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15160                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15161                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15162                pw.println(mi.hasActivities ? ",a" : ",e");
15163            } else {
15164                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15165                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15166            }
15167            if (mi.subitems != null) {
15168                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15169                        true, isCompact, dumpSwapPss);
15170            }
15171        }
15172    }
15173
15174    // These are in KB.
15175    static final long[] DUMP_MEM_BUCKETS = new long[] {
15176        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15177        120*1024, 160*1024, 200*1024,
15178        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15179        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15180    };
15181
15182    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15183            boolean stackLike) {
15184        int start = label.lastIndexOf('.');
15185        if (start >= 0) start++;
15186        else start = 0;
15187        int end = label.length();
15188        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15189            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15190                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15191                out.append(bucket);
15192                out.append(stackLike ? "MB." : "MB ");
15193                out.append(label, start, end);
15194                return;
15195            }
15196        }
15197        out.append(memKB/1024);
15198        out.append(stackLike ? "MB." : "MB ");
15199        out.append(label, start, end);
15200    }
15201
15202    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15203            ProcessList.NATIVE_ADJ,
15204            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15205            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15206            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15207            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15208            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15209            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15210    };
15211    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15212            "Native",
15213            "System", "Persistent", "Persistent Service", "Foreground",
15214            "Visible", "Perceptible",
15215            "Heavy Weight", "Backup",
15216            "A Services", "Home",
15217            "Previous", "B Services", "Cached"
15218    };
15219    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15220            "native",
15221            "sys", "pers", "persvc", "fore",
15222            "vis", "percept",
15223            "heavy", "backup",
15224            "servicea", "home",
15225            "prev", "serviceb", "cached"
15226    };
15227
15228    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15229            long realtime, boolean isCheckinRequest, boolean isCompact) {
15230        if (isCompact) {
15231            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15232        }
15233        if (isCheckinRequest || isCompact) {
15234            // short checkin version
15235            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15236        } else {
15237            pw.println("Applications Memory Usage (in Kilobytes):");
15238            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15239        }
15240    }
15241
15242    private static final int KSM_SHARED = 0;
15243    private static final int KSM_SHARING = 1;
15244    private static final int KSM_UNSHARED = 2;
15245    private static final int KSM_VOLATILE = 3;
15246
15247    private final long[] getKsmInfo() {
15248        long[] longOut = new long[4];
15249        final int[] SINGLE_LONG_FORMAT = new int[] {
15250            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15251        };
15252        long[] longTmp = new long[1];
15253        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15254                SINGLE_LONG_FORMAT, null, longTmp, null);
15255        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15256        longTmp[0] = 0;
15257        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15258                SINGLE_LONG_FORMAT, null, longTmp, null);
15259        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15260        longTmp[0] = 0;
15261        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15262                SINGLE_LONG_FORMAT, null, longTmp, null);
15263        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15264        longTmp[0] = 0;
15265        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15266                SINGLE_LONG_FORMAT, null, longTmp, null);
15267        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15268        return longOut;
15269    }
15270
15271    private static String stringifySize(long size, int order) {
15272        Locale locale = Locale.US;
15273        switch (order) {
15274            case 1:
15275                return String.format(locale, "%,13d", size);
15276            case 1024:
15277                return String.format(locale, "%,9dK", size / 1024);
15278            case 1024 * 1024:
15279                return String.format(locale, "%,5dM", size / 1024 / 1024);
15280            case 1024 * 1024 * 1024:
15281                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15282            default:
15283                throw new IllegalArgumentException("Invalid size order");
15284        }
15285    }
15286
15287    private static String stringifyKBSize(long size) {
15288        return stringifySize(size * 1024, 1024);
15289    }
15290
15291    // Update this version number in case you change the 'compact' format
15292    private static final int MEMINFO_COMPACT_VERSION = 1;
15293
15294    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15295            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15296        boolean dumpDetails = false;
15297        boolean dumpFullDetails = false;
15298        boolean dumpDalvik = false;
15299        boolean dumpSummaryOnly = false;
15300        boolean dumpUnreachable = false;
15301        boolean oomOnly = false;
15302        boolean isCompact = false;
15303        boolean localOnly = false;
15304        boolean packages = false;
15305        boolean isCheckinRequest = false;
15306        boolean dumpSwapPss = false;
15307
15308        int opti = 0;
15309        while (opti < args.length) {
15310            String opt = args[opti];
15311            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15312                break;
15313            }
15314            opti++;
15315            if ("-a".equals(opt)) {
15316                dumpDetails = true;
15317                dumpFullDetails = true;
15318                dumpDalvik = true;
15319                dumpSwapPss = true;
15320            } else if ("-d".equals(opt)) {
15321                dumpDalvik = true;
15322            } else if ("-c".equals(opt)) {
15323                isCompact = true;
15324            } else if ("-s".equals(opt)) {
15325                dumpDetails = true;
15326                dumpSummaryOnly = true;
15327            } else if ("-S".equals(opt)) {
15328                dumpSwapPss = true;
15329            } else if ("--unreachable".equals(opt)) {
15330                dumpUnreachable = true;
15331            } else if ("--oom".equals(opt)) {
15332                oomOnly = true;
15333            } else if ("--local".equals(opt)) {
15334                localOnly = true;
15335            } else if ("--package".equals(opt)) {
15336                packages = true;
15337            } else if ("--checkin".equals(opt)) {
15338                isCheckinRequest = true;
15339
15340            } else if ("-h".equals(opt)) {
15341                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15342                pw.println("  -a: include all available information for each process.");
15343                pw.println("  -d: include dalvik details.");
15344                pw.println("  -c: dump in a compact machine-parseable representation.");
15345                pw.println("  -s: dump only summary of application memory usage.");
15346                pw.println("  -S: dump also SwapPss.");
15347                pw.println("  --oom: only show processes organized by oom adj.");
15348                pw.println("  --local: only collect details locally, don't call process.");
15349                pw.println("  --package: interpret process arg as package, dumping all");
15350                pw.println("             processes that have loaded that package.");
15351                pw.println("  --checkin: dump data for a checkin");
15352                pw.println("If [process] is specified it can be the name or ");
15353                pw.println("pid of a specific process to dump.");
15354                return;
15355            } else {
15356                pw.println("Unknown argument: " + opt + "; use -h for help");
15357            }
15358        }
15359
15360        long uptime = SystemClock.uptimeMillis();
15361        long realtime = SystemClock.elapsedRealtime();
15362        final long[] tmpLong = new long[1];
15363
15364        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15365        if (procs == null) {
15366            // No Java processes.  Maybe they want to print a native process.
15367            if (args != null && args.length > opti
15368                    && args[opti].charAt(0) != '-') {
15369                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15370                        = new ArrayList<ProcessCpuTracker.Stats>();
15371                updateCpuStatsNow();
15372                int findPid = -1;
15373                try {
15374                    findPid = Integer.parseInt(args[opti]);
15375                } catch (NumberFormatException e) {
15376                }
15377                synchronized (mProcessCpuTracker) {
15378                    final int N = mProcessCpuTracker.countStats();
15379                    for (int i=0; i<N; i++) {
15380                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15381                        if (st.pid == findPid || (st.baseName != null
15382                                && st.baseName.equals(args[opti]))) {
15383                            nativeProcs.add(st);
15384                        }
15385                    }
15386                }
15387                if (nativeProcs.size() > 0) {
15388                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15389                            isCompact);
15390                    Debug.MemoryInfo mi = null;
15391                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15392                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15393                        final int pid = r.pid;
15394                        if (!isCheckinRequest && dumpDetails) {
15395                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15396                        }
15397                        if (mi == null) {
15398                            mi = new Debug.MemoryInfo();
15399                        }
15400                        if (dumpDetails || (!brief && !oomOnly)) {
15401                            Debug.getMemoryInfo(pid, mi);
15402                        } else {
15403                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15404                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15405                        }
15406                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15407                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15408                        if (isCheckinRequest) {
15409                            pw.println();
15410                        }
15411                    }
15412                    return;
15413                }
15414            }
15415            pw.println("No process found for: " + args[opti]);
15416            return;
15417        }
15418
15419        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15420            dumpDetails = true;
15421        }
15422
15423        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15424
15425        String[] innerArgs = new String[args.length-opti];
15426        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15427
15428        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15429        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15430        long nativePss = 0;
15431        long nativeSwapPss = 0;
15432        long dalvikPss = 0;
15433        long dalvikSwapPss = 0;
15434        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15435                EmptyArray.LONG;
15436        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15437                EmptyArray.LONG;
15438        long otherPss = 0;
15439        long otherSwapPss = 0;
15440        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15441        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15442
15443        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15444        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15445        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15446                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15447
15448        long totalPss = 0;
15449        long totalSwapPss = 0;
15450        long cachedPss = 0;
15451        long cachedSwapPss = 0;
15452        boolean hasSwapPss = false;
15453
15454        Debug.MemoryInfo mi = null;
15455        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15456            final ProcessRecord r = procs.get(i);
15457            final IApplicationThread thread;
15458            final int pid;
15459            final int oomAdj;
15460            final boolean hasActivities;
15461            synchronized (this) {
15462                thread = r.thread;
15463                pid = r.pid;
15464                oomAdj = r.getSetAdjWithServices();
15465                hasActivities = r.activities.size() > 0;
15466            }
15467            if (thread != null) {
15468                if (!isCheckinRequest && dumpDetails) {
15469                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15470                }
15471                if (mi == null) {
15472                    mi = new Debug.MemoryInfo();
15473                }
15474                if (dumpDetails || (!brief && !oomOnly)) {
15475                    Debug.getMemoryInfo(pid, mi);
15476                    hasSwapPss = mi.hasSwappedOutPss;
15477                } else {
15478                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15479                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15480                }
15481                if (dumpDetails) {
15482                    if (localOnly) {
15483                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15484                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15485                        if (isCheckinRequest) {
15486                            pw.println();
15487                        }
15488                    } else {
15489                        try {
15490                            pw.flush();
15491                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15492                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15493                        } catch (RemoteException e) {
15494                            if (!isCheckinRequest) {
15495                                pw.println("Got RemoteException!");
15496                                pw.flush();
15497                            }
15498                        }
15499                    }
15500                }
15501
15502                final long myTotalPss = mi.getTotalPss();
15503                final long myTotalUss = mi.getTotalUss();
15504                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15505
15506                synchronized (this) {
15507                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15508                        // Record this for posterity if the process has been stable.
15509                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15510                    }
15511                }
15512
15513                if (!isCheckinRequest && mi != null) {
15514                    totalPss += myTotalPss;
15515                    totalSwapPss += myTotalSwapPss;
15516                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15517                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15518                            myTotalSwapPss, pid, hasActivities);
15519                    procMems.add(pssItem);
15520                    procMemsMap.put(pid, pssItem);
15521
15522                    nativePss += mi.nativePss;
15523                    nativeSwapPss += mi.nativeSwappedOutPss;
15524                    dalvikPss += mi.dalvikPss;
15525                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15526                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15527                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15528                        dalvikSubitemSwapPss[j] +=
15529                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15530                    }
15531                    otherPss += mi.otherPss;
15532                    otherSwapPss += mi.otherSwappedOutPss;
15533                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15534                        long mem = mi.getOtherPss(j);
15535                        miscPss[j] += mem;
15536                        otherPss -= mem;
15537                        mem = mi.getOtherSwappedOutPss(j);
15538                        miscSwapPss[j] += mem;
15539                        otherSwapPss -= mem;
15540                    }
15541
15542                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15543                        cachedPss += myTotalPss;
15544                        cachedSwapPss += myTotalSwapPss;
15545                    }
15546
15547                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15548                        if (oomIndex == (oomPss.length - 1)
15549                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15550                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15551                            oomPss[oomIndex] += myTotalPss;
15552                            oomSwapPss[oomIndex] += myTotalSwapPss;
15553                            if (oomProcs[oomIndex] == null) {
15554                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15555                            }
15556                            oomProcs[oomIndex].add(pssItem);
15557                            break;
15558                        }
15559                    }
15560                }
15561            }
15562        }
15563
15564        long nativeProcTotalPss = 0;
15565
15566        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15567            // If we are showing aggregations, also look for native processes to
15568            // include so that our aggregations are more accurate.
15569            updateCpuStatsNow();
15570            mi = null;
15571            synchronized (mProcessCpuTracker) {
15572                final int N = mProcessCpuTracker.countStats();
15573                for (int i=0; i<N; i++) {
15574                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15575                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15576                        if (mi == null) {
15577                            mi = new Debug.MemoryInfo();
15578                        }
15579                        if (!brief && !oomOnly) {
15580                            Debug.getMemoryInfo(st.pid, mi);
15581                        } else {
15582                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15583                            mi.nativePrivateDirty = (int)tmpLong[0];
15584                        }
15585
15586                        final long myTotalPss = mi.getTotalPss();
15587                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15588                        totalPss += myTotalPss;
15589                        nativeProcTotalPss += myTotalPss;
15590
15591                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15592                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15593                        procMems.add(pssItem);
15594
15595                        nativePss += mi.nativePss;
15596                        nativeSwapPss += mi.nativeSwappedOutPss;
15597                        dalvikPss += mi.dalvikPss;
15598                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15599                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15600                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15601                            dalvikSubitemSwapPss[j] +=
15602                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15603                        }
15604                        otherPss += mi.otherPss;
15605                        otherSwapPss += mi.otherSwappedOutPss;
15606                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15607                            long mem = mi.getOtherPss(j);
15608                            miscPss[j] += mem;
15609                            otherPss -= mem;
15610                            mem = mi.getOtherSwappedOutPss(j);
15611                            miscSwapPss[j] += mem;
15612                            otherSwapPss -= mem;
15613                        }
15614                        oomPss[0] += myTotalPss;
15615                        oomSwapPss[0] += myTotalSwapPss;
15616                        if (oomProcs[0] == null) {
15617                            oomProcs[0] = new ArrayList<MemItem>();
15618                        }
15619                        oomProcs[0].add(pssItem);
15620                    }
15621                }
15622            }
15623
15624            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15625
15626            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15627            final MemItem dalvikItem =
15628                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15629            if (dalvikSubitemPss.length > 0) {
15630                dalvikItem.subitems = new ArrayList<MemItem>();
15631                for (int j=0; j<dalvikSubitemPss.length; j++) {
15632                    final String name = Debug.MemoryInfo.getOtherLabel(
15633                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15634                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15635                                    dalvikSubitemSwapPss[j], j));
15636                }
15637            }
15638            catMems.add(dalvikItem);
15639            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15640            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15641                String label = Debug.MemoryInfo.getOtherLabel(j);
15642                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15643            }
15644
15645            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15646            for (int j=0; j<oomPss.length; j++) {
15647                if (oomPss[j] != 0) {
15648                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15649                            : DUMP_MEM_OOM_LABEL[j];
15650                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15651                            DUMP_MEM_OOM_ADJ[j]);
15652                    item.subitems = oomProcs[j];
15653                    oomMems.add(item);
15654                }
15655            }
15656
15657            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15658            if (!brief && !oomOnly && !isCompact) {
15659                pw.println();
15660                pw.println("Total PSS by process:");
15661                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15662                pw.println();
15663            }
15664            if (!isCompact) {
15665                pw.println("Total PSS by OOM adjustment:");
15666            }
15667            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15668            if (!brief && !oomOnly) {
15669                PrintWriter out = categoryPw != null ? categoryPw : pw;
15670                if (!isCompact) {
15671                    out.println();
15672                    out.println("Total PSS by category:");
15673                }
15674                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15675            }
15676            if (!isCompact) {
15677                pw.println();
15678            }
15679            MemInfoReader memInfo = new MemInfoReader();
15680            memInfo.readMemInfo();
15681            if (nativeProcTotalPss > 0) {
15682                synchronized (this) {
15683                    final long cachedKb = memInfo.getCachedSizeKb();
15684                    final long freeKb = memInfo.getFreeSizeKb();
15685                    final long zramKb = memInfo.getZramTotalSizeKb();
15686                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15687                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15688                            kernelKb*1024, nativeProcTotalPss*1024);
15689                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15690                            nativeProcTotalPss);
15691                }
15692            }
15693            if (!brief) {
15694                if (!isCompact) {
15695                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15696                    pw.print(" (status ");
15697                    switch (mLastMemoryLevel) {
15698                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15699                            pw.println("normal)");
15700                            break;
15701                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15702                            pw.println("moderate)");
15703                            break;
15704                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15705                            pw.println("low)");
15706                            break;
15707                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15708                            pw.println("critical)");
15709                            break;
15710                        default:
15711                            pw.print(mLastMemoryLevel);
15712                            pw.println(")");
15713                            break;
15714                    }
15715                    pw.print(" Free RAM: ");
15716                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15717                            + memInfo.getFreeSizeKb()));
15718                    pw.print(" (");
15719                    pw.print(stringifyKBSize(cachedPss));
15720                    pw.print(" cached pss + ");
15721                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15722                    pw.print(" cached kernel + ");
15723                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15724                    pw.println(" free)");
15725                } else {
15726                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15727                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15728                            + memInfo.getFreeSizeKb()); pw.print(",");
15729                    pw.println(totalPss - cachedPss);
15730                }
15731            }
15732            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15733                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15734                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15735            if (!isCompact) {
15736                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15737                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15738                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15739                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15740                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15741            } else {
15742                pw.print("lostram,"); pw.println(lostRAM);
15743            }
15744            if (!brief) {
15745                if (memInfo.getZramTotalSizeKb() != 0) {
15746                    if (!isCompact) {
15747                        pw.print("     ZRAM: ");
15748                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15749                                pw.print(" physical used for ");
15750                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15751                                        - memInfo.getSwapFreeSizeKb()));
15752                                pw.print(" in swap (");
15753                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15754                                pw.println(" total swap)");
15755                    } else {
15756                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15757                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15758                                pw.println(memInfo.getSwapFreeSizeKb());
15759                    }
15760                }
15761                final long[] ksm = getKsmInfo();
15762                if (!isCompact) {
15763                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15764                            || ksm[KSM_VOLATILE] != 0) {
15765                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15766                                pw.print(" saved from shared ");
15767                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15768                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15769                                pw.print(" unshared; ");
15770                                pw.print(stringifyKBSize(
15771                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15772                    }
15773                    pw.print("   Tuning: ");
15774                    pw.print(ActivityManager.staticGetMemoryClass());
15775                    pw.print(" (large ");
15776                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15777                    pw.print("), oom ");
15778                    pw.print(stringifySize(
15779                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15780                    pw.print(", restore limit ");
15781                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15782                    if (ActivityManager.isLowRamDeviceStatic()) {
15783                        pw.print(" (low-ram)");
15784                    }
15785                    if (ActivityManager.isHighEndGfx()) {
15786                        pw.print(" (high-end-gfx)");
15787                    }
15788                    pw.println();
15789                } else {
15790                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15791                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15792                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15793                    pw.print("tuning,");
15794                    pw.print(ActivityManager.staticGetMemoryClass());
15795                    pw.print(',');
15796                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15797                    pw.print(',');
15798                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15799                    if (ActivityManager.isLowRamDeviceStatic()) {
15800                        pw.print(",low-ram");
15801                    }
15802                    if (ActivityManager.isHighEndGfx()) {
15803                        pw.print(",high-end-gfx");
15804                    }
15805                    pw.println();
15806                }
15807            }
15808        }
15809    }
15810
15811    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15812            long memtrack, String name) {
15813        sb.append("  ");
15814        sb.append(ProcessList.makeOomAdjString(oomAdj));
15815        sb.append(' ');
15816        sb.append(ProcessList.makeProcStateString(procState));
15817        sb.append(' ');
15818        ProcessList.appendRamKb(sb, pss);
15819        sb.append(": ");
15820        sb.append(name);
15821        if (memtrack > 0) {
15822            sb.append(" (");
15823            sb.append(stringifyKBSize(memtrack));
15824            sb.append(" memtrack)");
15825        }
15826    }
15827
15828    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15829        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15830        sb.append(" (pid ");
15831        sb.append(mi.pid);
15832        sb.append(") ");
15833        sb.append(mi.adjType);
15834        sb.append('\n');
15835        if (mi.adjReason != null) {
15836            sb.append("                      ");
15837            sb.append(mi.adjReason);
15838            sb.append('\n');
15839        }
15840    }
15841
15842    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15843        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15844        for (int i=0, N=memInfos.size(); i<N; i++) {
15845            ProcessMemInfo mi = memInfos.get(i);
15846            infoMap.put(mi.pid, mi);
15847        }
15848        updateCpuStatsNow();
15849        long[] memtrackTmp = new long[1];
15850        synchronized (mProcessCpuTracker) {
15851            final int N = mProcessCpuTracker.countStats();
15852            for (int i=0; i<N; i++) {
15853                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15854                if (st.vsize > 0) {
15855                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15856                    if (pss > 0) {
15857                        if (infoMap.indexOfKey(st.pid) < 0) {
15858                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15859                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15860                            mi.pss = pss;
15861                            mi.memtrack = memtrackTmp[0];
15862                            memInfos.add(mi);
15863                        }
15864                    }
15865                }
15866            }
15867        }
15868
15869        long totalPss = 0;
15870        long totalMemtrack = 0;
15871        for (int i=0, N=memInfos.size(); i<N; i++) {
15872            ProcessMemInfo mi = memInfos.get(i);
15873            if (mi.pss == 0) {
15874                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15875                mi.memtrack = memtrackTmp[0];
15876            }
15877            totalPss += mi.pss;
15878            totalMemtrack += mi.memtrack;
15879        }
15880        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15881            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15882                if (lhs.oomAdj != rhs.oomAdj) {
15883                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15884                }
15885                if (lhs.pss != rhs.pss) {
15886                    return lhs.pss < rhs.pss ? 1 : -1;
15887                }
15888                return 0;
15889            }
15890        });
15891
15892        StringBuilder tag = new StringBuilder(128);
15893        StringBuilder stack = new StringBuilder(128);
15894        tag.append("Low on memory -- ");
15895        appendMemBucket(tag, totalPss, "total", false);
15896        appendMemBucket(stack, totalPss, "total", true);
15897
15898        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15899        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15900        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15901
15902        boolean firstLine = true;
15903        int lastOomAdj = Integer.MIN_VALUE;
15904        long extraNativeRam = 0;
15905        long extraNativeMemtrack = 0;
15906        long cachedPss = 0;
15907        for (int i=0, N=memInfos.size(); i<N; i++) {
15908            ProcessMemInfo mi = memInfos.get(i);
15909
15910            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15911                cachedPss += mi.pss;
15912            }
15913
15914            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15915                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15916                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15917                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15918                if (lastOomAdj != mi.oomAdj) {
15919                    lastOomAdj = mi.oomAdj;
15920                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15921                        tag.append(" / ");
15922                    }
15923                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15924                        if (firstLine) {
15925                            stack.append(":");
15926                            firstLine = false;
15927                        }
15928                        stack.append("\n\t at ");
15929                    } else {
15930                        stack.append("$");
15931                    }
15932                } else {
15933                    tag.append(" ");
15934                    stack.append("$");
15935                }
15936                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15937                    appendMemBucket(tag, mi.pss, mi.name, false);
15938                }
15939                appendMemBucket(stack, mi.pss, mi.name, true);
15940                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15941                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15942                    stack.append("(");
15943                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15944                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15945                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15946                            stack.append(":");
15947                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15948                        }
15949                    }
15950                    stack.append(")");
15951                }
15952            }
15953
15954            appendMemInfo(fullNativeBuilder, mi);
15955            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15956                // The short form only has native processes that are >= 512K.
15957                if (mi.pss >= 512) {
15958                    appendMemInfo(shortNativeBuilder, mi);
15959                } else {
15960                    extraNativeRam += mi.pss;
15961                    extraNativeMemtrack += mi.memtrack;
15962                }
15963            } else {
15964                // Short form has all other details, but if we have collected RAM
15965                // from smaller native processes let's dump a summary of that.
15966                if (extraNativeRam > 0) {
15967                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15968                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15969                    shortNativeBuilder.append('\n');
15970                    extraNativeRam = 0;
15971                }
15972                appendMemInfo(fullJavaBuilder, mi);
15973            }
15974        }
15975
15976        fullJavaBuilder.append("           ");
15977        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15978        fullJavaBuilder.append(": TOTAL");
15979        if (totalMemtrack > 0) {
15980            fullJavaBuilder.append(" (");
15981            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15982            fullJavaBuilder.append(" memtrack)");
15983        } else {
15984        }
15985        fullJavaBuilder.append("\n");
15986
15987        MemInfoReader memInfo = new MemInfoReader();
15988        memInfo.readMemInfo();
15989        final long[] infos = memInfo.getRawInfo();
15990
15991        StringBuilder memInfoBuilder = new StringBuilder(1024);
15992        Debug.getMemInfo(infos);
15993        memInfoBuilder.append("  MemInfo: ");
15994        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15995        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15996        memInfoBuilder.append(stringifyKBSize(
15997                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15998        memInfoBuilder.append(stringifyKBSize(
15999                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16000        memInfoBuilder.append(stringifyKBSize(
16001                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16002        memInfoBuilder.append("           ");
16003        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16004        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16005        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16006        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16007        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16008            memInfoBuilder.append("  ZRAM: ");
16009            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16010            memInfoBuilder.append(" RAM, ");
16011            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16012            memInfoBuilder.append(" swap total, ");
16013            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16014            memInfoBuilder.append(" swap free\n");
16015        }
16016        final long[] ksm = getKsmInfo();
16017        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16018                || ksm[KSM_VOLATILE] != 0) {
16019            memInfoBuilder.append("  KSM: ");
16020            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16021            memInfoBuilder.append(" saved from shared ");
16022            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16023            memInfoBuilder.append("\n       ");
16024            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16025            memInfoBuilder.append(" unshared; ");
16026            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16027            memInfoBuilder.append(" volatile\n");
16028        }
16029        memInfoBuilder.append("  Free RAM: ");
16030        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16031                + memInfo.getFreeSizeKb()));
16032        memInfoBuilder.append("\n");
16033        memInfoBuilder.append("  Used RAM: ");
16034        memInfoBuilder.append(stringifyKBSize(
16035                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16036        memInfoBuilder.append("\n");
16037        memInfoBuilder.append("  Lost RAM: ");
16038        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16039                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16040                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16041        memInfoBuilder.append("\n");
16042        Slog.i(TAG, "Low on memory:");
16043        Slog.i(TAG, shortNativeBuilder.toString());
16044        Slog.i(TAG, fullJavaBuilder.toString());
16045        Slog.i(TAG, memInfoBuilder.toString());
16046
16047        StringBuilder dropBuilder = new StringBuilder(1024);
16048        /*
16049        StringWriter oomSw = new StringWriter();
16050        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16051        StringWriter catSw = new StringWriter();
16052        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16053        String[] emptyArgs = new String[] { };
16054        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16055        oomPw.flush();
16056        String oomString = oomSw.toString();
16057        */
16058        dropBuilder.append("Low on memory:");
16059        dropBuilder.append(stack);
16060        dropBuilder.append('\n');
16061        dropBuilder.append(fullNativeBuilder);
16062        dropBuilder.append(fullJavaBuilder);
16063        dropBuilder.append('\n');
16064        dropBuilder.append(memInfoBuilder);
16065        dropBuilder.append('\n');
16066        /*
16067        dropBuilder.append(oomString);
16068        dropBuilder.append('\n');
16069        */
16070        StringWriter catSw = new StringWriter();
16071        synchronized (ActivityManagerService.this) {
16072            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16073            String[] emptyArgs = new String[] { };
16074            catPw.println();
16075            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16076            catPw.println();
16077            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16078                    false, false, null);
16079            catPw.println();
16080            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16081            catPw.flush();
16082        }
16083        dropBuilder.append(catSw.toString());
16084        addErrorToDropBox("lowmem", null, "system_server", null,
16085                null, tag.toString(), dropBuilder.toString(), null, null);
16086        //Slog.i(TAG, "Sent to dropbox:");
16087        //Slog.i(TAG, dropBuilder.toString());
16088        synchronized (ActivityManagerService.this) {
16089            long now = SystemClock.uptimeMillis();
16090            if (mLastMemUsageReportTime < now) {
16091                mLastMemUsageReportTime = now;
16092            }
16093        }
16094    }
16095
16096    /**
16097     * Searches array of arguments for the specified string
16098     * @param args array of argument strings
16099     * @param value value to search for
16100     * @return true if the value is contained in the array
16101     */
16102    private static boolean scanArgs(String[] args, String value) {
16103        if (args != null) {
16104            for (String arg : args) {
16105                if (value.equals(arg)) {
16106                    return true;
16107                }
16108            }
16109        }
16110        return false;
16111    }
16112
16113    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16114            ContentProviderRecord cpr, boolean always) {
16115        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16116
16117        if (!inLaunching || always) {
16118            synchronized (cpr) {
16119                cpr.launchingApp = null;
16120                cpr.notifyAll();
16121            }
16122            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16123            String names[] = cpr.info.authority.split(";");
16124            for (int j = 0; j < names.length; j++) {
16125                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16126            }
16127        }
16128
16129        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16130            ContentProviderConnection conn = cpr.connections.get(i);
16131            if (conn.waiting) {
16132                // If this connection is waiting for the provider, then we don't
16133                // need to mess with its process unless we are always removing
16134                // or for some reason the provider is not currently launching.
16135                if (inLaunching && !always) {
16136                    continue;
16137                }
16138            }
16139            ProcessRecord capp = conn.client;
16140            conn.dead = true;
16141            if (conn.stableCount > 0) {
16142                if (!capp.persistent && capp.thread != null
16143                        && capp.pid != 0
16144                        && capp.pid != MY_PID) {
16145                    capp.kill("depends on provider "
16146                            + cpr.name.flattenToShortString()
16147                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16148                }
16149            } else if (capp.thread != null && conn.provider.provider != null) {
16150                try {
16151                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16152                } catch (RemoteException e) {
16153                }
16154                // In the protocol here, we don't expect the client to correctly
16155                // clean up this connection, we'll just remove it.
16156                cpr.connections.remove(i);
16157                if (conn.client.conProviders.remove(conn)) {
16158                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16159                }
16160            }
16161        }
16162
16163        if (inLaunching && always) {
16164            mLaunchingProviders.remove(cpr);
16165        }
16166        return inLaunching;
16167    }
16168
16169    /**
16170     * Main code for cleaning up a process when it has gone away.  This is
16171     * called both as a result of the process dying, or directly when stopping
16172     * a process when running in single process mode.
16173     *
16174     * @return Returns true if the given process has been restarted, so the
16175     * app that was passed in must remain on the process lists.
16176     */
16177    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16178            boolean restarting, boolean allowRestart, int index) {
16179        if (index >= 0) {
16180            removeLruProcessLocked(app);
16181            ProcessList.remove(app.pid);
16182        }
16183
16184        mProcessesToGc.remove(app);
16185        mPendingPssProcesses.remove(app);
16186
16187        // Dismiss any open dialogs.
16188        if (app.crashDialog != null && !app.forceCrashReport) {
16189            app.crashDialog.dismiss();
16190            app.crashDialog = null;
16191        }
16192        if (app.anrDialog != null) {
16193            app.anrDialog.dismiss();
16194            app.anrDialog = null;
16195        }
16196        if (app.waitDialog != null) {
16197            app.waitDialog.dismiss();
16198            app.waitDialog = null;
16199        }
16200
16201        app.crashing = false;
16202        app.notResponding = false;
16203
16204        app.resetPackageList(mProcessStats);
16205        app.unlinkDeathRecipient();
16206        app.makeInactive(mProcessStats);
16207        app.waitingToKill = null;
16208        app.forcingToForeground = null;
16209        updateProcessForegroundLocked(app, false, false);
16210        app.foregroundActivities = false;
16211        app.hasShownUi = false;
16212        app.treatLikeActivity = false;
16213        app.hasAboveClient = false;
16214        app.hasClientActivities = false;
16215
16216        mServices.killServicesLocked(app, allowRestart);
16217
16218        boolean restart = false;
16219
16220        // Remove published content providers.
16221        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16222            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16223            final boolean always = app.bad || !allowRestart;
16224            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16225            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16226                // We left the provider in the launching list, need to
16227                // restart it.
16228                restart = true;
16229            }
16230
16231            cpr.provider = null;
16232            cpr.proc = null;
16233        }
16234        app.pubProviders.clear();
16235
16236        // Take care of any launching providers waiting for this process.
16237        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16238            restart = true;
16239        }
16240
16241        // Unregister from connected content providers.
16242        if (!app.conProviders.isEmpty()) {
16243            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16244                ContentProviderConnection conn = app.conProviders.get(i);
16245                conn.provider.connections.remove(conn);
16246                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16247                        conn.provider.name);
16248            }
16249            app.conProviders.clear();
16250        }
16251
16252        // At this point there may be remaining entries in mLaunchingProviders
16253        // where we were the only one waiting, so they are no longer of use.
16254        // Look for these and clean up if found.
16255        // XXX Commented out for now.  Trying to figure out a way to reproduce
16256        // the actual situation to identify what is actually going on.
16257        if (false) {
16258            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16259                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16260                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16261                    synchronized (cpr) {
16262                        cpr.launchingApp = null;
16263                        cpr.notifyAll();
16264                    }
16265                }
16266            }
16267        }
16268
16269        skipCurrentReceiverLocked(app);
16270
16271        // Unregister any receivers.
16272        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16273            removeReceiverLocked(app.receivers.valueAt(i));
16274        }
16275        app.receivers.clear();
16276
16277        // If the app is undergoing backup, tell the backup manager about it
16278        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16279            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16280                    + mBackupTarget.appInfo + " died during backup");
16281            try {
16282                IBackupManager bm = IBackupManager.Stub.asInterface(
16283                        ServiceManager.getService(Context.BACKUP_SERVICE));
16284                bm.agentDisconnected(app.info.packageName);
16285            } catch (RemoteException e) {
16286                // can't happen; backup manager is local
16287            }
16288        }
16289
16290        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16291            ProcessChangeItem item = mPendingProcessChanges.get(i);
16292            if (item.pid == app.pid) {
16293                mPendingProcessChanges.remove(i);
16294                mAvailProcessChanges.add(item);
16295            }
16296        }
16297        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16298                null).sendToTarget();
16299
16300        // If the caller is restarting this app, then leave it in its
16301        // current lists and let the caller take care of it.
16302        if (restarting) {
16303            return false;
16304        }
16305
16306        if (!app.persistent || app.isolated) {
16307            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16308                    "Removing non-persistent process during cleanup: " + app);
16309            removeProcessNameLocked(app.processName, app.uid);
16310            if (mHeavyWeightProcess == app) {
16311                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16312                        mHeavyWeightProcess.userId, 0));
16313                mHeavyWeightProcess = null;
16314            }
16315        } else if (!app.removed) {
16316            // This app is persistent, so we need to keep its record around.
16317            // If it is not already on the pending app list, add it there
16318            // and start a new process for it.
16319            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16320                mPersistentStartingProcesses.add(app);
16321                restart = true;
16322            }
16323        }
16324        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16325                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16326        mProcessesOnHold.remove(app);
16327
16328        if (app == mHomeProcess) {
16329            mHomeProcess = null;
16330        }
16331        if (app == mPreviousProcess) {
16332            mPreviousProcess = null;
16333        }
16334
16335        if (restart && !app.isolated) {
16336            // We have components that still need to be running in the
16337            // process, so re-launch it.
16338            if (index < 0) {
16339                ProcessList.remove(app.pid);
16340            }
16341            addProcessNameLocked(app);
16342            startProcessLocked(app, "restart", app.processName);
16343            return true;
16344        } else if (app.pid > 0 && app.pid != MY_PID) {
16345            // Goodbye!
16346            boolean removed;
16347            synchronized (mPidsSelfLocked) {
16348                mPidsSelfLocked.remove(app.pid);
16349                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16350            }
16351            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16352            if (app.isolated) {
16353                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16354            }
16355            app.setPid(0);
16356        }
16357        return false;
16358    }
16359
16360    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16361        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16362            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16363            if (cpr.launchingApp == app) {
16364                return true;
16365            }
16366        }
16367        return false;
16368    }
16369
16370    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16371        // Look through the content providers we are waiting to have launched,
16372        // and if any run in this process then either schedule a restart of
16373        // the process or kill the client waiting for it if this process has
16374        // gone bad.
16375        boolean restart = false;
16376        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16377            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16378            if (cpr.launchingApp == app) {
16379                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16380                    restart = true;
16381                } else {
16382                    removeDyingProviderLocked(app, cpr, true);
16383                }
16384            }
16385        }
16386        return restart;
16387    }
16388
16389    // =========================================================
16390    // SERVICES
16391    // =========================================================
16392
16393    @Override
16394    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16395            int flags) {
16396        enforceNotIsolatedCaller("getServices");
16397        synchronized (this) {
16398            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16399        }
16400    }
16401
16402    @Override
16403    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16404        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16405        synchronized (this) {
16406            return mServices.getRunningServiceControlPanelLocked(name);
16407        }
16408    }
16409
16410    @Override
16411    public ComponentName startService(IApplicationThread caller, Intent service,
16412            String resolvedType, String callingPackage, int userId)
16413            throws TransactionTooLargeException {
16414        enforceNotIsolatedCaller("startService");
16415        // Refuse possible leaked file descriptors
16416        if (service != null && service.hasFileDescriptors() == true) {
16417            throw new IllegalArgumentException("File descriptors passed in Intent");
16418        }
16419
16420        if (callingPackage == null) {
16421            throw new IllegalArgumentException("callingPackage cannot be null");
16422        }
16423
16424        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16425                "startService: " + service + " type=" + resolvedType);
16426        synchronized(this) {
16427            final int callingPid = Binder.getCallingPid();
16428            final int callingUid = Binder.getCallingUid();
16429            final long origId = Binder.clearCallingIdentity();
16430            ComponentName res = mServices.startServiceLocked(caller, service,
16431                    resolvedType, callingPid, callingUid, callingPackage, userId);
16432            Binder.restoreCallingIdentity(origId);
16433            return res;
16434        }
16435    }
16436
16437    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16438            String callingPackage, int userId)
16439            throws TransactionTooLargeException {
16440        synchronized(this) {
16441            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16442                    "startServiceInPackage: " + service + " type=" + resolvedType);
16443            final long origId = Binder.clearCallingIdentity();
16444            ComponentName res = mServices.startServiceLocked(null, service,
16445                    resolvedType, -1, uid, callingPackage, userId);
16446            Binder.restoreCallingIdentity(origId);
16447            return res;
16448        }
16449    }
16450
16451    @Override
16452    public int stopService(IApplicationThread caller, Intent service,
16453            String resolvedType, int userId) {
16454        enforceNotIsolatedCaller("stopService");
16455        // Refuse possible leaked file descriptors
16456        if (service != null && service.hasFileDescriptors() == true) {
16457            throw new IllegalArgumentException("File descriptors passed in Intent");
16458        }
16459
16460        synchronized(this) {
16461            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16462        }
16463    }
16464
16465    @Override
16466    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16467        enforceNotIsolatedCaller("peekService");
16468        // Refuse possible leaked file descriptors
16469        if (service != null && service.hasFileDescriptors() == true) {
16470            throw new IllegalArgumentException("File descriptors passed in Intent");
16471        }
16472
16473        if (callingPackage == null) {
16474            throw new IllegalArgumentException("callingPackage cannot be null");
16475        }
16476
16477        synchronized(this) {
16478            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16479        }
16480    }
16481
16482    @Override
16483    public boolean stopServiceToken(ComponentName className, IBinder token,
16484            int startId) {
16485        synchronized(this) {
16486            return mServices.stopServiceTokenLocked(className, token, startId);
16487        }
16488    }
16489
16490    @Override
16491    public void setServiceForeground(ComponentName className, IBinder token,
16492            int id, Notification notification, int flags) {
16493        synchronized(this) {
16494            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16495        }
16496    }
16497
16498    @Override
16499    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16500            boolean requireFull, String name, String callerPackage) {
16501        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16502                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16503    }
16504
16505    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16506            String className, int flags) {
16507        boolean result = false;
16508        // For apps that don't have pre-defined UIDs, check for permission
16509        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16510            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16511                if (ActivityManager.checkUidPermission(
16512                        INTERACT_ACROSS_USERS,
16513                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16514                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16515                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16516                            + " requests FLAG_SINGLE_USER, but app does not hold "
16517                            + INTERACT_ACROSS_USERS;
16518                    Slog.w(TAG, msg);
16519                    throw new SecurityException(msg);
16520                }
16521                // Permission passed
16522                result = true;
16523            }
16524        } else if ("system".equals(componentProcessName)) {
16525            result = true;
16526        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16527            // Phone app and persistent apps are allowed to export singleuser providers.
16528            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16529                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16530        }
16531        if (DEBUG_MU) Slog.v(TAG_MU,
16532                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16533                + Integer.toHexString(flags) + ") = " + result);
16534        return result;
16535    }
16536
16537    /**
16538     * Checks to see if the caller is in the same app as the singleton
16539     * component, or the component is in a special app. It allows special apps
16540     * to export singleton components but prevents exporting singleton
16541     * components for regular apps.
16542     */
16543    boolean isValidSingletonCall(int callingUid, int componentUid) {
16544        int componentAppId = UserHandle.getAppId(componentUid);
16545        return UserHandle.isSameApp(callingUid, componentUid)
16546                || componentAppId == Process.SYSTEM_UID
16547                || componentAppId == Process.PHONE_UID
16548                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16549                        == PackageManager.PERMISSION_GRANTED;
16550    }
16551
16552    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16553            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16554            int userId) throws TransactionTooLargeException {
16555        enforceNotIsolatedCaller("bindService");
16556
16557        // Refuse possible leaked file descriptors
16558        if (service != null && service.hasFileDescriptors() == true) {
16559            throw new IllegalArgumentException("File descriptors passed in Intent");
16560        }
16561
16562        if (callingPackage == null) {
16563            throw new IllegalArgumentException("callingPackage cannot be null");
16564        }
16565
16566        synchronized(this) {
16567            return mServices.bindServiceLocked(caller, token, service,
16568                    resolvedType, connection, flags, callingPackage, userId);
16569        }
16570    }
16571
16572    public boolean unbindService(IServiceConnection connection) {
16573        synchronized (this) {
16574            return mServices.unbindServiceLocked(connection);
16575        }
16576    }
16577
16578    public void publishService(IBinder token, Intent intent, IBinder service) {
16579        // Refuse possible leaked file descriptors
16580        if (intent != null && intent.hasFileDescriptors() == true) {
16581            throw new IllegalArgumentException("File descriptors passed in Intent");
16582        }
16583
16584        synchronized(this) {
16585            if (!(token instanceof ServiceRecord)) {
16586                throw new IllegalArgumentException("Invalid service token");
16587            }
16588            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16589        }
16590    }
16591
16592    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16593        // Refuse possible leaked file descriptors
16594        if (intent != null && intent.hasFileDescriptors() == true) {
16595            throw new IllegalArgumentException("File descriptors passed in Intent");
16596        }
16597
16598        synchronized(this) {
16599            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16600        }
16601    }
16602
16603    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16604        synchronized(this) {
16605            if (!(token instanceof ServiceRecord)) {
16606                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16607                throw new IllegalArgumentException("Invalid service token");
16608            }
16609            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16610        }
16611    }
16612
16613    // =========================================================
16614    // BACKUP AND RESTORE
16615    // =========================================================
16616
16617    // Cause the target app to be launched if necessary and its backup agent
16618    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16619    // activity manager to announce its creation.
16620    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16621        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16622                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16623        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16624
16625        synchronized(this) {
16626            // !!! TODO: currently no check here that we're already bound
16627            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16628            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16629            synchronized (stats) {
16630                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16631            }
16632
16633            // Backup agent is now in use, its package can't be stopped.
16634            try {
16635                AppGlobals.getPackageManager().setPackageStoppedState(
16636                        app.packageName, false, UserHandle.getUserId(app.uid));
16637            } catch (RemoteException e) {
16638            } catch (IllegalArgumentException e) {
16639                Slog.w(TAG, "Failed trying to unstop package "
16640                        + app.packageName + ": " + e);
16641            }
16642
16643            BackupRecord r = new BackupRecord(ss, app, backupMode);
16644            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16645                    ? new ComponentName(app.packageName, app.backupAgentName)
16646                    : new ComponentName("android", "FullBackupAgent");
16647            // startProcessLocked() returns existing proc's record if it's already running
16648            ProcessRecord proc = startProcessLocked(app.processName, app,
16649                    false, 0, "backup", hostingName, false, false, false);
16650            if (proc == null) {
16651                Slog.e(TAG, "Unable to start backup agent process " + r);
16652                return false;
16653            }
16654
16655            r.app = proc;
16656            mBackupTarget = r;
16657            mBackupAppName = app.packageName;
16658
16659            // Try not to kill the process during backup
16660            updateOomAdjLocked(proc);
16661
16662            // If the process is already attached, schedule the creation of the backup agent now.
16663            // If it is not yet live, this will be done when it attaches to the framework.
16664            if (proc.thread != null) {
16665                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16666                try {
16667                    proc.thread.scheduleCreateBackupAgent(app,
16668                            compatibilityInfoForPackageLocked(app), backupMode);
16669                } catch (RemoteException e) {
16670                    // Will time out on the backup manager side
16671                }
16672            } else {
16673                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16674            }
16675            // Invariants: at this point, the target app process exists and the application
16676            // is either already running or in the process of coming up.  mBackupTarget and
16677            // mBackupAppName describe the app, so that when it binds back to the AM we
16678            // know that it's scheduled for a backup-agent operation.
16679        }
16680
16681        return true;
16682    }
16683
16684    @Override
16685    public void clearPendingBackup() {
16686        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16687        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16688
16689        synchronized (this) {
16690            mBackupTarget = null;
16691            mBackupAppName = null;
16692        }
16693    }
16694
16695    // A backup agent has just come up
16696    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16697        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16698                + " = " + agent);
16699
16700        synchronized(this) {
16701            if (!agentPackageName.equals(mBackupAppName)) {
16702                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16703                return;
16704            }
16705        }
16706
16707        long oldIdent = Binder.clearCallingIdentity();
16708        try {
16709            IBackupManager bm = IBackupManager.Stub.asInterface(
16710                    ServiceManager.getService(Context.BACKUP_SERVICE));
16711            bm.agentConnected(agentPackageName, agent);
16712        } catch (RemoteException e) {
16713            // can't happen; the backup manager service is local
16714        } catch (Exception e) {
16715            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16716            e.printStackTrace();
16717        } finally {
16718            Binder.restoreCallingIdentity(oldIdent);
16719        }
16720    }
16721
16722    // done with this agent
16723    public void unbindBackupAgent(ApplicationInfo appInfo) {
16724        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16725        if (appInfo == null) {
16726            Slog.w(TAG, "unbind backup agent for null app");
16727            return;
16728        }
16729
16730        synchronized(this) {
16731            try {
16732                if (mBackupAppName == null) {
16733                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16734                    return;
16735                }
16736
16737                if (!mBackupAppName.equals(appInfo.packageName)) {
16738                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16739                    return;
16740                }
16741
16742                // Not backing this app up any more; reset its OOM adjustment
16743                final ProcessRecord proc = mBackupTarget.app;
16744                updateOomAdjLocked(proc);
16745
16746                // If the app crashed during backup, 'thread' will be null here
16747                if (proc.thread != null) {
16748                    try {
16749                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16750                                compatibilityInfoForPackageLocked(appInfo));
16751                    } catch (Exception e) {
16752                        Slog.e(TAG, "Exception when unbinding backup agent:");
16753                        e.printStackTrace();
16754                    }
16755                }
16756            } finally {
16757                mBackupTarget = null;
16758                mBackupAppName = null;
16759            }
16760        }
16761    }
16762    // =========================================================
16763    // BROADCASTS
16764    // =========================================================
16765
16766    boolean isPendingBroadcastProcessLocked(int pid) {
16767        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16768                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16769    }
16770
16771    void skipPendingBroadcastLocked(int pid) {
16772            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16773            for (BroadcastQueue queue : mBroadcastQueues) {
16774                queue.skipPendingBroadcastLocked(pid);
16775            }
16776    }
16777
16778    // The app just attached; send any pending broadcasts that it should receive
16779    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16780        boolean didSomething = false;
16781        for (BroadcastQueue queue : mBroadcastQueues) {
16782            didSomething |= queue.sendPendingBroadcastsLocked(app);
16783        }
16784        return didSomething;
16785    }
16786
16787    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16788            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16789        enforceNotIsolatedCaller("registerReceiver");
16790        ArrayList<Intent> stickyIntents = null;
16791        ProcessRecord callerApp = null;
16792        int callingUid;
16793        int callingPid;
16794        synchronized(this) {
16795            if (caller != null) {
16796                callerApp = getRecordForAppLocked(caller);
16797                if (callerApp == null) {
16798                    throw new SecurityException(
16799                            "Unable to find app for caller " + caller
16800                            + " (pid=" + Binder.getCallingPid()
16801                            + ") when registering receiver " + receiver);
16802                }
16803                if (callerApp.info.uid != Process.SYSTEM_UID &&
16804                        !callerApp.pkgList.containsKey(callerPackage) &&
16805                        !"android".equals(callerPackage)) {
16806                    throw new SecurityException("Given caller package " + callerPackage
16807                            + " is not running in process " + callerApp);
16808                }
16809                callingUid = callerApp.info.uid;
16810                callingPid = callerApp.pid;
16811            } else {
16812                callerPackage = null;
16813                callingUid = Binder.getCallingUid();
16814                callingPid = Binder.getCallingPid();
16815            }
16816
16817            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16818                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16819
16820            Iterator<String> actions = filter.actionsIterator();
16821            if (actions == null) {
16822                ArrayList<String> noAction = new ArrayList<String>(1);
16823                noAction.add(null);
16824                actions = noAction.iterator();
16825            }
16826
16827            // Collect stickies of users
16828            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16829            while (actions.hasNext()) {
16830                String action = actions.next();
16831                for (int id : userIds) {
16832                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16833                    if (stickies != null) {
16834                        ArrayList<Intent> intents = stickies.get(action);
16835                        if (intents != null) {
16836                            if (stickyIntents == null) {
16837                                stickyIntents = new ArrayList<Intent>();
16838                            }
16839                            stickyIntents.addAll(intents);
16840                        }
16841                    }
16842                }
16843            }
16844        }
16845
16846        ArrayList<Intent> allSticky = null;
16847        if (stickyIntents != null) {
16848            final ContentResolver resolver = mContext.getContentResolver();
16849            // Look for any matching sticky broadcasts...
16850            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16851                Intent intent = stickyIntents.get(i);
16852                // If intent has scheme "content", it will need to acccess
16853                // provider that needs to lock mProviderMap in ActivityThread
16854                // and also it may need to wait application response, so we
16855                // cannot lock ActivityManagerService here.
16856                if (filter.match(resolver, intent, true, TAG) >= 0) {
16857                    if (allSticky == null) {
16858                        allSticky = new ArrayList<Intent>();
16859                    }
16860                    allSticky.add(intent);
16861                }
16862            }
16863        }
16864
16865        // The first sticky in the list is returned directly back to the client.
16866        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16867        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16868        if (receiver == null) {
16869            return sticky;
16870        }
16871
16872        synchronized (this) {
16873            if (callerApp != null && (callerApp.thread == null
16874                    || callerApp.thread.asBinder() != caller.asBinder())) {
16875                // Original caller already died
16876                return null;
16877            }
16878            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16879            if (rl == null) {
16880                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16881                        userId, receiver);
16882                if (rl.app != null) {
16883                    rl.app.receivers.add(rl);
16884                } else {
16885                    try {
16886                        receiver.asBinder().linkToDeath(rl, 0);
16887                    } catch (RemoteException e) {
16888                        return sticky;
16889                    }
16890                    rl.linkedToDeath = true;
16891                }
16892                mRegisteredReceivers.put(receiver.asBinder(), rl);
16893            } else if (rl.uid != callingUid) {
16894                throw new IllegalArgumentException(
16895                        "Receiver requested to register for uid " + callingUid
16896                        + " was previously registered for uid " + rl.uid);
16897            } else if (rl.pid != callingPid) {
16898                throw new IllegalArgumentException(
16899                        "Receiver requested to register for pid " + callingPid
16900                        + " was previously registered for pid " + rl.pid);
16901            } else if (rl.userId != userId) {
16902                throw new IllegalArgumentException(
16903                        "Receiver requested to register for user " + userId
16904                        + " was previously registered for user " + rl.userId);
16905            }
16906            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16907                    permission, callingUid, userId);
16908            rl.add(bf);
16909            if (!bf.debugCheck()) {
16910                Slog.w(TAG, "==> For Dynamic broadcast");
16911            }
16912            mReceiverResolver.addFilter(bf);
16913
16914            // Enqueue broadcasts for all existing stickies that match
16915            // this filter.
16916            if (allSticky != null) {
16917                ArrayList receivers = new ArrayList();
16918                receivers.add(bf);
16919
16920                final int stickyCount = allSticky.size();
16921                for (int i = 0; i < stickyCount; i++) {
16922                    Intent intent = allSticky.get(i);
16923                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16924                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16925                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16926                            null, 0, null, null, false, true, true, -1);
16927                    queue.enqueueParallelBroadcastLocked(r);
16928                    queue.scheduleBroadcastsLocked();
16929                }
16930            }
16931
16932            return sticky;
16933        }
16934    }
16935
16936    public void unregisterReceiver(IIntentReceiver receiver) {
16937        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16938
16939        final long origId = Binder.clearCallingIdentity();
16940        try {
16941            boolean doTrim = false;
16942
16943            synchronized(this) {
16944                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16945                if (rl != null) {
16946                    final BroadcastRecord r = rl.curBroadcast;
16947                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16948                        final boolean doNext = r.queue.finishReceiverLocked(
16949                                r, r.resultCode, r.resultData, r.resultExtras,
16950                                r.resultAbort, false);
16951                        if (doNext) {
16952                            doTrim = true;
16953                            r.queue.processNextBroadcast(false);
16954                        }
16955                    }
16956
16957                    if (rl.app != null) {
16958                        rl.app.receivers.remove(rl);
16959                    }
16960                    removeReceiverLocked(rl);
16961                    if (rl.linkedToDeath) {
16962                        rl.linkedToDeath = false;
16963                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16964                    }
16965                }
16966            }
16967
16968            // If we actually concluded any broadcasts, we might now be able
16969            // to trim the recipients' apps from our working set
16970            if (doTrim) {
16971                trimApplications();
16972                return;
16973            }
16974
16975        } finally {
16976            Binder.restoreCallingIdentity(origId);
16977        }
16978    }
16979
16980    void removeReceiverLocked(ReceiverList rl) {
16981        mRegisteredReceivers.remove(rl.receiver.asBinder());
16982        for (int i = rl.size() - 1; i >= 0; i--) {
16983            mReceiverResolver.removeFilter(rl.get(i));
16984        }
16985    }
16986
16987    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16988        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16989            ProcessRecord r = mLruProcesses.get(i);
16990            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16991                try {
16992                    r.thread.dispatchPackageBroadcast(cmd, packages);
16993                } catch (RemoteException ex) {
16994                }
16995            }
16996        }
16997    }
16998
16999    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17000            int callingUid, int[] users) {
17001        // TODO: come back and remove this assumption to triage all broadcasts
17002        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17003
17004        List<ResolveInfo> receivers = null;
17005        try {
17006            HashSet<ComponentName> singleUserReceivers = null;
17007            boolean scannedFirstReceivers = false;
17008            for (int user : users) {
17009                // Skip users that have Shell restrictions, with exception of always permitted
17010                // Shell broadcasts
17011                if (callingUid == Process.SHELL_UID
17012                        && mUserController.hasUserRestriction(
17013                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17014                        && !isPermittedShellBroadcast(intent)) {
17015                    continue;
17016                }
17017                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17018                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17019                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17020                    // If this is not the system user, we need to check for
17021                    // any receivers that should be filtered out.
17022                    for (int i=0; i<newReceivers.size(); i++) {
17023                        ResolveInfo ri = newReceivers.get(i);
17024                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17025                            newReceivers.remove(i);
17026                            i--;
17027                        }
17028                    }
17029                }
17030                if (newReceivers != null && newReceivers.size() == 0) {
17031                    newReceivers = null;
17032                }
17033                if (receivers == null) {
17034                    receivers = newReceivers;
17035                } else if (newReceivers != null) {
17036                    // We need to concatenate the additional receivers
17037                    // found with what we have do far.  This would be easy,
17038                    // but we also need to de-dup any receivers that are
17039                    // singleUser.
17040                    if (!scannedFirstReceivers) {
17041                        // Collect any single user receivers we had already retrieved.
17042                        scannedFirstReceivers = true;
17043                        for (int i=0; i<receivers.size(); i++) {
17044                            ResolveInfo ri = receivers.get(i);
17045                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17046                                ComponentName cn = new ComponentName(
17047                                        ri.activityInfo.packageName, ri.activityInfo.name);
17048                                if (singleUserReceivers == null) {
17049                                    singleUserReceivers = new HashSet<ComponentName>();
17050                                }
17051                                singleUserReceivers.add(cn);
17052                            }
17053                        }
17054                    }
17055                    // Add the new results to the existing results, tracking
17056                    // and de-dupping single user receivers.
17057                    for (int i=0; i<newReceivers.size(); i++) {
17058                        ResolveInfo ri = newReceivers.get(i);
17059                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17060                            ComponentName cn = new ComponentName(
17061                                    ri.activityInfo.packageName, ri.activityInfo.name);
17062                            if (singleUserReceivers == null) {
17063                                singleUserReceivers = new HashSet<ComponentName>();
17064                            }
17065                            if (!singleUserReceivers.contains(cn)) {
17066                                singleUserReceivers.add(cn);
17067                                receivers.add(ri);
17068                            }
17069                        } else {
17070                            receivers.add(ri);
17071                        }
17072                    }
17073                }
17074            }
17075        } catch (RemoteException ex) {
17076            // pm is in same process, this will never happen.
17077        }
17078        return receivers;
17079    }
17080
17081    private boolean isPermittedShellBroadcast(Intent intent) {
17082        // remote bugreport should always be allowed to be taken
17083        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17084    }
17085
17086    final int broadcastIntentLocked(ProcessRecord callerApp,
17087            String callerPackage, Intent intent, String resolvedType,
17088            IIntentReceiver resultTo, int resultCode, String resultData,
17089            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17090            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17091        intent = new Intent(intent);
17092
17093        // By default broadcasts do not go to stopped apps.
17094        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17095
17096        // If we have not finished booting, don't allow this to launch new processes.
17097        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17098            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17099        }
17100
17101        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17102                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17103                + " ordered=" + ordered + " userid=" + userId);
17104        if ((resultTo != null) && !ordered) {
17105            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17106        }
17107
17108        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17109                ALLOW_NON_FULL, "broadcast", callerPackage);
17110
17111        // Make sure that the user who is receiving this broadcast is running.
17112        // If not, we will just skip it. Make an exception for shutdown broadcasts
17113        // and upgrade steps.
17114
17115        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17116            if ((callingUid != Process.SYSTEM_UID
17117                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17118                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17119                Slog.w(TAG, "Skipping broadcast of " + intent
17120                        + ": user " + userId + " is stopped");
17121                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17122            }
17123        }
17124
17125        BroadcastOptions brOptions = null;
17126        if (bOptions != null) {
17127            brOptions = new BroadcastOptions(bOptions);
17128            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17129                // See if the caller is allowed to do this.  Note we are checking against
17130                // the actual real caller (not whoever provided the operation as say a
17131                // PendingIntent), because that who is actually supplied the arguments.
17132                if (checkComponentPermission(
17133                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17134                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17135                        != PackageManager.PERMISSION_GRANTED) {
17136                    String msg = "Permission Denial: " + intent.getAction()
17137                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17138                            + ", uid=" + callingUid + ")"
17139                            + " requires "
17140                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17141                    Slog.w(TAG, msg);
17142                    throw new SecurityException(msg);
17143                }
17144            }
17145        }
17146
17147        // Verify that protected broadcasts are only being sent by system code,
17148        // and that system code is only sending protected broadcasts.
17149        final String action = intent.getAction();
17150        final boolean isProtectedBroadcast;
17151        try {
17152            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17153        } catch (RemoteException e) {
17154            Slog.w(TAG, "Remote exception", e);
17155            return ActivityManager.BROADCAST_SUCCESS;
17156        }
17157
17158        final boolean isCallerSystem;
17159        switch (UserHandle.getAppId(callingUid)) {
17160            case Process.ROOT_UID:
17161            case Process.SYSTEM_UID:
17162            case Process.PHONE_UID:
17163            case Process.BLUETOOTH_UID:
17164            case Process.NFC_UID:
17165                isCallerSystem = true;
17166                break;
17167            default:
17168                isCallerSystem = (callerApp != null) && callerApp.persistent;
17169                break;
17170        }
17171
17172        if (isCallerSystem) {
17173            if (isProtectedBroadcast
17174                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17175                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17176                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17177                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17178                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17179                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17180                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17181                // Broadcast is either protected, or it's a public action that
17182                // we've relaxed, so it's fine for system internals to send.
17183            } else {
17184                // The vast majority of broadcasts sent from system internals
17185                // should be protected to avoid security holes, so yell loudly
17186                // to ensure we examine these cases.
17187                Log.wtf(TAG, "Sending non-protected broadcast " + action
17188                        + " from system", new Throwable());
17189            }
17190
17191        } else {
17192            if (isProtectedBroadcast) {
17193                String msg = "Permission Denial: not allowed to send broadcast "
17194                        + action + " from pid="
17195                        + callingPid + ", uid=" + callingUid;
17196                Slog.w(TAG, msg);
17197                throw new SecurityException(msg);
17198
17199            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17200                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17201                // Special case for compatibility: we don't want apps to send this,
17202                // but historically it has not been protected and apps may be using it
17203                // to poke their own app widget.  So, instead of making it protected,
17204                // just limit it to the caller.
17205                if (callerPackage == null) {
17206                    String msg = "Permission Denial: not allowed to send broadcast "
17207                            + action + " from unknown caller.";
17208                    Slog.w(TAG, msg);
17209                    throw new SecurityException(msg);
17210                } else if (intent.getComponent() != null) {
17211                    // They are good enough to send to an explicit component...  verify
17212                    // it is being sent to the calling app.
17213                    if (!intent.getComponent().getPackageName().equals(
17214                            callerPackage)) {
17215                        String msg = "Permission Denial: not allowed to send broadcast "
17216                                + action + " to "
17217                                + intent.getComponent().getPackageName() + " from "
17218                                + callerPackage;
17219                        Slog.w(TAG, msg);
17220                        throw new SecurityException(msg);
17221                    }
17222                } else {
17223                    // Limit broadcast to their own package.
17224                    intent.setPackage(callerPackage);
17225                }
17226            }
17227        }
17228
17229        if (action != null) {
17230            switch (action) {
17231                case Intent.ACTION_UID_REMOVED:
17232                case Intent.ACTION_PACKAGE_REMOVED:
17233                case Intent.ACTION_PACKAGE_CHANGED:
17234                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17235                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17236                case Intent.ACTION_PACKAGES_SUSPENDED:
17237                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17238                    // Handle special intents: if this broadcast is from the package
17239                    // manager about a package being removed, we need to remove all of
17240                    // its activities from the history stack.
17241                    if (checkComponentPermission(
17242                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17243                            callingPid, callingUid, -1, true)
17244                            != PackageManager.PERMISSION_GRANTED) {
17245                        String msg = "Permission Denial: " + intent.getAction()
17246                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17247                                + ", uid=" + callingUid + ")"
17248                                + " requires "
17249                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17250                        Slog.w(TAG, msg);
17251                        throw new SecurityException(msg);
17252                    }
17253                    switch (action) {
17254                        case Intent.ACTION_UID_REMOVED:
17255                            final Bundle intentExtras = intent.getExtras();
17256                            final int uid = intentExtras != null
17257                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17258                            if (uid >= 0) {
17259                                mBatteryStatsService.removeUid(uid);
17260                                mAppOpsService.uidRemoved(uid);
17261                            }
17262                            break;
17263                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17264                            // If resources are unavailable just force stop all those packages
17265                            // and flush the attribute cache as well.
17266                            String list[] =
17267                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17268                            if (list != null && list.length > 0) {
17269                                for (int i = 0; i < list.length; i++) {
17270                                    forceStopPackageLocked(list[i], -1, false, true, true,
17271                                            false, false, userId, "storage unmount");
17272                                }
17273                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17274                                sendPackageBroadcastLocked(
17275                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17276                                        userId);
17277                            }
17278                            break;
17279                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17280                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17281                            break;
17282                        case Intent.ACTION_PACKAGE_REMOVED:
17283                        case Intent.ACTION_PACKAGE_CHANGED:
17284                            Uri data = intent.getData();
17285                            String ssp;
17286                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17287                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17288                                final boolean replacing =
17289                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17290                                final boolean killProcess =
17291                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17292                                final boolean fullUninstall = removed && !replacing;
17293                                if (killProcess) {
17294                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17295                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17296                                            false, true, true, false, fullUninstall, userId,
17297                                            removed ? "pkg removed" : "pkg changed");
17298                                }
17299                                if (removed) {
17300                                    final int cmd = killProcess
17301                                            ? IApplicationThread.PACKAGE_REMOVED
17302                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17303                                    sendPackageBroadcastLocked(cmd,
17304                                            new String[] {ssp}, userId);
17305                                    if (fullUninstall) {
17306                                        mAppOpsService.packageRemoved(
17307                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17308
17309                                        // Remove all permissions granted from/to this package
17310                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17311
17312                                        removeTasksByPackageNameLocked(ssp, userId);
17313                                        mBatteryStatsService.notePackageUninstalled(ssp);
17314                                    }
17315                                } else {
17316                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17317                                            intent.getStringArrayExtra(
17318                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17319                                }
17320                            }
17321                            break;
17322                        case Intent.ACTION_PACKAGES_SUSPENDED:
17323                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17324                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17325                                    intent.getAction());
17326                            final String[] packageNames = intent.getStringArrayExtra(
17327                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17328                            final int userHandle = intent.getIntExtra(
17329                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17330
17331                            synchronized(ActivityManagerService.this) {
17332                                mRecentTasks.onPackagesSuspendedChanged(
17333                                        packageNames, suspended, userHandle);
17334                            }
17335                            break;
17336                    }
17337                    break;
17338                case Intent.ACTION_PACKAGE_REPLACED:
17339                {
17340                    final Uri data = intent.getData();
17341                    final String ssp;
17342                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17343                        final ApplicationInfo aInfo =
17344                                getPackageManagerInternalLocked().getApplicationInfo(
17345                                        ssp,
17346                                        userId);
17347                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17348                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17349                                new String[] {ssp}, userId);
17350                    }
17351                    break;
17352                }
17353                case Intent.ACTION_PACKAGE_ADDED:
17354                {
17355                    // Special case for adding a package: by default turn on compatibility mode.
17356                    Uri data = intent.getData();
17357                    String ssp;
17358                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17359                        final boolean replacing =
17360                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17361                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17362
17363                        try {
17364                            ApplicationInfo ai = AppGlobals.getPackageManager().
17365                                    getApplicationInfo(ssp, 0, 0);
17366                            mBatteryStatsService.notePackageInstalled(ssp,
17367                                    ai != null ? ai.versionCode : 0);
17368                        } catch (RemoteException e) {
17369                        }
17370                    }
17371                    break;
17372                }
17373                case Intent.ACTION_TIMEZONE_CHANGED:
17374                    // If this is the time zone changed action, queue up a message that will reset
17375                    // the timezone of all currently running processes. This message will get
17376                    // queued up before the broadcast happens.
17377                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17378                    break;
17379                case Intent.ACTION_TIME_CHANGED:
17380                    // If the user set the time, let all running processes know.
17381                    final int is24Hour =
17382                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17383                                    : 0;
17384                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17385                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17386                    synchronized (stats) {
17387                        stats.noteCurrentTimeChangedLocked();
17388                    }
17389                    break;
17390                case Intent.ACTION_CLEAR_DNS_CACHE:
17391                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17392                    break;
17393                case Proxy.PROXY_CHANGE_ACTION:
17394                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17395                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17396                    break;
17397                case android.hardware.Camera.ACTION_NEW_PICTURE:
17398                case android.hardware.Camera.ACTION_NEW_VIDEO:
17399                    // These broadcasts are no longer allowed by the system, since they can
17400                    // cause significant thrashing at a crictical point (using the camera).
17401                    // Apps should use JobScehduler to monitor for media provider changes.
17402                    Slog.w(TAG, action + " no longer allowed; dropping from "
17403                            + UserHandle.formatUid(callingUid));
17404                    // Lie; we don't want to crash the app.
17405                    return ActivityManager.BROADCAST_SUCCESS;
17406            }
17407        }
17408
17409        // Add to the sticky list if requested.
17410        if (sticky) {
17411            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17412                    callingPid, callingUid)
17413                    != PackageManager.PERMISSION_GRANTED) {
17414                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17415                        + callingPid + ", uid=" + callingUid
17416                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17417                Slog.w(TAG, msg);
17418                throw new SecurityException(msg);
17419            }
17420            if (requiredPermissions != null && requiredPermissions.length > 0) {
17421                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17422                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17423                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17424            }
17425            if (intent.getComponent() != null) {
17426                throw new SecurityException(
17427                        "Sticky broadcasts can't target a specific component");
17428            }
17429            // We use userId directly here, since the "all" target is maintained
17430            // as a separate set of sticky broadcasts.
17431            if (userId != UserHandle.USER_ALL) {
17432                // But first, if this is not a broadcast to all users, then
17433                // make sure it doesn't conflict with an existing broadcast to
17434                // all users.
17435                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17436                        UserHandle.USER_ALL);
17437                if (stickies != null) {
17438                    ArrayList<Intent> list = stickies.get(intent.getAction());
17439                    if (list != null) {
17440                        int N = list.size();
17441                        int i;
17442                        for (i=0; i<N; i++) {
17443                            if (intent.filterEquals(list.get(i))) {
17444                                throw new IllegalArgumentException(
17445                                        "Sticky broadcast " + intent + " for user "
17446                                        + userId + " conflicts with existing global broadcast");
17447                            }
17448                        }
17449                    }
17450                }
17451            }
17452            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17453            if (stickies == null) {
17454                stickies = new ArrayMap<>();
17455                mStickyBroadcasts.put(userId, stickies);
17456            }
17457            ArrayList<Intent> list = stickies.get(intent.getAction());
17458            if (list == null) {
17459                list = new ArrayList<>();
17460                stickies.put(intent.getAction(), list);
17461            }
17462            final int stickiesCount = list.size();
17463            int i;
17464            for (i = 0; i < stickiesCount; i++) {
17465                if (intent.filterEquals(list.get(i))) {
17466                    // This sticky already exists, replace it.
17467                    list.set(i, new Intent(intent));
17468                    break;
17469                }
17470            }
17471            if (i >= stickiesCount) {
17472                list.add(new Intent(intent));
17473            }
17474        }
17475
17476        int[] users;
17477        if (userId == UserHandle.USER_ALL) {
17478            // Caller wants broadcast to go to all started users.
17479            users = mUserController.getStartedUserArrayLocked();
17480        } else {
17481            // Caller wants broadcast to go to one specific user.
17482            users = new int[] {userId};
17483        }
17484
17485        // Figure out who all will receive this broadcast.
17486        List receivers = null;
17487        List<BroadcastFilter> registeredReceivers = null;
17488        // Need to resolve the intent to interested receivers...
17489        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17490                 == 0) {
17491            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17492        }
17493        if (intent.getComponent() == null) {
17494            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17495                // Query one target user at a time, excluding shell-restricted users
17496                for (int i = 0; i < users.length; i++) {
17497                    if (mUserController.hasUserRestriction(
17498                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17499                        continue;
17500                    }
17501                    List<BroadcastFilter> registeredReceiversForUser =
17502                            mReceiverResolver.queryIntent(intent,
17503                                    resolvedType, false, users[i]);
17504                    if (registeredReceivers == null) {
17505                        registeredReceivers = registeredReceiversForUser;
17506                    } else if (registeredReceiversForUser != null) {
17507                        registeredReceivers.addAll(registeredReceiversForUser);
17508                    }
17509                }
17510            } else {
17511                registeredReceivers = mReceiverResolver.queryIntent(intent,
17512                        resolvedType, false, userId);
17513            }
17514        }
17515
17516        final boolean replacePending =
17517                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17518
17519        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17520                + " replacePending=" + replacePending);
17521
17522        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17523        if (!ordered && NR > 0) {
17524            // If we are not serializing this broadcast, then send the
17525            // registered receivers separately so they don't wait for the
17526            // components to be launched.
17527            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17528            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17529                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17530                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17531                    resultExtras, ordered, sticky, false, userId);
17532            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17533            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17534            if (!replaced) {
17535                queue.enqueueParallelBroadcastLocked(r);
17536                queue.scheduleBroadcastsLocked();
17537            }
17538            registeredReceivers = null;
17539            NR = 0;
17540        }
17541
17542        // Merge into one list.
17543        int ir = 0;
17544        if (receivers != null) {
17545            // A special case for PACKAGE_ADDED: do not allow the package
17546            // being added to see this broadcast.  This prevents them from
17547            // using this as a back door to get run as soon as they are
17548            // installed.  Maybe in the future we want to have a special install
17549            // broadcast or such for apps, but we'd like to deliberately make
17550            // this decision.
17551            String skipPackages[] = null;
17552            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17553                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17554                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17555                Uri data = intent.getData();
17556                if (data != null) {
17557                    String pkgName = data.getSchemeSpecificPart();
17558                    if (pkgName != null) {
17559                        skipPackages = new String[] { pkgName };
17560                    }
17561                }
17562            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17563                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17564            }
17565            if (skipPackages != null && (skipPackages.length > 0)) {
17566                for (String skipPackage : skipPackages) {
17567                    if (skipPackage != null) {
17568                        int NT = receivers.size();
17569                        for (int it=0; it<NT; it++) {
17570                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17571                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17572                                receivers.remove(it);
17573                                it--;
17574                                NT--;
17575                            }
17576                        }
17577                    }
17578                }
17579            }
17580
17581            int NT = receivers != null ? receivers.size() : 0;
17582            int it = 0;
17583            ResolveInfo curt = null;
17584            BroadcastFilter curr = null;
17585            while (it < NT && ir < NR) {
17586                if (curt == null) {
17587                    curt = (ResolveInfo)receivers.get(it);
17588                }
17589                if (curr == null) {
17590                    curr = registeredReceivers.get(ir);
17591                }
17592                if (curr.getPriority() >= curt.priority) {
17593                    // Insert this broadcast record into the final list.
17594                    receivers.add(it, curr);
17595                    ir++;
17596                    curr = null;
17597                    it++;
17598                    NT++;
17599                } else {
17600                    // Skip to the next ResolveInfo in the final list.
17601                    it++;
17602                    curt = null;
17603                }
17604            }
17605        }
17606        while (ir < NR) {
17607            if (receivers == null) {
17608                receivers = new ArrayList();
17609            }
17610            receivers.add(registeredReceivers.get(ir));
17611            ir++;
17612        }
17613
17614        if ((receivers != null && receivers.size() > 0)
17615                || resultTo != null) {
17616            BroadcastQueue queue = broadcastQueueForIntent(intent);
17617            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17618                    callerPackage, callingPid, callingUid, resolvedType,
17619                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17620                    resultData, resultExtras, ordered, sticky, false, userId);
17621
17622            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17623                    + ": prev had " + queue.mOrderedBroadcasts.size());
17624            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17625                    "Enqueueing broadcast " + r.intent.getAction());
17626
17627            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17628            if (!replaced) {
17629                queue.enqueueOrderedBroadcastLocked(r);
17630                queue.scheduleBroadcastsLocked();
17631            }
17632        }
17633
17634        return ActivityManager.BROADCAST_SUCCESS;
17635    }
17636
17637    final Intent verifyBroadcastLocked(Intent intent) {
17638        // Refuse possible leaked file descriptors
17639        if (intent != null && intent.hasFileDescriptors() == true) {
17640            throw new IllegalArgumentException("File descriptors passed in Intent");
17641        }
17642
17643        int flags = intent.getFlags();
17644
17645        if (!mProcessesReady) {
17646            // if the caller really truly claims to know what they're doing, go
17647            // ahead and allow the broadcast without launching any receivers
17648            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17649                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17650            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17651                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17652                        + " before boot completion");
17653                throw new IllegalStateException("Cannot broadcast before boot completed");
17654            }
17655        }
17656
17657        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17658            throw new IllegalArgumentException(
17659                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17660        }
17661
17662        return intent;
17663    }
17664
17665    public final int broadcastIntent(IApplicationThread caller,
17666            Intent intent, String resolvedType, IIntentReceiver resultTo,
17667            int resultCode, String resultData, Bundle resultExtras,
17668            String[] requiredPermissions, int appOp, Bundle bOptions,
17669            boolean serialized, boolean sticky, int userId) {
17670        enforceNotIsolatedCaller("broadcastIntent");
17671        synchronized(this) {
17672            intent = verifyBroadcastLocked(intent);
17673
17674            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17675            final int callingPid = Binder.getCallingPid();
17676            final int callingUid = Binder.getCallingUid();
17677            final long origId = Binder.clearCallingIdentity();
17678            int res = broadcastIntentLocked(callerApp,
17679                    callerApp != null ? callerApp.info.packageName : null,
17680                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17681                    requiredPermissions, appOp, bOptions, serialized, sticky,
17682                    callingPid, callingUid, userId);
17683            Binder.restoreCallingIdentity(origId);
17684            return res;
17685        }
17686    }
17687
17688
17689    int broadcastIntentInPackage(String packageName, int uid,
17690            Intent intent, String resolvedType, IIntentReceiver resultTo,
17691            int resultCode, String resultData, Bundle resultExtras,
17692            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17693            int userId) {
17694        synchronized(this) {
17695            intent = verifyBroadcastLocked(intent);
17696
17697            final long origId = Binder.clearCallingIdentity();
17698            String[] requiredPermissions = requiredPermission == null ? null
17699                    : new String[] {requiredPermission};
17700            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17701                    resultTo, resultCode, resultData, resultExtras,
17702                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17703                    sticky, -1, uid, userId);
17704            Binder.restoreCallingIdentity(origId);
17705            return res;
17706        }
17707    }
17708
17709    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17710        // Refuse possible leaked file descriptors
17711        if (intent != null && intent.hasFileDescriptors() == true) {
17712            throw new IllegalArgumentException("File descriptors passed in Intent");
17713        }
17714
17715        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17716                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17717
17718        synchronized(this) {
17719            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17720                    != PackageManager.PERMISSION_GRANTED) {
17721                String msg = "Permission Denial: unbroadcastIntent() from pid="
17722                        + Binder.getCallingPid()
17723                        + ", uid=" + Binder.getCallingUid()
17724                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17725                Slog.w(TAG, msg);
17726                throw new SecurityException(msg);
17727            }
17728            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17729            if (stickies != null) {
17730                ArrayList<Intent> list = stickies.get(intent.getAction());
17731                if (list != null) {
17732                    int N = list.size();
17733                    int i;
17734                    for (i=0; i<N; i++) {
17735                        if (intent.filterEquals(list.get(i))) {
17736                            list.remove(i);
17737                            break;
17738                        }
17739                    }
17740                    if (list.size() <= 0) {
17741                        stickies.remove(intent.getAction());
17742                    }
17743                }
17744                if (stickies.size() <= 0) {
17745                    mStickyBroadcasts.remove(userId);
17746                }
17747            }
17748        }
17749    }
17750
17751    void backgroundServicesFinishedLocked(int userId) {
17752        for (BroadcastQueue queue : mBroadcastQueues) {
17753            queue.backgroundServicesFinishedLocked(userId);
17754        }
17755    }
17756
17757    public void finishReceiver(IBinder who, int resultCode, String resultData,
17758            Bundle resultExtras, boolean resultAbort, int flags) {
17759        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17760
17761        // Refuse possible leaked file descriptors
17762        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17763            throw new IllegalArgumentException("File descriptors passed in Bundle");
17764        }
17765
17766        final long origId = Binder.clearCallingIdentity();
17767        try {
17768            boolean doNext = false;
17769            BroadcastRecord r;
17770
17771            synchronized(this) {
17772                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17773                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17774                r = queue.getMatchingOrderedReceiver(who);
17775                if (r != null) {
17776                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17777                        resultData, resultExtras, resultAbort, true);
17778                }
17779            }
17780
17781            if (doNext) {
17782                r.queue.processNextBroadcast(false);
17783            }
17784            trimApplications();
17785        } finally {
17786            Binder.restoreCallingIdentity(origId);
17787        }
17788    }
17789
17790    // =========================================================
17791    // INSTRUMENTATION
17792    // =========================================================
17793
17794    public boolean startInstrumentation(ComponentName className,
17795            String profileFile, int flags, Bundle arguments,
17796            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17797            int userId, String abiOverride) {
17798        enforceNotIsolatedCaller("startInstrumentation");
17799        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17800                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17801        // Refuse possible leaked file descriptors
17802        if (arguments != null && arguments.hasFileDescriptors()) {
17803            throw new IllegalArgumentException("File descriptors passed in Bundle");
17804        }
17805
17806        synchronized(this) {
17807            InstrumentationInfo ii = null;
17808            ApplicationInfo ai = null;
17809            try {
17810                ii = mContext.getPackageManager().getInstrumentationInfo(
17811                    className, STOCK_PM_FLAGS);
17812                ai = AppGlobals.getPackageManager().getApplicationInfo(
17813                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17814            } catch (PackageManager.NameNotFoundException e) {
17815            } catch (RemoteException e) {
17816            }
17817            if (ii == null) {
17818                reportStartInstrumentationFailureLocked(watcher, className,
17819                        "Unable to find instrumentation info for: " + className);
17820                return false;
17821            }
17822            if (ai == null) {
17823                reportStartInstrumentationFailureLocked(watcher, className,
17824                        "Unable to find instrumentation target package: " + ii.targetPackage);
17825                return false;
17826            }
17827            if (!ai.hasCode()) {
17828                reportStartInstrumentationFailureLocked(watcher, className,
17829                        "Instrumentation target has no code: " + ii.targetPackage);
17830                return false;
17831            }
17832
17833            int match = mContext.getPackageManager().checkSignatures(
17834                    ii.targetPackage, ii.packageName);
17835            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17836                String msg = "Permission Denial: starting instrumentation "
17837                        + className + " from pid="
17838                        + Binder.getCallingPid()
17839                        + ", uid=" + Binder.getCallingPid()
17840                        + " not allowed because package " + ii.packageName
17841                        + " does not have a signature matching the target "
17842                        + ii.targetPackage;
17843                reportStartInstrumentationFailureLocked(watcher, className, msg);
17844                throw new SecurityException(msg);
17845            }
17846
17847            final long origId = Binder.clearCallingIdentity();
17848            // Instrumentation can kill and relaunch even persistent processes
17849            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17850                    "start instr");
17851            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17852            app.instrumentationClass = className;
17853            app.instrumentationInfo = ai;
17854            app.instrumentationProfileFile = profileFile;
17855            app.instrumentationArguments = arguments;
17856            app.instrumentationWatcher = watcher;
17857            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17858            app.instrumentationResultClass = className;
17859            Binder.restoreCallingIdentity(origId);
17860        }
17861
17862        return true;
17863    }
17864
17865    /**
17866     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17867     * error to the logs, but if somebody is watching, send the report there too.  This enables
17868     * the "am" command to report errors with more information.
17869     *
17870     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17871     * @param cn The component name of the instrumentation.
17872     * @param report The error report.
17873     */
17874    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17875            ComponentName cn, String report) {
17876        Slog.w(TAG, report);
17877        if (watcher != null) {
17878            Bundle results = new Bundle();
17879            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17880            results.putString("Error", report);
17881            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17882        }
17883    }
17884
17885    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17886        if (app.instrumentationWatcher != null) {
17887            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17888                    app.instrumentationClass, resultCode, results);
17889        }
17890
17891        // Can't call out of the system process with a lock held, so post a message.
17892        if (app.instrumentationUiAutomationConnection != null) {
17893            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17894                    app.instrumentationUiAutomationConnection).sendToTarget();
17895        }
17896
17897        app.instrumentationWatcher = null;
17898        app.instrumentationUiAutomationConnection = null;
17899        app.instrumentationClass = null;
17900        app.instrumentationInfo = null;
17901        app.instrumentationProfileFile = null;
17902        app.instrumentationArguments = null;
17903
17904        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17905                "finished inst");
17906    }
17907
17908    public void finishInstrumentation(IApplicationThread target,
17909            int resultCode, Bundle results) {
17910        int userId = UserHandle.getCallingUserId();
17911        // Refuse possible leaked file descriptors
17912        if (results != null && results.hasFileDescriptors()) {
17913            throw new IllegalArgumentException("File descriptors passed in Intent");
17914        }
17915
17916        synchronized(this) {
17917            ProcessRecord app = getRecordForAppLocked(target);
17918            if (app == null) {
17919                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17920                return;
17921            }
17922            final long origId = Binder.clearCallingIdentity();
17923            finishInstrumentationLocked(app, resultCode, results);
17924            Binder.restoreCallingIdentity(origId);
17925        }
17926    }
17927
17928    // =========================================================
17929    // CONFIGURATION
17930    // =========================================================
17931
17932    public ConfigurationInfo getDeviceConfigurationInfo() {
17933        ConfigurationInfo config = new ConfigurationInfo();
17934        synchronized (this) {
17935            config.reqTouchScreen = mConfiguration.touchscreen;
17936            config.reqKeyboardType = mConfiguration.keyboard;
17937            config.reqNavigation = mConfiguration.navigation;
17938            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17939                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17940                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17941            }
17942            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17943                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17944                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17945            }
17946            config.reqGlEsVersion = GL_ES_VERSION;
17947        }
17948        return config;
17949    }
17950
17951    ActivityStack getFocusedStack() {
17952        return mStackSupervisor.getFocusedStack();
17953    }
17954
17955    @Override
17956    public int getFocusedStackId() throws RemoteException {
17957        ActivityStack focusedStack = getFocusedStack();
17958        if (focusedStack != null) {
17959            return focusedStack.getStackId();
17960        }
17961        return -1;
17962    }
17963
17964    public Configuration getConfiguration() {
17965        Configuration ci;
17966        synchronized(this) {
17967            ci = new Configuration(mConfiguration);
17968            ci.userSetLocale = false;
17969        }
17970        return ci;
17971    }
17972
17973    @Override
17974    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17975        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17976        synchronized (this) {
17977            mSuppressResizeConfigChanges = suppress;
17978        }
17979    }
17980
17981    @Override
17982    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17983        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17984        if (fromStackId == HOME_STACK_ID) {
17985            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17986        }
17987        synchronized (this) {
17988            final long origId = Binder.clearCallingIdentity();
17989            try {
17990                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17991            } finally {
17992                Binder.restoreCallingIdentity(origId);
17993            }
17994        }
17995    }
17996
17997    @Override
17998    public void updatePersistentConfiguration(Configuration values) {
17999        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18000                "updateConfiguration()");
18001        enforceWriteSettingsPermission("updateConfiguration()");
18002        if (values == null) {
18003            throw new NullPointerException("Configuration must not be null");
18004        }
18005
18006        int userId = UserHandle.getCallingUserId();
18007
18008        synchronized(this) {
18009            final long origId = Binder.clearCallingIdentity();
18010            updateConfigurationLocked(values, null, false, true, userId);
18011            Binder.restoreCallingIdentity(origId);
18012        }
18013    }
18014
18015    private void updateFontScaleIfNeeded() {
18016        final int currentUserId;
18017        synchronized(this) {
18018            currentUserId = mUserController.getCurrentUserIdLocked();
18019        }
18020        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18021                FONT_SCALE, 1.0f, currentUserId);
18022        if (mConfiguration.fontScale != scaleFactor) {
18023            final Configuration configuration = mWindowManager.computeNewConfiguration();
18024            configuration.fontScale = scaleFactor;
18025            updatePersistentConfiguration(configuration);
18026        }
18027    }
18028
18029    private void enforceWriteSettingsPermission(String func) {
18030        int uid = Binder.getCallingUid();
18031        if (uid == Process.ROOT_UID) {
18032            return;
18033        }
18034
18035        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18036                Settings.getPackageNameForUid(mContext, uid), false)) {
18037            return;
18038        }
18039
18040        String msg = "Permission Denial: " + func + " from pid="
18041                + Binder.getCallingPid()
18042                + ", uid=" + uid
18043                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18044        Slog.w(TAG, msg);
18045        throw new SecurityException(msg);
18046    }
18047
18048    public void updateConfiguration(Configuration values) {
18049        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18050                "updateConfiguration()");
18051
18052        synchronized(this) {
18053            if (values == null && mWindowManager != null) {
18054                // sentinel: fetch the current configuration from the window manager
18055                values = mWindowManager.computeNewConfiguration();
18056            }
18057
18058            if (mWindowManager != null) {
18059                mProcessList.applyDisplaySize(mWindowManager);
18060            }
18061
18062            final long origId = Binder.clearCallingIdentity();
18063            if (values != null) {
18064                Settings.System.clearConfiguration(values);
18065            }
18066            updateConfigurationLocked(values, null, false);
18067            Binder.restoreCallingIdentity(origId);
18068        }
18069    }
18070
18071    void updateUserConfigurationLocked() {
18072        Configuration configuration = new Configuration(mConfiguration);
18073        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18074                mUserController.getCurrentUserIdLocked());
18075        updateConfigurationLocked(configuration, null, false);
18076    }
18077
18078    boolean updateConfigurationLocked(Configuration values,
18079            ActivityRecord starting, boolean initLocale) {
18080        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18081        return updateConfigurationLocked(values, starting, initLocale, false,
18082                UserHandle.USER_NULL);
18083    }
18084
18085    // To cache the list of supported system locales
18086    private String[] mSupportedSystemLocales = null;
18087
18088    /**
18089     * Do either or both things: (1) change the current configuration, and (2)
18090     * make sure the given activity is running with the (now) current
18091     * configuration.  Returns true if the activity has been left running, or
18092     * false if <var>starting</var> is being destroyed to match the new
18093     * configuration.
18094     *
18095     * @param userId is only used when persistent parameter is set to true to persist configuration
18096     *               for that particular user
18097     */
18098    private boolean updateConfigurationLocked(Configuration values,
18099            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18100        int changes = 0;
18101
18102        if (mWindowManager != null) {
18103            mWindowManager.deferSurfaceLayout();
18104        }
18105        if (values != null) {
18106            Configuration newConfig = new Configuration(mConfiguration);
18107            changes = newConfig.updateFrom(values);
18108            if (changes != 0) {
18109                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18110                        "Updating configuration to: " + values);
18111
18112                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18113
18114                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18115                    final Locale locale;
18116                    if (values.getLocales().size() == 1) {
18117                        // This is an optimization to avoid the JNI call when the result of
18118                        // getFirstMatch() does not depend on the supported locales.
18119                        locale = values.getLocales().get(0);
18120                    } else {
18121                        if (mSupportedSystemLocales == null) {
18122                            mSupportedSystemLocales =
18123                                    Resources.getSystem().getAssets().getLocales();
18124                        }
18125                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18126                    }
18127                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18128                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18129                            locale));
18130                }
18131
18132                mConfigurationSeq++;
18133                if (mConfigurationSeq <= 0) {
18134                    mConfigurationSeq = 1;
18135                }
18136                newConfig.seq = mConfigurationSeq;
18137                mConfiguration = newConfig;
18138                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18139                mUsageStatsService.reportConfigurationChange(newConfig,
18140                        mUserController.getCurrentUserIdLocked());
18141                //mUsageStatsService.noteStartConfig(newConfig);
18142
18143                final Configuration configCopy = new Configuration(mConfiguration);
18144
18145                // TODO: If our config changes, should we auto dismiss any currently
18146                // showing dialogs?
18147                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18148
18149                AttributeCache ac = AttributeCache.instance();
18150                if (ac != null) {
18151                    ac.updateConfiguration(configCopy);
18152                }
18153
18154                // Make sure all resources in our process are updated
18155                // right now, so that anyone who is going to retrieve
18156                // resource values after we return will be sure to get
18157                // the new ones.  This is especially important during
18158                // boot, where the first config change needs to guarantee
18159                // all resources have that config before following boot
18160                // code is executed.
18161                mSystemThread.applyConfigurationToResources(configCopy);
18162
18163                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18164                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18165                    msg.obj = new Configuration(configCopy);
18166                    msg.arg1 = userId;
18167                    mHandler.sendMessage(msg);
18168                }
18169
18170                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18171                if (isDensityChange) {
18172                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18173                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18174                }
18175
18176                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18177                    ProcessRecord app = mLruProcesses.get(i);
18178                    try {
18179                        if (app.thread != null) {
18180                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18181                                    + app.processName + " new config " + mConfiguration);
18182                            app.thread.scheduleConfigurationChanged(configCopy);
18183                        }
18184                    } catch (Exception e) {
18185                    }
18186                }
18187                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18188                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18189                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18190                        | Intent.FLAG_RECEIVER_FOREGROUND);
18191                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18192                        null, AppOpsManager.OP_NONE, null, false, false,
18193                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18194                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18195                    // Tell the shortcut manager that the system locale changed.  It needs to know
18196                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18197                    // we "push" from here, rather than having the service listen to the broadcast.
18198                    LocalServices.getService(ShortcutServiceInternal.class)
18199                            .onSystemLocaleChangedNoLock();
18200
18201                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18202                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18203                    if (!mProcessesReady) {
18204                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18205                    }
18206                    broadcastIntentLocked(null, null, intent,
18207                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18208                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18209                }
18210            }
18211            // Update the configuration with WM first and check if any of the stacks need to be
18212            // resized due to the configuration change. If so, resize the stacks now and do any
18213            // relaunches if necessary. This way we don't need to relaunch again below in
18214            // ensureActivityConfigurationLocked().
18215            if (mWindowManager != null) {
18216                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18217                if (resizedStacks != null) {
18218                    for (int stackId : resizedStacks) {
18219                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18220                        mStackSupervisor.resizeStackLocked(
18221                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18222                    }
18223                }
18224            }
18225        }
18226
18227        boolean kept = true;
18228        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18229        // mainStack is null during startup.
18230        if (mainStack != null) {
18231            if (changes != 0 && starting == null) {
18232                // If the configuration changed, and the caller is not already
18233                // in the process of starting an activity, then find the top
18234                // activity to check if its configuration needs to change.
18235                starting = mainStack.topRunningActivityLocked();
18236            }
18237
18238            if (starting != null) {
18239                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18240                // And we need to make sure at this point that all other activities
18241                // are made visible with the correct configuration.
18242                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18243                        !PRESERVE_WINDOWS);
18244            }
18245        }
18246        if (mWindowManager != null) {
18247            mWindowManager.continueSurfaceLayout();
18248        }
18249        return kept;
18250    }
18251
18252    /**
18253     * Decide based on the configuration whether we should shouw the ANR,
18254     * crash, etc dialogs.  The idea is that if there is no affordnace to
18255     * press the on-screen buttons, we shouldn't show the dialog.
18256     *
18257     * A thought: SystemUI might also want to get told about this, the Power
18258     * dialog / global actions also might want different behaviors.
18259     */
18260    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18261        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18262                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18263                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18264        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18265                                    == Configuration.UI_MODE_TYPE_CAR);
18266        return inputMethodExists && uiIsNotCarType && !inVrMode;
18267    }
18268
18269    @Override
18270    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18271        synchronized (this) {
18272            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18273            if (srec != null) {
18274                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18275            }
18276        }
18277        return false;
18278    }
18279
18280    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18281            Intent resultData) {
18282
18283        synchronized (this) {
18284            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18285            if (r != null) {
18286                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18287            }
18288            return false;
18289        }
18290    }
18291
18292    public int getLaunchedFromUid(IBinder activityToken) {
18293        ActivityRecord srec;
18294        synchronized (this) {
18295            srec = ActivityRecord.forTokenLocked(activityToken);
18296        }
18297        if (srec == null) {
18298            return -1;
18299        }
18300        return srec.launchedFromUid;
18301    }
18302
18303    public String getLaunchedFromPackage(IBinder activityToken) {
18304        ActivityRecord srec;
18305        synchronized (this) {
18306            srec = ActivityRecord.forTokenLocked(activityToken);
18307        }
18308        if (srec == null) {
18309            return null;
18310        }
18311        return srec.launchedFromPackage;
18312    }
18313
18314    // =========================================================
18315    // LIFETIME MANAGEMENT
18316    // =========================================================
18317
18318    // Returns which broadcast queue the app is the current [or imminent] receiver
18319    // on, or 'null' if the app is not an active broadcast recipient.
18320    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18321        BroadcastRecord r = app.curReceiver;
18322        if (r != null) {
18323            return r.queue;
18324        }
18325
18326        // It's not the current receiver, but it might be starting up to become one
18327        synchronized (this) {
18328            for (BroadcastQueue queue : mBroadcastQueues) {
18329                r = queue.mPendingBroadcast;
18330                if (r != null && r.curApp == app) {
18331                    // found it; report which queue it's in
18332                    return queue;
18333                }
18334            }
18335        }
18336
18337        return null;
18338    }
18339
18340    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18341            int targetUid, ComponentName targetComponent, String targetProcess) {
18342        if (!mTrackingAssociations) {
18343            return null;
18344        }
18345        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18346                = mAssociations.get(targetUid);
18347        if (components == null) {
18348            components = new ArrayMap<>();
18349            mAssociations.put(targetUid, components);
18350        }
18351        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18352        if (sourceUids == null) {
18353            sourceUids = new SparseArray<>();
18354            components.put(targetComponent, sourceUids);
18355        }
18356        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18357        if (sourceProcesses == null) {
18358            sourceProcesses = new ArrayMap<>();
18359            sourceUids.put(sourceUid, sourceProcesses);
18360        }
18361        Association ass = sourceProcesses.get(sourceProcess);
18362        if (ass == null) {
18363            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18364                    targetProcess);
18365            sourceProcesses.put(sourceProcess, ass);
18366        }
18367        ass.mCount++;
18368        ass.mNesting++;
18369        if (ass.mNesting == 1) {
18370            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18371            ass.mLastState = sourceState;
18372        }
18373        return ass;
18374    }
18375
18376    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18377            ComponentName targetComponent) {
18378        if (!mTrackingAssociations) {
18379            return;
18380        }
18381        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18382                = mAssociations.get(targetUid);
18383        if (components == null) {
18384            return;
18385        }
18386        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18387        if (sourceUids == null) {
18388            return;
18389        }
18390        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18391        if (sourceProcesses == null) {
18392            return;
18393        }
18394        Association ass = sourceProcesses.get(sourceProcess);
18395        if (ass == null || ass.mNesting <= 0) {
18396            return;
18397        }
18398        ass.mNesting--;
18399        if (ass.mNesting == 0) {
18400            long uptime = SystemClock.uptimeMillis();
18401            ass.mTime += uptime - ass.mStartTime;
18402            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18403                    += uptime - ass.mLastStateUptime;
18404            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18405        }
18406    }
18407
18408    private void noteUidProcessState(final int uid, final int state) {
18409        mBatteryStatsService.noteUidProcessState(uid, state);
18410        if (mTrackingAssociations) {
18411            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18412                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18413                        = mAssociations.valueAt(i1);
18414                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18415                    SparseArray<ArrayMap<String, Association>> sourceUids
18416                            = targetComponents.valueAt(i2);
18417                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18418                    if (sourceProcesses != null) {
18419                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18420                            Association ass = sourceProcesses.valueAt(i4);
18421                            if (ass.mNesting >= 1) {
18422                                // currently associated
18423                                long uptime = SystemClock.uptimeMillis();
18424                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18425                                        += uptime - ass.mLastStateUptime;
18426                                ass.mLastState = state;
18427                                ass.mLastStateUptime = uptime;
18428                            }
18429                        }
18430                    }
18431                }
18432            }
18433        }
18434    }
18435
18436    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18437            boolean doingAll, long now) {
18438        if (mAdjSeq == app.adjSeq) {
18439            // This adjustment has already been computed.
18440            return app.curRawAdj;
18441        }
18442
18443        if (app.thread == null) {
18444            app.adjSeq = mAdjSeq;
18445            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18446            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18447            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18448        }
18449
18450        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18451        app.adjSource = null;
18452        app.adjTarget = null;
18453        app.empty = false;
18454        app.cached = false;
18455
18456        final int activitiesSize = app.activities.size();
18457
18458        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18459            // The max adjustment doesn't allow this app to be anything
18460            // below foreground, so it is not worth doing work for it.
18461            app.adjType = "fixed";
18462            app.adjSeq = mAdjSeq;
18463            app.curRawAdj = app.maxAdj;
18464            app.foregroundActivities = false;
18465            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18466            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18467            // System processes can do UI, and when they do we want to have
18468            // them trim their memory after the user leaves the UI.  To
18469            // facilitate this, here we need to determine whether or not it
18470            // is currently showing UI.
18471            app.systemNoUi = true;
18472            if (app == TOP_APP) {
18473                app.systemNoUi = false;
18474            } else if (activitiesSize > 0) {
18475                for (int j = 0; j < activitiesSize; j++) {
18476                    final ActivityRecord r = app.activities.get(j);
18477                    if (r.visible) {
18478                        app.systemNoUi = false;
18479                    }
18480                }
18481            }
18482            if (!app.systemNoUi) {
18483                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18484            }
18485            return (app.curAdj=app.maxAdj);
18486        }
18487
18488        app.systemNoUi = false;
18489
18490        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18491
18492        // Determine the importance of the process, starting with most
18493        // important to least, and assign an appropriate OOM adjustment.
18494        int adj;
18495        int schedGroup;
18496        int procState;
18497        boolean foregroundActivities = false;
18498        BroadcastQueue queue;
18499        if (app == TOP_APP) {
18500            // The last app on the list is the foreground app.
18501            adj = ProcessList.FOREGROUND_APP_ADJ;
18502            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18503            app.adjType = "top-activity";
18504            foregroundActivities = true;
18505            procState = PROCESS_STATE_CUR_TOP;
18506        } else if (app.instrumentationClass != null) {
18507            // Don't want to kill running instrumentation.
18508            adj = ProcessList.FOREGROUND_APP_ADJ;
18509            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18510            app.adjType = "instrumentation";
18511            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18512        } else if ((queue = isReceivingBroadcast(app)) != null) {
18513            // An app that is currently receiving a broadcast also
18514            // counts as being in the foreground for OOM killer purposes.
18515            // It's placed in a sched group based on the nature of the
18516            // broadcast as reflected by which queue it's active in.
18517            adj = ProcessList.FOREGROUND_APP_ADJ;
18518            schedGroup = (queue == mFgBroadcastQueue)
18519                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18520            app.adjType = "broadcast";
18521            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18522        } else if (app.executingServices.size() > 0) {
18523            // An app that is currently executing a service callback also
18524            // counts as being in the foreground.
18525            adj = ProcessList.FOREGROUND_APP_ADJ;
18526            schedGroup = app.execServicesFg ?
18527                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18528            app.adjType = "exec-service";
18529            procState = ActivityManager.PROCESS_STATE_SERVICE;
18530            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18531        } else {
18532            // As far as we know the process is empty.  We may change our mind later.
18533            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18534            // At this point we don't actually know the adjustment.  Use the cached adj
18535            // value that the caller wants us to.
18536            adj = cachedAdj;
18537            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18538            app.cached = true;
18539            app.empty = true;
18540            app.adjType = "cch-empty";
18541        }
18542
18543        // Examine all activities if not already foreground.
18544        if (!foregroundActivities && activitiesSize > 0) {
18545            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18546            for (int j = 0; j < activitiesSize; j++) {
18547                final ActivityRecord r = app.activities.get(j);
18548                if (r.app != app) {
18549                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18550                            + " instead of expected " + app);
18551                    if (r.app == null || (r.app.uid == app.uid)) {
18552                        // Only fix things up when they look sane
18553                        r.app = app;
18554                    } else {
18555                        continue;
18556                    }
18557                }
18558                if (r.visible) {
18559                    // App has a visible activity; only upgrade adjustment.
18560                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18561                        adj = ProcessList.VISIBLE_APP_ADJ;
18562                        app.adjType = "visible";
18563                    }
18564                    if (procState > PROCESS_STATE_CUR_TOP) {
18565                        procState = PROCESS_STATE_CUR_TOP;
18566                    }
18567                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18568                    app.cached = false;
18569                    app.empty = false;
18570                    foregroundActivities = true;
18571                    if (r.task != null && minLayer > 0) {
18572                        final int layer = r.task.mLayerRank;
18573                        if (layer >= 0 && minLayer > layer) {
18574                            minLayer = layer;
18575                        }
18576                    }
18577                    break;
18578                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18579                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18580                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18581                        app.adjType = "pausing";
18582                    }
18583                    if (procState > PROCESS_STATE_CUR_TOP) {
18584                        procState = PROCESS_STATE_CUR_TOP;
18585                    }
18586                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18587                    app.cached = false;
18588                    app.empty = false;
18589                    foregroundActivities = true;
18590                } else if (r.state == ActivityState.STOPPING) {
18591                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18592                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18593                        app.adjType = "stopping";
18594                    }
18595                    // For the process state, we will at this point consider the
18596                    // process to be cached.  It will be cached either as an activity
18597                    // or empty depending on whether the activity is finishing.  We do
18598                    // this so that we can treat the process as cached for purposes of
18599                    // memory trimming (determing current memory level, trim command to
18600                    // send to process) since there can be an arbitrary number of stopping
18601                    // processes and they should soon all go into the cached state.
18602                    if (!r.finishing) {
18603                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18604                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18605                        }
18606                    }
18607                    app.cached = false;
18608                    app.empty = false;
18609                    foregroundActivities = true;
18610                } else {
18611                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18612                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18613                        app.adjType = "cch-act";
18614                    }
18615                }
18616            }
18617            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18618                adj += minLayer;
18619            }
18620        }
18621
18622        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18623                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18624            if (app.foregroundServices) {
18625                // The user is aware of this app, so make it visible.
18626                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18627                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18628                app.cached = false;
18629                app.adjType = "fg-service";
18630                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18631            } else if (app.forcingToForeground != null) {
18632                // The user is aware of this app, so make it visible.
18633                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18634                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18635                app.cached = false;
18636                app.adjType = "force-fg";
18637                app.adjSource = app.forcingToForeground;
18638                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18639            }
18640        }
18641
18642        if (app == mHeavyWeightProcess) {
18643            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18644                // We don't want to kill the current heavy-weight process.
18645                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18646                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18647                app.cached = false;
18648                app.adjType = "heavy";
18649            }
18650            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18651                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18652            }
18653        }
18654
18655        if (app == mHomeProcess) {
18656            if (adj > ProcessList.HOME_APP_ADJ) {
18657                // This process is hosting what we currently consider to be the
18658                // home app, so we don't want to let it go into the background.
18659                adj = ProcessList.HOME_APP_ADJ;
18660                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18661                app.cached = false;
18662                app.adjType = "home";
18663            }
18664            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18665                procState = ActivityManager.PROCESS_STATE_HOME;
18666            }
18667        }
18668
18669        if (app == mPreviousProcess && app.activities.size() > 0) {
18670            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18671                // This was the previous process that showed UI to the user.
18672                // We want to try to keep it around more aggressively, to give
18673                // a good experience around switching between two apps.
18674                adj = ProcessList.PREVIOUS_APP_ADJ;
18675                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18676                app.cached = false;
18677                app.adjType = "previous";
18678            }
18679            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18680                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18681            }
18682        }
18683
18684        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18685                + " reason=" + app.adjType);
18686
18687        // By default, we use the computed adjustment.  It may be changed if
18688        // there are applications dependent on our services or providers, but
18689        // this gives us a baseline and makes sure we don't get into an
18690        // infinite recursion.
18691        app.adjSeq = mAdjSeq;
18692        app.curRawAdj = adj;
18693        app.hasStartedServices = false;
18694
18695        if (mBackupTarget != null && app == mBackupTarget.app) {
18696            // If possible we want to avoid killing apps while they're being backed up
18697            if (adj > ProcessList.BACKUP_APP_ADJ) {
18698                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18699                adj = ProcessList.BACKUP_APP_ADJ;
18700                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18701                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18702                }
18703                app.adjType = "backup";
18704                app.cached = false;
18705            }
18706            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18707                procState = ActivityManager.PROCESS_STATE_BACKUP;
18708            }
18709        }
18710
18711        boolean mayBeTop = false;
18712
18713        for (int is = app.services.size()-1;
18714                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18715                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18716                        || procState > ActivityManager.PROCESS_STATE_TOP);
18717                is--) {
18718            ServiceRecord s = app.services.valueAt(is);
18719            if (s.startRequested) {
18720                app.hasStartedServices = true;
18721                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18722                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18723                }
18724                if (app.hasShownUi && app != mHomeProcess) {
18725                    // If this process has shown some UI, let it immediately
18726                    // go to the LRU list because it may be pretty heavy with
18727                    // UI stuff.  We'll tag it with a label just to help
18728                    // debug and understand what is going on.
18729                    if (adj > ProcessList.SERVICE_ADJ) {
18730                        app.adjType = "cch-started-ui-services";
18731                    }
18732                } else {
18733                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18734                        // This service has seen some activity within
18735                        // recent memory, so we will keep its process ahead
18736                        // of the background processes.
18737                        if (adj > ProcessList.SERVICE_ADJ) {
18738                            adj = ProcessList.SERVICE_ADJ;
18739                            app.adjType = "started-services";
18740                            app.cached = false;
18741                        }
18742                    }
18743                    // If we have let the service slide into the background
18744                    // state, still have some text describing what it is doing
18745                    // even though the service no longer has an impact.
18746                    if (adj > ProcessList.SERVICE_ADJ) {
18747                        app.adjType = "cch-started-services";
18748                    }
18749                }
18750            }
18751            for (int conni = s.connections.size()-1;
18752                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18753                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18754                            || procState > ActivityManager.PROCESS_STATE_TOP);
18755                    conni--) {
18756                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18757                for (int i = 0;
18758                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18759                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18760                                || procState > ActivityManager.PROCESS_STATE_TOP);
18761                        i++) {
18762                    // XXX should compute this based on the max of
18763                    // all connected clients.
18764                    ConnectionRecord cr = clist.get(i);
18765                    if (cr.binding.client == app) {
18766                        // Binding to ourself is not interesting.
18767                        continue;
18768                    }
18769                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18770                        ProcessRecord client = cr.binding.client;
18771                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18772                                TOP_APP, doingAll, now);
18773                        int clientProcState = client.curProcState;
18774                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18775                            // If the other app is cached for any reason, for purposes here
18776                            // we are going to consider it empty.  The specific cached state
18777                            // doesn't propagate except under certain conditions.
18778                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18779                        }
18780                        String adjType = null;
18781                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18782                            // Not doing bind OOM management, so treat
18783                            // this guy more like a started service.
18784                            if (app.hasShownUi && app != mHomeProcess) {
18785                                // If this process has shown some UI, let it immediately
18786                                // go to the LRU list because it may be pretty heavy with
18787                                // UI stuff.  We'll tag it with a label just to help
18788                                // debug and understand what is going on.
18789                                if (adj > clientAdj) {
18790                                    adjType = "cch-bound-ui-services";
18791                                }
18792                                app.cached = false;
18793                                clientAdj = adj;
18794                                clientProcState = procState;
18795                            } else {
18796                                if (now >= (s.lastActivity
18797                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18798                                    // This service has not seen activity within
18799                                    // recent memory, so allow it to drop to the
18800                                    // LRU list if there is no other reason to keep
18801                                    // it around.  We'll also tag it with a label just
18802                                    // to help debug and undertand what is going on.
18803                                    if (adj > clientAdj) {
18804                                        adjType = "cch-bound-services";
18805                                    }
18806                                    clientAdj = adj;
18807                                }
18808                            }
18809                        }
18810                        if (adj > clientAdj) {
18811                            // If this process has recently shown UI, and
18812                            // the process that is binding to it is less
18813                            // important than being visible, then we don't
18814                            // care about the binding as much as we care
18815                            // about letting this process get into the LRU
18816                            // list to be killed and restarted if needed for
18817                            // memory.
18818                            if (app.hasShownUi && app != mHomeProcess
18819                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18820                                adjType = "cch-bound-ui-services";
18821                            } else {
18822                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18823                                        |Context.BIND_IMPORTANT)) != 0) {
18824                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18825                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18826                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18827                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18828                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18829                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18830                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18831                                    adj = clientAdj;
18832                                } else {
18833                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18834                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18835                                    }
18836                                }
18837                                if (!client.cached) {
18838                                    app.cached = false;
18839                                }
18840                                adjType = "service";
18841                            }
18842                        }
18843                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18844                            // This will treat important bound services identically to
18845                            // the top app, which may behave differently than generic
18846                            // foreground work.
18847                            if (client.curSchedGroup > schedGroup) {
18848                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18849                                    schedGroup = client.curSchedGroup;
18850                                } else {
18851                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18852                                }
18853                            }
18854                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18855                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18856                                    // Special handling of clients who are in the top state.
18857                                    // We *may* want to consider this process to be in the
18858                                    // top state as well, but only if there is not another
18859                                    // reason for it to be running.  Being on the top is a
18860                                    // special state, meaning you are specifically running
18861                                    // for the current top app.  If the process is already
18862                                    // running in the background for some other reason, it
18863                                    // is more important to continue considering it to be
18864                                    // in the background state.
18865                                    mayBeTop = true;
18866                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18867                                } else {
18868                                    // Special handling for above-top states (persistent
18869                                    // processes).  These should not bring the current process
18870                                    // into the top state, since they are not on top.  Instead
18871                                    // give them the best state after that.
18872                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18873                                        clientProcState =
18874                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18875                                    } else if (mWakefulness
18876                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18877                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18878                                                    != 0) {
18879                                        clientProcState =
18880                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18881                                    } else {
18882                                        clientProcState =
18883                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18884                                    }
18885                                }
18886                            }
18887                        } else {
18888                            if (clientProcState <
18889                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18890                                clientProcState =
18891                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18892                            }
18893                        }
18894                        if (procState > clientProcState) {
18895                            procState = clientProcState;
18896                        }
18897                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18898                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18899                            app.pendingUiClean = true;
18900                        }
18901                        if (adjType != null) {
18902                            app.adjType = adjType;
18903                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18904                                    .REASON_SERVICE_IN_USE;
18905                            app.adjSource = cr.binding.client;
18906                            app.adjSourceProcState = clientProcState;
18907                            app.adjTarget = s.name;
18908                        }
18909                    }
18910                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18911                        app.treatLikeActivity = true;
18912                    }
18913                    final ActivityRecord a = cr.activity;
18914                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18915                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18916                            (a.visible || a.state == ActivityState.RESUMED ||
18917                             a.state == ActivityState.PAUSING)) {
18918                            adj = ProcessList.FOREGROUND_APP_ADJ;
18919                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18920                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18921                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18922                                } else {
18923                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18924                                }
18925                            }
18926                            app.cached = false;
18927                            app.adjType = "service";
18928                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18929                                    .REASON_SERVICE_IN_USE;
18930                            app.adjSource = a;
18931                            app.adjSourceProcState = procState;
18932                            app.adjTarget = s.name;
18933                        }
18934                    }
18935                }
18936            }
18937        }
18938
18939        for (int provi = app.pubProviders.size()-1;
18940                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18941                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18942                        || procState > ActivityManager.PROCESS_STATE_TOP);
18943                provi--) {
18944            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18945            for (int i = cpr.connections.size()-1;
18946                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18947                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18948                            || procState > ActivityManager.PROCESS_STATE_TOP);
18949                    i--) {
18950                ContentProviderConnection conn = cpr.connections.get(i);
18951                ProcessRecord client = conn.client;
18952                if (client == app) {
18953                    // Being our own client is not interesting.
18954                    continue;
18955                }
18956                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18957                int clientProcState = client.curProcState;
18958                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18959                    // If the other app is cached for any reason, for purposes here
18960                    // we are going to consider it empty.
18961                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18962                }
18963                if (adj > clientAdj) {
18964                    if (app.hasShownUi && app != mHomeProcess
18965                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18966                        app.adjType = "cch-ui-provider";
18967                    } else {
18968                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18969                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18970                        app.adjType = "provider";
18971                    }
18972                    app.cached &= client.cached;
18973                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18974                            .REASON_PROVIDER_IN_USE;
18975                    app.adjSource = client;
18976                    app.adjSourceProcState = clientProcState;
18977                    app.adjTarget = cpr.name;
18978                }
18979                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18980                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18981                        // Special handling of clients who are in the top state.
18982                        // We *may* want to consider this process to be in the
18983                        // top state as well, but only if there is not another
18984                        // reason for it to be running.  Being on the top is a
18985                        // special state, meaning you are specifically running
18986                        // for the current top app.  If the process is already
18987                        // running in the background for some other reason, it
18988                        // is more important to continue considering it to be
18989                        // in the background state.
18990                        mayBeTop = true;
18991                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18992                    } else {
18993                        // Special handling for above-top states (persistent
18994                        // processes).  These should not bring the current process
18995                        // into the top state, since they are not on top.  Instead
18996                        // give them the best state after that.
18997                        clientProcState =
18998                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18999                    }
19000                }
19001                if (procState > clientProcState) {
19002                    procState = clientProcState;
19003                }
19004                if (client.curSchedGroup > schedGroup) {
19005                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19006                }
19007            }
19008            // If the provider has external (non-framework) process
19009            // dependencies, ensure that its adjustment is at least
19010            // FOREGROUND_APP_ADJ.
19011            if (cpr.hasExternalProcessHandles()) {
19012                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19013                    adj = ProcessList.FOREGROUND_APP_ADJ;
19014                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19015                    app.cached = false;
19016                    app.adjType = "provider";
19017                    app.adjTarget = cpr.name;
19018                }
19019                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19020                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19021                }
19022            }
19023        }
19024
19025        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19026            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19027                adj = ProcessList.PREVIOUS_APP_ADJ;
19028                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19029                app.cached = false;
19030                app.adjType = "provider";
19031            }
19032            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19033                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19034            }
19035        }
19036
19037        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19038            // A client of one of our services or providers is in the top state.  We
19039            // *may* want to be in the top state, but not if we are already running in
19040            // the background for some other reason.  For the decision here, we are going
19041            // to pick out a few specific states that we want to remain in when a client
19042            // is top (states that tend to be longer-term) and otherwise allow it to go
19043            // to the top state.
19044            switch (procState) {
19045                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19046                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19047                case ActivityManager.PROCESS_STATE_SERVICE:
19048                    // These all are longer-term states, so pull them up to the top
19049                    // of the background states, but not all the way to the top state.
19050                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19051                    break;
19052                default:
19053                    // Otherwise, top is a better choice, so take it.
19054                    procState = ActivityManager.PROCESS_STATE_TOP;
19055                    break;
19056            }
19057        }
19058
19059        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19060            if (app.hasClientActivities) {
19061                // This is a cached process, but with client activities.  Mark it so.
19062                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19063                app.adjType = "cch-client-act";
19064            } else if (app.treatLikeActivity) {
19065                // This is a cached process, but somebody wants us to treat it like it has
19066                // an activity, okay!
19067                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19068                app.adjType = "cch-as-act";
19069            }
19070        }
19071
19072        if (adj == ProcessList.SERVICE_ADJ) {
19073            if (doingAll) {
19074                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19075                mNewNumServiceProcs++;
19076                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19077                if (!app.serviceb) {
19078                    // This service isn't far enough down on the LRU list to
19079                    // normally be a B service, but if we are low on RAM and it
19080                    // is large we want to force it down since we would prefer to
19081                    // keep launcher over it.
19082                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19083                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19084                        app.serviceHighRam = true;
19085                        app.serviceb = true;
19086                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19087                    } else {
19088                        mNewNumAServiceProcs++;
19089                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19090                    }
19091                } else {
19092                    app.serviceHighRam = false;
19093                }
19094            }
19095            if (app.serviceb) {
19096                adj = ProcessList.SERVICE_B_ADJ;
19097            }
19098        }
19099
19100        app.curRawAdj = adj;
19101
19102        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19103        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19104        if (adj > app.maxAdj) {
19105            adj = app.maxAdj;
19106            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19107                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19108            }
19109        }
19110
19111        // Do final modification to adj.  Everything we do between here and applying
19112        // the final setAdj must be done in this function, because we will also use
19113        // it when computing the final cached adj later.  Note that we don't need to
19114        // worry about this for max adj above, since max adj will always be used to
19115        // keep it out of the cached vaues.
19116        app.curAdj = app.modifyRawOomAdj(adj);
19117        app.curSchedGroup = schedGroup;
19118        app.curProcState = procState;
19119        app.foregroundActivities = foregroundActivities;
19120
19121        return app.curRawAdj;
19122    }
19123
19124    /**
19125     * Record new PSS sample for a process.
19126     */
19127    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19128            long now) {
19129        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19130                swapPss * 1024);
19131        proc.lastPssTime = now;
19132        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19133        if (DEBUG_PSS) Slog.d(TAG_PSS,
19134                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19135                + " state=" + ProcessList.makeProcStateString(procState));
19136        if (proc.initialIdlePss == 0) {
19137            proc.initialIdlePss = pss;
19138        }
19139        proc.lastPss = pss;
19140        proc.lastSwapPss = swapPss;
19141        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19142            proc.lastCachedPss = pss;
19143            proc.lastCachedSwapPss = swapPss;
19144        }
19145
19146        final SparseArray<Pair<Long, String>> watchUids
19147                = mMemWatchProcesses.getMap().get(proc.processName);
19148        Long check = null;
19149        if (watchUids != null) {
19150            Pair<Long, String> val = watchUids.get(proc.uid);
19151            if (val == null) {
19152                val = watchUids.get(0);
19153            }
19154            if (val != null) {
19155                check = val.first;
19156            }
19157        }
19158        if (check != null) {
19159            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19160                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19161                if (!isDebuggable) {
19162                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19163                        isDebuggable = true;
19164                    }
19165                }
19166                if (isDebuggable) {
19167                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19168                    final ProcessRecord myProc = proc;
19169                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19170                    mMemWatchDumpProcName = proc.processName;
19171                    mMemWatchDumpFile = heapdumpFile.toString();
19172                    mMemWatchDumpPid = proc.pid;
19173                    mMemWatchDumpUid = proc.uid;
19174                    BackgroundThread.getHandler().post(new Runnable() {
19175                        @Override
19176                        public void run() {
19177                            revokeUriPermission(ActivityThread.currentActivityThread()
19178                                            .getApplicationThread(),
19179                                    DumpHeapActivity.JAVA_URI,
19180                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19181                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19182                                    UserHandle.myUserId());
19183                            ParcelFileDescriptor fd = null;
19184                            try {
19185                                heapdumpFile.delete();
19186                                fd = ParcelFileDescriptor.open(heapdumpFile,
19187                                        ParcelFileDescriptor.MODE_CREATE |
19188                                                ParcelFileDescriptor.MODE_TRUNCATE |
19189                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19190                                                ParcelFileDescriptor.MODE_APPEND);
19191                                IApplicationThread thread = myProc.thread;
19192                                if (thread != null) {
19193                                    try {
19194                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19195                                                "Requesting dump heap from "
19196                                                + myProc + " to " + heapdumpFile);
19197                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19198                                    } catch (RemoteException e) {
19199                                    }
19200                                }
19201                            } catch (FileNotFoundException e) {
19202                                e.printStackTrace();
19203                            } finally {
19204                                if (fd != null) {
19205                                    try {
19206                                        fd.close();
19207                                    } catch (IOException e) {
19208                                    }
19209                                }
19210                            }
19211                        }
19212                    });
19213                } else {
19214                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19215                            + ", but debugging not enabled");
19216                }
19217            }
19218        }
19219    }
19220
19221    /**
19222     * Schedule PSS collection of a process.
19223     */
19224    void requestPssLocked(ProcessRecord proc, int procState) {
19225        if (mPendingPssProcesses.contains(proc)) {
19226            return;
19227        }
19228        if (mPendingPssProcesses.size() == 0) {
19229            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19230        }
19231        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19232        proc.pssProcState = procState;
19233        mPendingPssProcesses.add(proc);
19234    }
19235
19236    /**
19237     * Schedule PSS collection of all processes.
19238     */
19239    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19240        if (!always) {
19241            if (now < (mLastFullPssTime +
19242                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19243                return;
19244            }
19245        }
19246        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19247        mLastFullPssTime = now;
19248        mFullPssPending = true;
19249        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19250        mPendingPssProcesses.clear();
19251        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19252            ProcessRecord app = mLruProcesses.get(i);
19253            if (app.thread == null
19254                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19255                continue;
19256            }
19257            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19258                app.pssProcState = app.setProcState;
19259                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19260                        mTestPssMode, isSleeping(), now);
19261                mPendingPssProcesses.add(app);
19262            }
19263        }
19264        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19265    }
19266
19267    public void setTestPssMode(boolean enabled) {
19268        synchronized (this) {
19269            mTestPssMode = enabled;
19270            if (enabled) {
19271                // Whenever we enable the mode, we want to take a snapshot all of current
19272                // process mem use.
19273                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19274            }
19275        }
19276    }
19277
19278    /**
19279     * Ask a given process to GC right now.
19280     */
19281    final void performAppGcLocked(ProcessRecord app) {
19282        try {
19283            app.lastRequestedGc = SystemClock.uptimeMillis();
19284            if (app.thread != null) {
19285                if (app.reportLowMemory) {
19286                    app.reportLowMemory = false;
19287                    app.thread.scheduleLowMemory();
19288                } else {
19289                    app.thread.processInBackground();
19290                }
19291            }
19292        } catch (Exception e) {
19293            // whatever.
19294        }
19295    }
19296
19297    /**
19298     * Returns true if things are idle enough to perform GCs.
19299     */
19300    private final boolean canGcNowLocked() {
19301        boolean processingBroadcasts = false;
19302        for (BroadcastQueue q : mBroadcastQueues) {
19303            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19304                processingBroadcasts = true;
19305            }
19306        }
19307        return !processingBroadcasts
19308                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19309    }
19310
19311    /**
19312     * Perform GCs on all processes that are waiting for it, but only
19313     * if things are idle.
19314     */
19315    final void performAppGcsLocked() {
19316        final int N = mProcessesToGc.size();
19317        if (N <= 0) {
19318            return;
19319        }
19320        if (canGcNowLocked()) {
19321            while (mProcessesToGc.size() > 0) {
19322                ProcessRecord proc = mProcessesToGc.remove(0);
19323                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19324                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19325                            <= SystemClock.uptimeMillis()) {
19326                        // To avoid spamming the system, we will GC processes one
19327                        // at a time, waiting a few seconds between each.
19328                        performAppGcLocked(proc);
19329                        scheduleAppGcsLocked();
19330                        return;
19331                    } else {
19332                        // It hasn't been long enough since we last GCed this
19333                        // process...  put it in the list to wait for its time.
19334                        addProcessToGcListLocked(proc);
19335                        break;
19336                    }
19337                }
19338            }
19339
19340            scheduleAppGcsLocked();
19341        }
19342    }
19343
19344    /**
19345     * If all looks good, perform GCs on all processes waiting for them.
19346     */
19347    final void performAppGcsIfAppropriateLocked() {
19348        if (canGcNowLocked()) {
19349            performAppGcsLocked();
19350            return;
19351        }
19352        // Still not idle, wait some more.
19353        scheduleAppGcsLocked();
19354    }
19355
19356    /**
19357     * Schedule the execution of all pending app GCs.
19358     */
19359    final void scheduleAppGcsLocked() {
19360        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19361
19362        if (mProcessesToGc.size() > 0) {
19363            // Schedule a GC for the time to the next process.
19364            ProcessRecord proc = mProcessesToGc.get(0);
19365            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19366
19367            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19368            long now = SystemClock.uptimeMillis();
19369            if (when < (now+GC_TIMEOUT)) {
19370                when = now + GC_TIMEOUT;
19371            }
19372            mHandler.sendMessageAtTime(msg, when);
19373        }
19374    }
19375
19376    /**
19377     * Add a process to the array of processes waiting to be GCed.  Keeps the
19378     * list in sorted order by the last GC time.  The process can't already be
19379     * on the list.
19380     */
19381    final void addProcessToGcListLocked(ProcessRecord proc) {
19382        boolean added = false;
19383        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19384            if (mProcessesToGc.get(i).lastRequestedGc <
19385                    proc.lastRequestedGc) {
19386                added = true;
19387                mProcessesToGc.add(i+1, proc);
19388                break;
19389            }
19390        }
19391        if (!added) {
19392            mProcessesToGc.add(0, proc);
19393        }
19394    }
19395
19396    /**
19397     * Set up to ask a process to GC itself.  This will either do it
19398     * immediately, or put it on the list of processes to gc the next
19399     * time things are idle.
19400     */
19401    final void scheduleAppGcLocked(ProcessRecord app) {
19402        long now = SystemClock.uptimeMillis();
19403        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19404            return;
19405        }
19406        if (!mProcessesToGc.contains(app)) {
19407            addProcessToGcListLocked(app);
19408            scheduleAppGcsLocked();
19409        }
19410    }
19411
19412    final void checkExcessivePowerUsageLocked(boolean doKills) {
19413        updateCpuStatsNow();
19414
19415        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19416        boolean doWakeKills = doKills;
19417        boolean doCpuKills = doKills;
19418        if (mLastPowerCheckRealtime == 0) {
19419            doWakeKills = false;
19420        }
19421        if (mLastPowerCheckUptime == 0) {
19422            doCpuKills = false;
19423        }
19424        if (stats.isScreenOn()) {
19425            doWakeKills = false;
19426        }
19427        final long curRealtime = SystemClock.elapsedRealtime();
19428        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19429        final long curUptime = SystemClock.uptimeMillis();
19430        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19431        mLastPowerCheckRealtime = curRealtime;
19432        mLastPowerCheckUptime = curUptime;
19433        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19434            doWakeKills = false;
19435        }
19436        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19437            doCpuKills = false;
19438        }
19439        int i = mLruProcesses.size();
19440        while (i > 0) {
19441            i--;
19442            ProcessRecord app = mLruProcesses.get(i);
19443            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19444                long wtime;
19445                synchronized (stats) {
19446                    wtime = stats.getProcessWakeTime(app.info.uid,
19447                            app.pid, curRealtime);
19448                }
19449                long wtimeUsed = wtime - app.lastWakeTime;
19450                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19451                if (DEBUG_POWER) {
19452                    StringBuilder sb = new StringBuilder(128);
19453                    sb.append("Wake for ");
19454                    app.toShortString(sb);
19455                    sb.append(": over ");
19456                    TimeUtils.formatDuration(realtimeSince, sb);
19457                    sb.append(" used ");
19458                    TimeUtils.formatDuration(wtimeUsed, sb);
19459                    sb.append(" (");
19460                    sb.append((wtimeUsed*100)/realtimeSince);
19461                    sb.append("%)");
19462                    Slog.i(TAG_POWER, sb.toString());
19463                    sb.setLength(0);
19464                    sb.append("CPU for ");
19465                    app.toShortString(sb);
19466                    sb.append(": over ");
19467                    TimeUtils.formatDuration(uptimeSince, sb);
19468                    sb.append(" used ");
19469                    TimeUtils.formatDuration(cputimeUsed, sb);
19470                    sb.append(" (");
19471                    sb.append((cputimeUsed*100)/uptimeSince);
19472                    sb.append("%)");
19473                    Slog.i(TAG_POWER, sb.toString());
19474                }
19475                // If a process has held a wake lock for more
19476                // than 50% of the time during this period,
19477                // that sounds bad.  Kill!
19478                if (doWakeKills && realtimeSince > 0
19479                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19480                    synchronized (stats) {
19481                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19482                                realtimeSince, wtimeUsed);
19483                    }
19484                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19485                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19486                } else if (doCpuKills && uptimeSince > 0
19487                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19488                    synchronized (stats) {
19489                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19490                                uptimeSince, cputimeUsed);
19491                    }
19492                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19493                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19494                } else {
19495                    app.lastWakeTime = wtime;
19496                    app.lastCpuTime = app.curCpuTime;
19497                }
19498            }
19499        }
19500    }
19501
19502    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19503            long nowElapsed) {
19504        boolean success = true;
19505
19506        if (app.curRawAdj != app.setRawAdj) {
19507            app.setRawAdj = app.curRawAdj;
19508        }
19509
19510        int changes = 0;
19511
19512        if (app.curAdj != app.setAdj) {
19513            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19514            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19515                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19516                    + app.adjType);
19517            app.setAdj = app.curAdj;
19518        }
19519
19520        if (app.setSchedGroup != app.curSchedGroup) {
19521            app.setSchedGroup = app.curSchedGroup;
19522            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19523                    "Setting sched group of " + app.processName
19524                    + " to " + app.curSchedGroup);
19525            if (app.waitingToKill != null && app.curReceiver == null
19526                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19527                app.kill(app.waitingToKill, true);
19528                success = false;
19529            } else {
19530                int processGroup;
19531                switch (app.curSchedGroup) {
19532                    case ProcessList.SCHED_GROUP_BACKGROUND:
19533                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19534                        break;
19535                    case ProcessList.SCHED_GROUP_TOP_APP:
19536                        processGroup = Process.THREAD_GROUP_TOP_APP;
19537                        break;
19538                    default:
19539                        processGroup = Process.THREAD_GROUP_DEFAULT;
19540                        break;
19541                }
19542                if (true) {
19543                    long oldId = Binder.clearCallingIdentity();
19544                    try {
19545                        Process.setProcessGroup(app.pid, processGroup);
19546                    } catch (Exception e) {
19547                        Slog.w(TAG, "Failed setting process group of " + app.pid
19548                                + " to " + app.curSchedGroup);
19549                        e.printStackTrace();
19550                    } finally {
19551                        Binder.restoreCallingIdentity(oldId);
19552                    }
19553                } else {
19554                    if (app.thread != null) {
19555                        try {
19556                            app.thread.setSchedulingGroup(processGroup);
19557                        } catch (RemoteException e) {
19558                        }
19559                    }
19560                }
19561            }
19562        }
19563        if (app.repForegroundActivities != app.foregroundActivities) {
19564            app.repForegroundActivities = app.foregroundActivities;
19565            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19566        }
19567        if (app.repProcState != app.curProcState) {
19568            app.repProcState = app.curProcState;
19569            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19570            if (app.thread != null) {
19571                try {
19572                    if (false) {
19573                        //RuntimeException h = new RuntimeException("here");
19574                        Slog.i(TAG, "Sending new process state " + app.repProcState
19575                                + " to " + app /*, h*/);
19576                    }
19577                    app.thread.setProcessState(app.repProcState);
19578                } catch (RemoteException e) {
19579                }
19580            }
19581        }
19582        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19583                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19584            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19585                // Experimental code to more aggressively collect pss while
19586                // running test...  the problem is that this tends to collect
19587                // the data right when a process is transitioning between process
19588                // states, which well tend to give noisy data.
19589                long start = SystemClock.uptimeMillis();
19590                long pss = Debug.getPss(app.pid, mTmpLong, null);
19591                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19592                mPendingPssProcesses.remove(app);
19593                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19594                        + " to " + app.curProcState + ": "
19595                        + (SystemClock.uptimeMillis()-start) + "ms");
19596            }
19597            app.lastStateTime = now;
19598            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19599                    mTestPssMode, isSleeping(), now);
19600            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19601                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19602                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19603                    + (app.nextPssTime-now) + ": " + app);
19604        } else {
19605            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19606                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19607                    mTestPssMode)))) {
19608                requestPssLocked(app, app.setProcState);
19609                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19610                        mTestPssMode, isSleeping(), now);
19611            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19612                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19613        }
19614        if (app.setProcState != app.curProcState) {
19615            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19616                    "Proc state change of " + app.processName
19617                            + " to " + app.curProcState);
19618            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19619            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19620            if (setImportant && !curImportant) {
19621                // This app is no longer something we consider important enough to allow to
19622                // use arbitrary amounts of battery power.  Note
19623                // its current wake lock time to later know to kill it if
19624                // it is not behaving well.
19625                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19626                synchronized (stats) {
19627                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19628                            app.pid, nowElapsed);
19629                }
19630                app.lastCpuTime = app.curCpuTime;
19631
19632            }
19633            // Inform UsageStats of important process state change
19634            // Must be called before updating setProcState
19635            maybeUpdateUsageStatsLocked(app, nowElapsed);
19636
19637            app.setProcState = app.curProcState;
19638            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19639                app.notCachedSinceIdle = false;
19640            }
19641            if (!doingAll) {
19642                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19643            } else {
19644                app.procStateChanged = true;
19645            }
19646        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19647                > USAGE_STATS_INTERACTION_INTERVAL) {
19648            // For apps that sit around for a long time in the interactive state, we need
19649            // to report this at least once a day so they don't go idle.
19650            maybeUpdateUsageStatsLocked(app, nowElapsed);
19651        }
19652
19653        if (changes != 0) {
19654            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19655                    "Changes in " + app + ": " + changes);
19656            int i = mPendingProcessChanges.size()-1;
19657            ProcessChangeItem item = null;
19658            while (i >= 0) {
19659                item = mPendingProcessChanges.get(i);
19660                if (item.pid == app.pid) {
19661                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19662                            "Re-using existing item: " + item);
19663                    break;
19664                }
19665                i--;
19666            }
19667            if (i < 0) {
19668                // No existing item in pending changes; need a new one.
19669                final int NA = mAvailProcessChanges.size();
19670                if (NA > 0) {
19671                    item = mAvailProcessChanges.remove(NA-1);
19672                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19673                            "Retrieving available item: " + item);
19674                } else {
19675                    item = new ProcessChangeItem();
19676                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19677                            "Allocating new item: " + item);
19678                }
19679                item.changes = 0;
19680                item.pid = app.pid;
19681                item.uid = app.info.uid;
19682                if (mPendingProcessChanges.size() == 0) {
19683                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19684                            "*** Enqueueing dispatch processes changed!");
19685                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19686                }
19687                mPendingProcessChanges.add(item);
19688            }
19689            item.changes |= changes;
19690            item.processState = app.repProcState;
19691            item.foregroundActivities = app.repForegroundActivities;
19692            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19693                    "Item " + Integer.toHexString(System.identityHashCode(item))
19694                    + " " + app.toShortString() + ": changes=" + item.changes
19695                    + " procState=" + item.processState
19696                    + " foreground=" + item.foregroundActivities
19697                    + " type=" + app.adjType + " source=" + app.adjSource
19698                    + " target=" + app.adjTarget);
19699        }
19700
19701        return success;
19702    }
19703
19704    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19705        final UidRecord.ChangeItem pendingChange;
19706        if (uidRec == null || uidRec.pendingChange == null) {
19707            if (mPendingUidChanges.size() == 0) {
19708                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19709                        "*** Enqueueing dispatch uid changed!");
19710                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19711            }
19712            final int NA = mAvailUidChanges.size();
19713            if (NA > 0) {
19714                pendingChange = mAvailUidChanges.remove(NA-1);
19715                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19716                        "Retrieving available item: " + pendingChange);
19717            } else {
19718                pendingChange = new UidRecord.ChangeItem();
19719                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19720                        "Allocating new item: " + pendingChange);
19721            }
19722            if (uidRec != null) {
19723                uidRec.pendingChange = pendingChange;
19724                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19725                    // If this uid is going away, and we haven't yet reported it is gone,
19726                    // then do so now.
19727                    change = UidRecord.CHANGE_GONE_IDLE;
19728                }
19729            } else if (uid < 0) {
19730                throw new IllegalArgumentException("No UidRecord or uid");
19731            }
19732            pendingChange.uidRecord = uidRec;
19733            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19734            mPendingUidChanges.add(pendingChange);
19735        } else {
19736            pendingChange = uidRec.pendingChange;
19737            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19738                change = UidRecord.CHANGE_GONE_IDLE;
19739            }
19740        }
19741        pendingChange.change = change;
19742        pendingChange.processState = uidRec != null
19743                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19744    }
19745
19746    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19747            String authority) {
19748        if (app == null) return;
19749        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19750            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19751            if (userState == null) return;
19752            final long now = SystemClock.elapsedRealtime();
19753            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19754            if (lastReported == null || lastReported < now - 60 * 1000L) {
19755                mUsageStatsService.reportContentProviderUsage(
19756                        authority, providerPkgName, app.userId);
19757                userState.mProviderLastReportedFg.put(authority, now);
19758            }
19759        }
19760    }
19761
19762    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19763        if (DEBUG_USAGE_STATS) {
19764            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19765                    + "] state changes: old = " + app.setProcState + ", new = "
19766                    + app.curProcState);
19767        }
19768        if (mUsageStatsService == null) {
19769            return;
19770        }
19771        boolean isInteraction;
19772        // To avoid some abuse patterns, we are going to be careful about what we consider
19773        // to be an app interaction.  Being the top activity doesn't count while the display
19774        // is sleeping, nor do short foreground services.
19775        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19776            isInteraction = true;
19777            app.fgInteractionTime = 0;
19778        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19779            if (app.fgInteractionTime == 0) {
19780                app.fgInteractionTime = nowElapsed;
19781                isInteraction = false;
19782            } else {
19783                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19784            }
19785        } else {
19786            isInteraction = app.curProcState
19787                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19788            app.fgInteractionTime = 0;
19789        }
19790        if (isInteraction && (!app.reportedInteraction
19791                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19792            app.interactionEventTime = nowElapsed;
19793            String[] packages = app.getPackageList();
19794            if (packages != null) {
19795                for (int i = 0; i < packages.length; i++) {
19796                    mUsageStatsService.reportEvent(packages[i], app.userId,
19797                            UsageEvents.Event.SYSTEM_INTERACTION);
19798                }
19799            }
19800        }
19801        app.reportedInteraction = isInteraction;
19802        if (!isInteraction) {
19803            app.interactionEventTime = 0;
19804        }
19805    }
19806
19807    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19808        if (proc.thread != null) {
19809            if (proc.baseProcessTracker != null) {
19810                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19811            }
19812        }
19813    }
19814
19815    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19816            ProcessRecord TOP_APP, boolean doingAll, long now) {
19817        if (app.thread == null) {
19818            return false;
19819        }
19820
19821        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19822
19823        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19824    }
19825
19826    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19827            boolean oomAdj) {
19828        if (isForeground != proc.foregroundServices) {
19829            proc.foregroundServices = isForeground;
19830            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19831                    proc.info.uid);
19832            if (isForeground) {
19833                if (curProcs == null) {
19834                    curProcs = new ArrayList<ProcessRecord>();
19835                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19836                }
19837                if (!curProcs.contains(proc)) {
19838                    curProcs.add(proc);
19839                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19840                            proc.info.packageName, proc.info.uid);
19841                }
19842            } else {
19843                if (curProcs != null) {
19844                    if (curProcs.remove(proc)) {
19845                        mBatteryStatsService.noteEvent(
19846                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19847                                proc.info.packageName, proc.info.uid);
19848                        if (curProcs.size() <= 0) {
19849                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19850                        }
19851                    }
19852                }
19853            }
19854            if (oomAdj) {
19855                updateOomAdjLocked();
19856            }
19857        }
19858    }
19859
19860    private final ActivityRecord resumedAppLocked() {
19861        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19862        String pkg;
19863        int uid;
19864        if (act != null) {
19865            pkg = act.packageName;
19866            uid = act.info.applicationInfo.uid;
19867        } else {
19868            pkg = null;
19869            uid = -1;
19870        }
19871        // Has the UID or resumed package name changed?
19872        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19873                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19874            if (mCurResumedPackage != null) {
19875                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19876                        mCurResumedPackage, mCurResumedUid);
19877            }
19878            mCurResumedPackage = pkg;
19879            mCurResumedUid = uid;
19880            if (mCurResumedPackage != null) {
19881                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19882                        mCurResumedPackage, mCurResumedUid);
19883            }
19884        }
19885        return act;
19886    }
19887
19888    final boolean updateOomAdjLocked(ProcessRecord app) {
19889        final ActivityRecord TOP_ACT = resumedAppLocked();
19890        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19891        final boolean wasCached = app.cached;
19892
19893        mAdjSeq++;
19894
19895        // This is the desired cached adjusment we want to tell it to use.
19896        // If our app is currently cached, we know it, and that is it.  Otherwise,
19897        // we don't know it yet, and it needs to now be cached we will then
19898        // need to do a complete oom adj.
19899        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19900                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19901        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19902                SystemClock.uptimeMillis());
19903        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19904            // Changed to/from cached state, so apps after it in the LRU
19905            // list may also be changed.
19906            updateOomAdjLocked();
19907        }
19908        return success;
19909    }
19910
19911    final void updateOomAdjLocked() {
19912        final ActivityRecord TOP_ACT = resumedAppLocked();
19913        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19914        final long now = SystemClock.uptimeMillis();
19915        final long nowElapsed = SystemClock.elapsedRealtime();
19916        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19917        final int N = mLruProcesses.size();
19918
19919        if (false) {
19920            RuntimeException e = new RuntimeException();
19921            e.fillInStackTrace();
19922            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19923        }
19924
19925        // Reset state in all uid records.
19926        for (int i=mActiveUids.size()-1; i>=0; i--) {
19927            final UidRecord uidRec = mActiveUids.valueAt(i);
19928            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19929                    "Starting update of " + uidRec);
19930            uidRec.reset();
19931        }
19932
19933        mStackSupervisor.rankTaskLayersIfNeeded();
19934
19935        mAdjSeq++;
19936        mNewNumServiceProcs = 0;
19937        mNewNumAServiceProcs = 0;
19938
19939        final int emptyProcessLimit;
19940        final int cachedProcessLimit;
19941        if (mProcessLimit <= 0) {
19942            emptyProcessLimit = cachedProcessLimit = 0;
19943        } else if (mProcessLimit == 1) {
19944            emptyProcessLimit = 1;
19945            cachedProcessLimit = 0;
19946        } else {
19947            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19948            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19949        }
19950
19951        // Let's determine how many processes we have running vs.
19952        // how many slots we have for background processes; we may want
19953        // to put multiple processes in a slot of there are enough of
19954        // them.
19955        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19956                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19957        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19958        if (numEmptyProcs > cachedProcessLimit) {
19959            // If there are more empty processes than our limit on cached
19960            // processes, then use the cached process limit for the factor.
19961            // This ensures that the really old empty processes get pushed
19962            // down to the bottom, so if we are running low on memory we will
19963            // have a better chance at keeping around more cached processes
19964            // instead of a gazillion empty processes.
19965            numEmptyProcs = cachedProcessLimit;
19966        }
19967        int emptyFactor = numEmptyProcs/numSlots;
19968        if (emptyFactor < 1) emptyFactor = 1;
19969        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19970        if (cachedFactor < 1) cachedFactor = 1;
19971        int stepCached = 0;
19972        int stepEmpty = 0;
19973        int numCached = 0;
19974        int numEmpty = 0;
19975        int numTrimming = 0;
19976
19977        mNumNonCachedProcs = 0;
19978        mNumCachedHiddenProcs = 0;
19979
19980        // First update the OOM adjustment for each of the
19981        // application processes based on their current state.
19982        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19983        int nextCachedAdj = curCachedAdj+1;
19984        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19985        int nextEmptyAdj = curEmptyAdj+2;
19986        for (int i=N-1; i>=0; i--) {
19987            ProcessRecord app = mLruProcesses.get(i);
19988            if (!app.killedByAm && app.thread != null) {
19989                app.procStateChanged = false;
19990                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19991
19992                // If we haven't yet assigned the final cached adj
19993                // to the process, do that now.
19994                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19995                    switch (app.curProcState) {
19996                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19997                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19998                            // This process is a cached process holding activities...
19999                            // assign it the next cached value for that type, and then
20000                            // step that cached level.
20001                            app.curRawAdj = curCachedAdj;
20002                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20003                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20004                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20005                                    + ")");
20006                            if (curCachedAdj != nextCachedAdj) {
20007                                stepCached++;
20008                                if (stepCached >= cachedFactor) {
20009                                    stepCached = 0;
20010                                    curCachedAdj = nextCachedAdj;
20011                                    nextCachedAdj += 2;
20012                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20013                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20014                                    }
20015                                }
20016                            }
20017                            break;
20018                        default:
20019                            // For everything else, assign next empty cached process
20020                            // level and bump that up.  Note that this means that
20021                            // long-running services that have dropped down to the
20022                            // cached level will be treated as empty (since their process
20023                            // state is still as a service), which is what we want.
20024                            app.curRawAdj = curEmptyAdj;
20025                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20026                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20027                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20028                                    + ")");
20029                            if (curEmptyAdj != nextEmptyAdj) {
20030                                stepEmpty++;
20031                                if (stepEmpty >= emptyFactor) {
20032                                    stepEmpty = 0;
20033                                    curEmptyAdj = nextEmptyAdj;
20034                                    nextEmptyAdj += 2;
20035                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20036                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20037                                    }
20038                                }
20039                            }
20040                            break;
20041                    }
20042                }
20043
20044                applyOomAdjLocked(app, true, now, nowElapsed);
20045
20046                // Count the number of process types.
20047                switch (app.curProcState) {
20048                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20049                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20050                        mNumCachedHiddenProcs++;
20051                        numCached++;
20052                        if (numCached > cachedProcessLimit) {
20053                            app.kill("cached #" + numCached, true);
20054                        }
20055                        break;
20056                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20057                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20058                                && app.lastActivityTime < oldTime) {
20059                            app.kill("empty for "
20060                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20061                                    / 1000) + "s", true);
20062                        } else {
20063                            numEmpty++;
20064                            if (numEmpty > emptyProcessLimit) {
20065                                app.kill("empty #" + numEmpty, true);
20066                            }
20067                        }
20068                        break;
20069                    default:
20070                        mNumNonCachedProcs++;
20071                        break;
20072                }
20073
20074                if (app.isolated && app.services.size() <= 0) {
20075                    // If this is an isolated process, and there are no
20076                    // services running in it, then the process is no longer
20077                    // needed.  We agressively kill these because we can by
20078                    // definition not re-use the same process again, and it is
20079                    // good to avoid having whatever code was running in them
20080                    // left sitting around after no longer needed.
20081                    app.kill("isolated not needed", true);
20082                } else {
20083                    // Keeping this process, update its uid.
20084                    final UidRecord uidRec = app.uidRecord;
20085                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20086                        uidRec.curProcState = app.curProcState;
20087                    }
20088                }
20089
20090                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20091                        && !app.killedByAm) {
20092                    numTrimming++;
20093                }
20094            }
20095        }
20096
20097        mNumServiceProcs = mNewNumServiceProcs;
20098
20099        // Now determine the memory trimming level of background processes.
20100        // Unfortunately we need to start at the back of the list to do this
20101        // properly.  We only do this if the number of background apps we
20102        // are managing to keep around is less than half the maximum we desire;
20103        // if we are keeping a good number around, we'll let them use whatever
20104        // memory they want.
20105        final int numCachedAndEmpty = numCached + numEmpty;
20106        int memFactor;
20107        if (numCached <= ProcessList.TRIM_CACHED_APPS
20108                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20109            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20110                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20111            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20112                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20113            } else {
20114                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20115            }
20116        } else {
20117            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20118        }
20119        // We always allow the memory level to go up (better).  We only allow it to go
20120        // down if we are in a state where that is allowed, *and* the total number of processes
20121        // has gone down since last time.
20122        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20123                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20124                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20125        if (memFactor > mLastMemoryLevel) {
20126            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20127                memFactor = mLastMemoryLevel;
20128                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20129            }
20130        }
20131        if (memFactor != mLastMemoryLevel) {
20132            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20133        }
20134        mLastMemoryLevel = memFactor;
20135        mLastNumProcesses = mLruProcesses.size();
20136        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20137        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20138        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20139            if (mLowRamStartTime == 0) {
20140                mLowRamStartTime = now;
20141            }
20142            int step = 0;
20143            int fgTrimLevel;
20144            switch (memFactor) {
20145                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20146                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20147                    break;
20148                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20149                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20150                    break;
20151                default:
20152                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20153                    break;
20154            }
20155            int factor = numTrimming/3;
20156            int minFactor = 2;
20157            if (mHomeProcess != null) minFactor++;
20158            if (mPreviousProcess != null) minFactor++;
20159            if (factor < minFactor) factor = minFactor;
20160            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20161            for (int i=N-1; i>=0; i--) {
20162                ProcessRecord app = mLruProcesses.get(i);
20163                if (allChanged || app.procStateChanged) {
20164                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20165                    app.procStateChanged = false;
20166                }
20167                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20168                        && !app.killedByAm) {
20169                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20170                        try {
20171                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20172                                    "Trimming memory of " + app.processName + " to " + curLevel);
20173                            app.thread.scheduleTrimMemory(curLevel);
20174                        } catch (RemoteException e) {
20175                        }
20176                        if (false) {
20177                            // For now we won't do this; our memory trimming seems
20178                            // to be good enough at this point that destroying
20179                            // activities causes more harm than good.
20180                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20181                                    && app != mHomeProcess && app != mPreviousProcess) {
20182                                // Need to do this on its own message because the stack may not
20183                                // be in a consistent state at this point.
20184                                // For these apps we will also finish their activities
20185                                // to help them free memory.
20186                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20187                            }
20188                        }
20189                    }
20190                    app.trimMemoryLevel = curLevel;
20191                    step++;
20192                    if (step >= factor) {
20193                        step = 0;
20194                        switch (curLevel) {
20195                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20196                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20197                                break;
20198                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20199                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20200                                break;
20201                        }
20202                    }
20203                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20204                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20205                            && app.thread != null) {
20206                        try {
20207                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20208                                    "Trimming memory of heavy-weight " + app.processName
20209                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20210                            app.thread.scheduleTrimMemory(
20211                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20212                        } catch (RemoteException e) {
20213                        }
20214                    }
20215                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20216                } else {
20217                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20218                            || app.systemNoUi) && app.pendingUiClean) {
20219                        // If this application is now in the background and it
20220                        // had done UI, then give it the special trim level to
20221                        // have it free UI resources.
20222                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20223                        if (app.trimMemoryLevel < level && app.thread != null) {
20224                            try {
20225                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20226                                        "Trimming memory of bg-ui " + app.processName
20227                                        + " to " + level);
20228                                app.thread.scheduleTrimMemory(level);
20229                            } catch (RemoteException e) {
20230                            }
20231                        }
20232                        app.pendingUiClean = false;
20233                    }
20234                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20235                        try {
20236                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20237                                    "Trimming memory of fg " + app.processName
20238                                    + " to " + fgTrimLevel);
20239                            app.thread.scheduleTrimMemory(fgTrimLevel);
20240                        } catch (RemoteException e) {
20241                        }
20242                    }
20243                    app.trimMemoryLevel = fgTrimLevel;
20244                }
20245            }
20246        } else {
20247            if (mLowRamStartTime != 0) {
20248                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20249                mLowRamStartTime = 0;
20250            }
20251            for (int i=N-1; i>=0; i--) {
20252                ProcessRecord app = mLruProcesses.get(i);
20253                if (allChanged || app.procStateChanged) {
20254                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20255                    app.procStateChanged = false;
20256                }
20257                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20258                        || app.systemNoUi) && app.pendingUiClean) {
20259                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20260                            && app.thread != null) {
20261                        try {
20262                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20263                                    "Trimming memory of ui hidden " + app.processName
20264                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20265                            app.thread.scheduleTrimMemory(
20266                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20267                        } catch (RemoteException e) {
20268                        }
20269                    }
20270                    app.pendingUiClean = false;
20271                }
20272                app.trimMemoryLevel = 0;
20273            }
20274        }
20275
20276        if (mAlwaysFinishActivities) {
20277            // Need to do this on its own message because the stack may not
20278            // be in a consistent state at this point.
20279            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20280        }
20281
20282        if (allChanged) {
20283            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20284        }
20285
20286        // Update from any uid changes.
20287        for (int i=mActiveUids.size()-1; i>=0; i--) {
20288            final UidRecord uidRec = mActiveUids.valueAt(i);
20289            int uidChange = UidRecord.CHANGE_PROCSTATE;
20290            if (uidRec.setProcState != uidRec.curProcState) {
20291                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20292                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20293                        + " to " + uidRec.curProcState);
20294                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20295                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20296                        uidRec.lastBackgroundTime = nowElapsed;
20297                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20298                            // Note: the background settle time is in elapsed realtime, while
20299                            // the handler time base is uptime.  All this means is that we may
20300                            // stop background uids later than we had intended, but that only
20301                            // happens because the device was sleeping so we are okay anyway.
20302                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20303                        }
20304                    }
20305                } else {
20306                    if (uidRec.idle) {
20307                        uidChange = UidRecord.CHANGE_ACTIVE;
20308                        uidRec.idle = false;
20309                    }
20310                    uidRec.lastBackgroundTime = 0;
20311                }
20312                uidRec.setProcState = uidRec.curProcState;
20313                enqueueUidChangeLocked(uidRec, -1, uidChange);
20314                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20315            }
20316        }
20317
20318        if (mProcessStats.shouldWriteNowLocked(now)) {
20319            mHandler.post(new Runnable() {
20320                @Override public void run() {
20321                    synchronized (ActivityManagerService.this) {
20322                        mProcessStats.writeStateAsyncLocked();
20323                    }
20324                }
20325            });
20326        }
20327
20328        if (DEBUG_OOM_ADJ) {
20329            final long duration = SystemClock.uptimeMillis() - now;
20330            if (false) {
20331                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20332                        new RuntimeException("here").fillInStackTrace());
20333            } else {
20334                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20335            }
20336        }
20337    }
20338
20339    final void idleUids() {
20340        synchronized (this) {
20341            final long nowElapsed = SystemClock.elapsedRealtime();
20342            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20343            long nextTime = 0;
20344            for (int i=mActiveUids.size()-1; i>=0; i--) {
20345                final UidRecord uidRec = mActiveUids.valueAt(i);
20346                final long bgTime = uidRec.lastBackgroundTime;
20347                if (bgTime > 0 && !uidRec.idle) {
20348                    if (bgTime <= maxBgTime) {
20349                        uidRec.idle = true;
20350                        doStopUidLocked(uidRec.uid, uidRec);
20351                    } else {
20352                        if (nextTime == 0 || nextTime > bgTime) {
20353                            nextTime = bgTime;
20354                        }
20355                    }
20356                }
20357            }
20358            if (nextTime > 0) {
20359                mHandler.removeMessages(IDLE_UIDS_MSG);
20360                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20361                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20362            }
20363        }
20364    }
20365
20366    final void runInBackgroundDisabled(int uid) {
20367        synchronized (this) {
20368            UidRecord uidRec = mActiveUids.get(uid);
20369            if (uidRec != null) {
20370                // This uid is actually running...  should it be considered background now?
20371                if (uidRec.idle) {
20372                    doStopUidLocked(uidRec.uid, uidRec);
20373                }
20374            } else {
20375                // This uid isn't actually running...  still send a report about it being "stopped".
20376                doStopUidLocked(uid, null);
20377            }
20378        }
20379    }
20380
20381    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20382        mServices.stopInBackgroundLocked(uid);
20383        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20384    }
20385
20386    final void trimApplications() {
20387        synchronized (this) {
20388            int i;
20389
20390            // First remove any unused application processes whose package
20391            // has been removed.
20392            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20393                final ProcessRecord app = mRemovedProcesses.get(i);
20394                if (app.activities.size() == 0
20395                        && app.curReceiver == null && app.services.size() == 0) {
20396                    Slog.i(
20397                        TAG, "Exiting empty application process "
20398                        + app.processName + " ("
20399                        + (app.thread != null ? app.thread.asBinder() : null)
20400                        + ")\n");
20401                    if (app.pid > 0 && app.pid != MY_PID) {
20402                        app.kill("empty", false);
20403                    } else {
20404                        try {
20405                            app.thread.scheduleExit();
20406                        } catch (Exception e) {
20407                            // Ignore exceptions.
20408                        }
20409                    }
20410                    cleanUpApplicationRecordLocked(app, false, true, -1);
20411                    mRemovedProcesses.remove(i);
20412
20413                    if (app.persistent) {
20414                        addAppLocked(app.info, false, null /* ABI override */);
20415                    }
20416                }
20417            }
20418
20419            // Now update the oom adj for all processes.
20420            updateOomAdjLocked();
20421        }
20422    }
20423
20424    /** This method sends the specified signal to each of the persistent apps */
20425    public void signalPersistentProcesses(int sig) throws RemoteException {
20426        if (sig != Process.SIGNAL_USR1) {
20427            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20428        }
20429
20430        synchronized (this) {
20431            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20432                    != PackageManager.PERMISSION_GRANTED) {
20433                throw new SecurityException("Requires permission "
20434                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20435            }
20436
20437            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20438                ProcessRecord r = mLruProcesses.get(i);
20439                if (r.thread != null && r.persistent) {
20440                    Process.sendSignal(r.pid, sig);
20441                }
20442            }
20443        }
20444    }
20445
20446    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20447        if (proc == null || proc == mProfileProc) {
20448            proc = mProfileProc;
20449            profileType = mProfileType;
20450            clearProfilerLocked();
20451        }
20452        if (proc == null) {
20453            return;
20454        }
20455        try {
20456            proc.thread.profilerControl(false, null, profileType);
20457        } catch (RemoteException e) {
20458            throw new IllegalStateException("Process disappeared");
20459        }
20460    }
20461
20462    private void clearProfilerLocked() {
20463        if (mProfileFd != null) {
20464            try {
20465                mProfileFd.close();
20466            } catch (IOException e) {
20467            }
20468        }
20469        mProfileApp = null;
20470        mProfileProc = null;
20471        mProfileFile = null;
20472        mProfileType = 0;
20473        mAutoStopProfiler = false;
20474        mSamplingInterval = 0;
20475    }
20476
20477    public boolean profileControl(String process, int userId, boolean start,
20478            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20479
20480        try {
20481            synchronized (this) {
20482                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20483                // its own permission.
20484                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20485                        != PackageManager.PERMISSION_GRANTED) {
20486                    throw new SecurityException("Requires permission "
20487                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20488                }
20489
20490                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20491                    throw new IllegalArgumentException("null profile info or fd");
20492                }
20493
20494                ProcessRecord proc = null;
20495                if (process != null) {
20496                    proc = findProcessLocked(process, userId, "profileControl");
20497                }
20498
20499                if (start && (proc == null || proc.thread == null)) {
20500                    throw new IllegalArgumentException("Unknown process: " + process);
20501                }
20502
20503                if (start) {
20504                    stopProfilerLocked(null, 0);
20505                    setProfileApp(proc.info, proc.processName, profilerInfo);
20506                    mProfileProc = proc;
20507                    mProfileType = profileType;
20508                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20509                    try {
20510                        fd = fd.dup();
20511                    } catch (IOException e) {
20512                        fd = null;
20513                    }
20514                    profilerInfo.profileFd = fd;
20515                    proc.thread.profilerControl(start, profilerInfo, profileType);
20516                    fd = null;
20517                    mProfileFd = null;
20518                } else {
20519                    stopProfilerLocked(proc, profileType);
20520                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20521                        try {
20522                            profilerInfo.profileFd.close();
20523                        } catch (IOException e) {
20524                        }
20525                    }
20526                }
20527
20528                return true;
20529            }
20530        } catch (RemoteException e) {
20531            throw new IllegalStateException("Process disappeared");
20532        } finally {
20533            if (profilerInfo != null && profilerInfo.profileFd != null) {
20534                try {
20535                    profilerInfo.profileFd.close();
20536                } catch (IOException e) {
20537                }
20538            }
20539        }
20540    }
20541
20542    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20543        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20544                userId, true, ALLOW_FULL_ONLY, callName, null);
20545        ProcessRecord proc = null;
20546        try {
20547            int pid = Integer.parseInt(process);
20548            synchronized (mPidsSelfLocked) {
20549                proc = mPidsSelfLocked.get(pid);
20550            }
20551        } catch (NumberFormatException e) {
20552        }
20553
20554        if (proc == null) {
20555            ArrayMap<String, SparseArray<ProcessRecord>> all
20556                    = mProcessNames.getMap();
20557            SparseArray<ProcessRecord> procs = all.get(process);
20558            if (procs != null && procs.size() > 0) {
20559                proc = procs.valueAt(0);
20560                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20561                    for (int i=1; i<procs.size(); i++) {
20562                        ProcessRecord thisProc = procs.valueAt(i);
20563                        if (thisProc.userId == userId) {
20564                            proc = thisProc;
20565                            break;
20566                        }
20567                    }
20568                }
20569            }
20570        }
20571
20572        return proc;
20573    }
20574
20575    public boolean dumpHeap(String process, int userId, boolean managed,
20576            String path, ParcelFileDescriptor fd) throws RemoteException {
20577
20578        try {
20579            synchronized (this) {
20580                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20581                // its own permission (same as profileControl).
20582                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20583                        != PackageManager.PERMISSION_GRANTED) {
20584                    throw new SecurityException("Requires permission "
20585                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20586                }
20587
20588                if (fd == null) {
20589                    throw new IllegalArgumentException("null fd");
20590                }
20591
20592                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20593                if (proc == null || proc.thread == null) {
20594                    throw new IllegalArgumentException("Unknown process: " + process);
20595                }
20596
20597                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20598                if (!isDebuggable) {
20599                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20600                        throw new SecurityException("Process not debuggable: " + proc);
20601                    }
20602                }
20603
20604                proc.thread.dumpHeap(managed, path, fd);
20605                fd = null;
20606                return true;
20607            }
20608        } catch (RemoteException e) {
20609            throw new IllegalStateException("Process disappeared");
20610        } finally {
20611            if (fd != null) {
20612                try {
20613                    fd.close();
20614                } catch (IOException e) {
20615                }
20616            }
20617        }
20618    }
20619
20620    @Override
20621    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20622            String reportPackage) {
20623        if (processName != null) {
20624            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20625                    "setDumpHeapDebugLimit()");
20626        } else {
20627            synchronized (mPidsSelfLocked) {
20628                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20629                if (proc == null) {
20630                    throw new SecurityException("No process found for calling pid "
20631                            + Binder.getCallingPid());
20632                }
20633                if (!Build.IS_DEBUGGABLE
20634                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20635                    throw new SecurityException("Not running a debuggable build");
20636                }
20637                processName = proc.processName;
20638                uid = proc.uid;
20639                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20640                    throw new SecurityException("Package " + reportPackage + " is not running in "
20641                            + proc);
20642                }
20643            }
20644        }
20645        synchronized (this) {
20646            if (maxMemSize > 0) {
20647                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20648            } else {
20649                if (uid != 0) {
20650                    mMemWatchProcesses.remove(processName, uid);
20651                } else {
20652                    mMemWatchProcesses.getMap().remove(processName);
20653                }
20654            }
20655        }
20656    }
20657
20658    @Override
20659    public void dumpHeapFinished(String path) {
20660        synchronized (this) {
20661            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20662                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20663                        + " does not match last pid " + mMemWatchDumpPid);
20664                return;
20665            }
20666            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20667                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20668                        + " does not match last path " + mMemWatchDumpFile);
20669                return;
20670            }
20671            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20672            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20673        }
20674    }
20675
20676    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20677    public void monitor() {
20678        synchronized (this) { }
20679    }
20680
20681    void onCoreSettingsChange(Bundle settings) {
20682        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20683            ProcessRecord processRecord = mLruProcesses.get(i);
20684            try {
20685                if (processRecord.thread != null) {
20686                    processRecord.thread.setCoreSettings(settings);
20687                }
20688            } catch (RemoteException re) {
20689                /* ignore */
20690            }
20691        }
20692    }
20693
20694    // Multi-user methods
20695
20696    /**
20697     * Start user, if its not already running, but don't bring it to foreground.
20698     */
20699    @Override
20700    public boolean startUserInBackground(final int userId) {
20701        return mUserController.startUser(userId, /* foreground */ false);
20702    }
20703
20704    @Override
20705    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20706        return mUserController.unlockUser(userId, token, secret, listener);
20707    }
20708
20709    @Override
20710    public boolean switchUser(final int targetUserId) {
20711        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20712        UserInfo currentUserInfo;
20713        UserInfo targetUserInfo;
20714        synchronized (this) {
20715            int currentUserId = mUserController.getCurrentUserIdLocked();
20716            currentUserInfo = mUserController.getUserInfo(currentUserId);
20717            targetUserInfo = mUserController.getUserInfo(targetUserId);
20718            if (targetUserInfo == null) {
20719                Slog.w(TAG, "No user info for user #" + targetUserId);
20720                return false;
20721            }
20722            if (!targetUserInfo.supportsSwitchTo()) {
20723                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20724                return false;
20725            }
20726            if (targetUserInfo.isManagedProfile()) {
20727                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20728                return false;
20729            }
20730            mUserController.setTargetUserIdLocked(targetUserId);
20731        }
20732        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20733        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20734        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20735        return true;
20736    }
20737
20738    void scheduleStartProfilesLocked() {
20739        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20740            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20741                    DateUtils.SECOND_IN_MILLIS);
20742        }
20743    }
20744
20745    @Override
20746    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20747        return mUserController.stopUser(userId, force, callback);
20748    }
20749
20750    @Override
20751    public UserInfo getCurrentUser() {
20752        return mUserController.getCurrentUser();
20753    }
20754
20755    @Override
20756    public boolean isUserRunning(int userId, int flags) {
20757        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20758                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20759            String msg = "Permission Denial: isUserRunning() from pid="
20760                    + Binder.getCallingPid()
20761                    + ", uid=" + Binder.getCallingUid()
20762                    + " requires " + INTERACT_ACROSS_USERS;
20763            Slog.w(TAG, msg);
20764            throw new SecurityException(msg);
20765        }
20766        synchronized (this) {
20767            return mUserController.isUserRunningLocked(userId, flags);
20768        }
20769    }
20770
20771    @Override
20772    public int[] getRunningUserIds() {
20773        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20774                != PackageManager.PERMISSION_GRANTED) {
20775            String msg = "Permission Denial: isUserRunning() from pid="
20776                    + Binder.getCallingPid()
20777                    + ", uid=" + Binder.getCallingUid()
20778                    + " requires " + INTERACT_ACROSS_USERS;
20779            Slog.w(TAG, msg);
20780            throw new SecurityException(msg);
20781        }
20782        synchronized (this) {
20783            return mUserController.getStartedUserArrayLocked();
20784        }
20785    }
20786
20787    @Override
20788    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20789        mUserController.registerUserSwitchObserver(observer);
20790    }
20791
20792    @Override
20793    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20794        mUserController.unregisterUserSwitchObserver(observer);
20795    }
20796
20797    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20798        if (info == null) return null;
20799        ApplicationInfo newInfo = new ApplicationInfo(info);
20800        newInfo.initForUser(userId);
20801        return newInfo;
20802    }
20803
20804    public boolean isUserStopped(int userId) {
20805        synchronized (this) {
20806            return mUserController.getStartedUserStateLocked(userId) == null;
20807        }
20808    }
20809
20810    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20811        if (aInfo == null
20812                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20813            return aInfo;
20814        }
20815
20816        ActivityInfo info = new ActivityInfo(aInfo);
20817        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20818        return info;
20819    }
20820
20821    private boolean processSanityChecksLocked(ProcessRecord process) {
20822        if (process == null || process.thread == null) {
20823            return false;
20824        }
20825
20826        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20827        if (!isDebuggable) {
20828            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20829                return false;
20830            }
20831        }
20832
20833        return true;
20834    }
20835
20836    public boolean startBinderTracking() throws RemoteException {
20837        synchronized (this) {
20838            mBinderTransactionTrackingEnabled = true;
20839            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20840            // permission (same as profileControl).
20841            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20842                    != PackageManager.PERMISSION_GRANTED) {
20843                throw new SecurityException("Requires permission "
20844                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20845            }
20846
20847            for (int i = 0; i < mLruProcesses.size(); i++) {
20848                ProcessRecord process = mLruProcesses.get(i);
20849                if (!processSanityChecksLocked(process)) {
20850                    continue;
20851                }
20852                try {
20853                    process.thread.startBinderTracking();
20854                } catch (RemoteException e) {
20855                    Log.v(TAG, "Process disappared");
20856                }
20857            }
20858            return true;
20859        }
20860    }
20861
20862    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20863        try {
20864            synchronized (this) {
20865                mBinderTransactionTrackingEnabled = false;
20866                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20867                // permission (same as profileControl).
20868                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20869                        != PackageManager.PERMISSION_GRANTED) {
20870                    throw new SecurityException("Requires permission "
20871                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20872                }
20873
20874                if (fd == null) {
20875                    throw new IllegalArgumentException("null fd");
20876                }
20877
20878                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20879                pw.println("Binder transaction traces for all processes.\n");
20880                for (ProcessRecord process : mLruProcesses) {
20881                    if (!processSanityChecksLocked(process)) {
20882                        continue;
20883                    }
20884
20885                    pw.println("Traces for process: " + process.processName);
20886                    pw.flush();
20887                    try {
20888                        TransferPipe tp = new TransferPipe();
20889                        try {
20890                            process.thread.stopBinderTrackingAndDump(
20891                                    tp.getWriteFd().getFileDescriptor());
20892                            tp.go(fd.getFileDescriptor());
20893                        } finally {
20894                            tp.kill();
20895                        }
20896                    } catch (IOException e) {
20897                        pw.println("Failure while dumping IPC traces from " + process +
20898                                ".  Exception: " + e);
20899                        pw.flush();
20900                    } catch (RemoteException e) {
20901                        pw.println("Got a RemoteException while dumping IPC traces from " +
20902                                process + ".  Exception: " + e);
20903                        pw.flush();
20904                    }
20905                }
20906                fd = null;
20907                return true;
20908            }
20909        } finally {
20910            if (fd != null) {
20911                try {
20912                    fd.close();
20913                } catch (IOException e) {
20914                }
20915            }
20916        }
20917    }
20918
20919    private final class LocalService extends ActivityManagerInternal {
20920        @Override
20921        public void onWakefulnessChanged(int wakefulness) {
20922            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20923        }
20924
20925        @Override
20926        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20927                String processName, String abiOverride, int uid, Runnable crashHandler) {
20928            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20929                    processName, abiOverride, uid, crashHandler);
20930        }
20931
20932        @Override
20933        public SleepToken acquireSleepToken(String tag) {
20934            Preconditions.checkNotNull(tag);
20935
20936            synchronized (ActivityManagerService.this) {
20937                SleepTokenImpl token = new SleepTokenImpl(tag);
20938                mSleepTokens.add(token);
20939                updateSleepIfNeededLocked();
20940                applyVrModeIfNeededLocked(mFocusedActivity, false);
20941                return token;
20942            }
20943        }
20944
20945        @Override
20946        public ComponentName getHomeActivityForUser(int userId) {
20947            synchronized (ActivityManagerService.this) {
20948                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20949                return homeActivity == null ? null : homeActivity.realActivity;
20950            }
20951        }
20952
20953        @Override
20954        public void onUserRemoved(int userId) {
20955            synchronized (ActivityManagerService.this) {
20956                ActivityManagerService.this.onUserStoppedLocked(userId);
20957            }
20958        }
20959
20960        @Override
20961        public void onLocalVoiceInteractionStarted(IBinder activity,
20962                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20963            synchronized (ActivityManagerService.this) {
20964                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20965                        voiceSession, voiceInteractor);
20966            }
20967        }
20968
20969        @Override
20970        public void notifyStartingWindowDrawn() {
20971            synchronized (ActivityManagerService.this) {
20972                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20973            }
20974        }
20975
20976        @Override
20977        public void notifyAppTransitionStarting(int reason) {
20978            synchronized (ActivityManagerService.this) {
20979                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20980            }
20981        }
20982
20983        @Override
20984        public void notifyAppTransitionFinished() {
20985            synchronized (ActivityManagerService.this) {
20986                mStackSupervisor.notifyAppTransitionDone();
20987            }
20988        }
20989
20990        @Override
20991        public void notifyAppTransitionCancelled() {
20992            synchronized (ActivityManagerService.this) {
20993                mStackSupervisor.notifyAppTransitionDone();
20994            }
20995        }
20996
20997        @Override
20998        public List<IBinder> getTopVisibleActivities() {
20999            synchronized (ActivityManagerService.this) {
21000                return mStackSupervisor.getTopVisibleActivities();
21001            }
21002        }
21003
21004        @Override
21005        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21006            synchronized (ActivityManagerService.this) {
21007                mStackSupervisor.setDockedStackMinimized(minimized);
21008            }
21009        }
21010
21011        @Override
21012        public void killForegroundAppsForUser(int userHandle) {
21013            synchronized (ActivityManagerService.this) {
21014                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21015                final int NP = mProcessNames.getMap().size();
21016                for (int ip = 0; ip < NP; ip++) {
21017                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21018                    final int NA = apps.size();
21019                    for (int ia = 0; ia < NA; ia++) {
21020                        final ProcessRecord app = apps.valueAt(ia);
21021                        if (app.persistent) {
21022                            // We don't kill persistent processes.
21023                            continue;
21024                        }
21025                        if (app.removed) {
21026                            procs.add(app);
21027                        } else if (app.userId == userHandle && app.foregroundActivities) {
21028                            app.removed = true;
21029                            procs.add(app);
21030                        }
21031                    }
21032                }
21033
21034                final int N = procs.size();
21035                for (int i = 0; i < N; i++) {
21036                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21037                }
21038            }
21039        }
21040    }
21041
21042    private final class SleepTokenImpl extends SleepToken {
21043        private final String mTag;
21044        private final long mAcquireTime;
21045
21046        public SleepTokenImpl(String tag) {
21047            mTag = tag;
21048            mAcquireTime = SystemClock.uptimeMillis();
21049        }
21050
21051        @Override
21052        public void release() {
21053            synchronized (ActivityManagerService.this) {
21054                if (mSleepTokens.remove(this)) {
21055                    updateSleepIfNeededLocked();
21056                }
21057            }
21058        }
21059
21060        @Override
21061        public String toString() {
21062            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21063        }
21064    }
21065
21066    /**
21067     * An implementation of IAppTask, that allows an app to manage its own tasks via
21068     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21069     * only the process that calls getAppTasks() can call the AppTask methods.
21070     */
21071    class AppTaskImpl extends IAppTask.Stub {
21072        private int mTaskId;
21073        private int mCallingUid;
21074
21075        public AppTaskImpl(int taskId, int callingUid) {
21076            mTaskId = taskId;
21077            mCallingUid = callingUid;
21078        }
21079
21080        private void checkCaller() {
21081            if (mCallingUid != Binder.getCallingUid()) {
21082                throw new SecurityException("Caller " + mCallingUid
21083                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21084            }
21085        }
21086
21087        @Override
21088        public void finishAndRemoveTask() {
21089            checkCaller();
21090
21091            synchronized (ActivityManagerService.this) {
21092                long origId = Binder.clearCallingIdentity();
21093                try {
21094                    // We remove the task from recents to preserve backwards
21095                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21096                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21097                    }
21098                } finally {
21099                    Binder.restoreCallingIdentity(origId);
21100                }
21101            }
21102        }
21103
21104        @Override
21105        public ActivityManager.RecentTaskInfo getTaskInfo() {
21106            checkCaller();
21107
21108            synchronized (ActivityManagerService.this) {
21109                long origId = Binder.clearCallingIdentity();
21110                try {
21111                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21112                    if (tr == null) {
21113                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21114                    }
21115                    return createRecentTaskInfoFromTaskRecord(tr);
21116                } finally {
21117                    Binder.restoreCallingIdentity(origId);
21118                }
21119            }
21120        }
21121
21122        @Override
21123        public void moveToFront() {
21124            checkCaller();
21125            // Will bring task to front if it already has a root activity.
21126            final long origId = Binder.clearCallingIdentity();
21127            try {
21128                synchronized (this) {
21129                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21130                }
21131            } finally {
21132                Binder.restoreCallingIdentity(origId);
21133            }
21134        }
21135
21136        @Override
21137        public int startActivity(IBinder whoThread, String callingPackage,
21138                Intent intent, String resolvedType, Bundle bOptions) {
21139            checkCaller();
21140
21141            int callingUser = UserHandle.getCallingUserId();
21142            TaskRecord tr;
21143            IApplicationThread appThread;
21144            synchronized (ActivityManagerService.this) {
21145                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21146                if (tr == null) {
21147                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21148                }
21149                appThread = ApplicationThreadNative.asInterface(whoThread);
21150                if (appThread == null) {
21151                    throw new IllegalArgumentException("Bad app thread " + appThread);
21152                }
21153            }
21154            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21155                    resolvedType, null, null, null, null, 0, 0, null, null,
21156                    null, bOptions, false, callingUser, null, tr);
21157        }
21158
21159        @Override
21160        public void setExcludeFromRecents(boolean exclude) {
21161            checkCaller();
21162
21163            synchronized (ActivityManagerService.this) {
21164                long origId = Binder.clearCallingIdentity();
21165                try {
21166                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21167                    if (tr == null) {
21168                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21169                    }
21170                    Intent intent = tr.getBaseIntent();
21171                    if (exclude) {
21172                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21173                    } else {
21174                        intent.setFlags(intent.getFlags()
21175                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21176                    }
21177                } finally {
21178                    Binder.restoreCallingIdentity(origId);
21179                }
21180            }
21181        }
21182    }
21183
21184    /**
21185     * Kill processes for the user with id userId and that depend on the package named packageName
21186     */
21187    @Override
21188    public void killPackageDependents(String packageName, int userId) {
21189        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21190        if (packageName == null) {
21191            throw new NullPointerException(
21192                    "Cannot kill the dependents of a package without its name.");
21193        }
21194
21195        long callingId = Binder.clearCallingIdentity();
21196        IPackageManager pm = AppGlobals.getPackageManager();
21197        int pkgUid = -1;
21198        try {
21199            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21200        } catch (RemoteException e) {
21201        }
21202        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21203            throw new IllegalArgumentException(
21204                    "Cannot kill dependents of non-existing package " + packageName);
21205        }
21206        try {
21207            synchronized(this) {
21208                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21209                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21210                        "dep: " + packageName);
21211            }
21212        } finally {
21213            Binder.restoreCallingIdentity(callingId);
21214        }
21215    }
21216}
21217