ActivityManagerService.java revision c043ebee4b4b5851898667a92fdfca34a4d64e52
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.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.text.format.DateUtils;
200import android.text.format.Time;
201import android.util.ArrayMap;
202import android.util.ArraySet;
203import android.util.AtomicFile;
204import android.util.DebugUtils;
205import android.util.EventLog;
206import android.util.LocaleList;
207import android.util.Log;
208import android.util.Pair;
209import android.util.PrintWriterPrinter;
210import android.util.Slog;
211import android.util.SparseArray;
212import android.util.TimeUtils;
213import android.util.Xml;
214import android.view.Display;
215import android.view.Gravity;
216import android.view.LayoutInflater;
217import android.view.View;
218import android.view.WindowManager;
219
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
344import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
345import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
346import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
347import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
348import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
349import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
350import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
354import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
359import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
360import static org.xmlpull.v1.XmlPullParser.START_TAG;
361
362public final class ActivityManagerService extends ActivityManagerNative
363        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
364
365    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
366    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
367    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
368    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
369    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
370    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
371    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
372    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
373    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
374    private static final String TAG_LRU = TAG + POSTFIX_LRU;
375    private static final String TAG_MU = TAG + POSTFIX_MU;
376    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
377    private static final String TAG_POWER = TAG + POSTFIX_POWER;
378    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
379    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
380    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
381    private static final String TAG_PSS = TAG + POSTFIX_PSS;
382    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
383    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
384    private static final String TAG_STACK = TAG + POSTFIX_STACK;
385    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
386    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
387    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
388    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
389    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
390
391    /** Control over CPU and battery monitoring */
392    // write battery stats every 30 minutes.
393    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
394    static final boolean MONITOR_CPU_USAGE = true;
395    // don't sample cpu less than every 5 seconds.
396    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
397    // wait possibly forever for next cpu sample.
398    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
399    static final boolean MONITOR_THREAD_CPU_USAGE = false;
400
401    // The flags that are set for all calls we make to the package manager.
402    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
403
404    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
405
406    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
407
408    // Amount of time after a call to stopAppSwitches() during which we will
409    // prevent further untrusted switches from happening.
410    static final long APP_SWITCH_DELAY_TIME = 5*1000;
411
412    // How long we wait for a launched process to attach to the activity manager
413    // before we decide it's never going to come up for real.
414    static final int PROC_START_TIMEOUT = 10*1000;
415    // How long we wait for an attached process to publish its content providers
416    // before we decide it must be hung.
417    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
418
419    // How long we will retain processes hosting content providers in the "last activity"
420    // state before allowing them to drop down to the regular cached LRU list.  This is
421    // to avoid thrashing of provider processes under low memory situations.
422    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
423
424    // How long we wait for a launched process to attach to the activity manager
425    // before we decide it's never going to come up for real, when the process was
426    // started with a wrapper for instrumentation (such as Valgrind) because it
427    // could take much longer than usual.
428    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
429
430    // How long to wait after going idle before forcing apps to GC.
431    static final int GC_TIMEOUT = 5*1000;
432
433    // The minimum amount of time between successive GC requests for a process.
434    static final int GC_MIN_INTERVAL = 60*1000;
435
436    // The minimum amount of time between successive PSS requests for a process.
437    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
438
439    // The minimum amount of time between successive PSS requests for a process
440    // when the request is due to the memory state being lowered.
441    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
442
443    // The rate at which we check for apps using excessive power -- 15 mins.
444    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
445
446    // The minimum sample duration we will allow before deciding we have
447    // enough data on wake locks to start killing things.
448    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
449
450    // The minimum sample duration we will allow before deciding we have
451    // enough data on CPU usage to start killing things.
452    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
453
454    // How long we allow a receiver to run before giving up on it.
455    static final int BROADCAST_FG_TIMEOUT = 10*1000;
456    static final int BROADCAST_BG_TIMEOUT = 60*1000;
457
458    // How long we wait until we timeout on key dispatching.
459    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
460
461    // How long we wait until we timeout on key dispatching during instrumentation.
462    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
463
464    // This is the amount of time an app needs to be running a foreground service before
465    // we will consider it to be doing interaction for usage stats.
466    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
467
468    // Maximum amount of time we will allow to elapse before re-reporting usage stats
469    // interaction with foreground processes.
470    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
471
472    // This is the amount of time we allow an app to settle after it goes into the background,
473    // before we start restricting what it can do.
474    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
475
476    // How long to wait in getAssistContextExtras for the activity and foreground services
477    // to respond with the result.
478    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
479
480    // How long top wait when going through the modern assist (which doesn't need to block
481    // on getting this result before starting to launch its UI).
482    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
483
484    // Maximum number of persisted Uri grants a package is allowed
485    static final int MAX_PERSISTED_URI_GRANTS = 128;
486
487    static final int MY_PID = Process.myPid();
488
489    static final String[] EMPTY_STRING_ARRAY = new String[0];
490
491    // How many bytes to write into the dropbox log before truncating
492    static final int DROPBOX_MAX_SIZE = 256 * 1024;
493
494    // Access modes for handleIncomingUser.
495    static final int ALLOW_NON_FULL = 0;
496    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
497    static final int ALLOW_FULL_ONLY = 2;
498
499    // Delay in notifying task stack change listeners (in millis)
500    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
501
502    // Necessary ApplicationInfo flags to mark an app as persistent
503    private static final int PERSISTENT_MASK =
504            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
505
506    // Intent sent when remote bugreport collection has been completed
507    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
508            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
509
510    // Delay to disable app launch boost
511    static final int APP_BOOST_MESSAGE_DELAY = 3000;
512    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
513    static final int APP_BOOST_TIMEOUT = 2500;
514
515    // Used to indicate that a task is removed it should also be removed from recents.
516    private static final boolean REMOVE_FROM_RECENTS = true;
517    // Used to indicate that an app transition should be animated.
518    static final boolean ANIMATE = true;
519
520    // Determines whether to take full screen screenshots
521    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
522    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
523
524    private static native int nativeMigrateToBoost();
525    private static native int nativeMigrateFromBoost();
526    private boolean mIsBoosted = false;
527    private long mBoostStartTime = 0;
528
529    /** All system services */
530    SystemServiceManager mSystemServiceManager;
531
532    private Installer mInstaller;
533
534    /** Run all ActivityStacks through this */
535    final ActivityStackSupervisor mStackSupervisor;
536
537    final ActivityStarter mActivityStarter;
538
539    /** Task stack change listeners. */
540    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
541            new RemoteCallbackList<ITaskStackListener>();
542
543    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
544
545    public IntentFirewall mIntentFirewall;
546
547    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
548    // default actuion automatically.  Important for devices without direct input
549    // devices.
550    private boolean mShowDialogs = true;
551    private boolean mInVrMode = false;
552
553    BroadcastQueue mFgBroadcastQueue;
554    BroadcastQueue mBgBroadcastQueue;
555    // Convenient for easy iteration over the queues. Foreground is first
556    // so that dispatch of foreground broadcasts gets precedence.
557    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
558
559    BroadcastQueue broadcastQueueForIntent(Intent intent) {
560        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
561        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
562                "Broadcast intent " + intent + " on "
563                + (isFg ? "foreground" : "background") + " queue");
564        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
565    }
566
567    /**
568     * Activity we have told the window manager to have key focus.
569     */
570    ActivityRecord mFocusedActivity = null;
571
572    /**
573     * User id of the last activity mFocusedActivity was set to.
574     */
575    private int mLastFocusedUserId;
576
577    /**
578     * If non-null, we are tracking the time the user spends in the currently focused app.
579     */
580    private AppTimeTracker mCurAppTimeTracker;
581
582    /**
583     * List of intents that were used to start the most recent tasks.
584     */
585    final RecentTasks mRecentTasks;
586
587    /**
588     * For addAppTask: cached of the last activity component that was added.
589     */
590    ComponentName mLastAddedTaskComponent;
591
592    /**
593     * For addAppTask: cached of the last activity uid that was added.
594     */
595    int mLastAddedTaskUid;
596
597    /**
598     * For addAppTask: cached of the last ActivityInfo that was added.
599     */
600    ActivityInfo mLastAddedTaskActivity;
601
602    /**
603     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
604     */
605    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
606
607    /**
608     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
609     */
610    String mDeviceOwnerName;
611
612    final UserController mUserController;
613
614    final AppErrors mAppErrors;
615
616    boolean mDoingSetFocusedActivity;
617
618    public boolean canShowErrorDialogs() {
619        return mShowDialogs && !mSleeping && !mShuttingDown;
620    }
621
622    public class PendingAssistExtras extends Binder implements Runnable {
623        public final ActivityRecord activity;
624        public final Bundle extras;
625        public final Intent intent;
626        public final String hint;
627        public final IResultReceiver receiver;
628        public final int userHandle;
629        public boolean haveResult = false;
630        public Bundle result = null;
631        public AssistStructure structure = null;
632        public AssistContent content = null;
633        public Bundle receiverExtras;
634
635        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
636                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
637            activity = _activity;
638            extras = _extras;
639            intent = _intent;
640            hint = _hint;
641            receiver = _receiver;
642            receiverExtras = _receiverExtras;
643            userHandle = _userHandle;
644        }
645        @Override
646        public void run() {
647            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
648            synchronized (this) {
649                haveResult = true;
650                notifyAll();
651            }
652            pendingAssistExtrasTimedOut(this);
653        }
654    }
655
656    final ArrayList<PendingAssistExtras> mPendingAssistExtras
657            = new ArrayList<PendingAssistExtras>();
658
659    /**
660     * Process management.
661     */
662    final ProcessList mProcessList = new ProcessList();
663
664    /**
665     * All of the applications we currently have running organized by name.
666     * The keys are strings of the application package name (as
667     * returned by the package manager), and the keys are ApplicationRecord
668     * objects.
669     */
670    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
671
672    /**
673     * Tracking long-term execution of processes to look for abuse and other
674     * bad app behavior.
675     */
676    final ProcessStatsService mProcessStats;
677
678    /**
679     * The currently running isolated processes.
680     */
681    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
682
683    /**
684     * Counter for assigning isolated process uids, to avoid frequently reusing the
685     * same ones.
686     */
687    int mNextIsolatedProcessUid = 0;
688
689    /**
690     * The currently running heavy-weight process, if any.
691     */
692    ProcessRecord mHeavyWeightProcess = null;
693
694    /**
695     * All of the processes we currently have running organized by pid.
696     * The keys are the pid running the application.
697     *
698     * <p>NOTE: This object is protected by its own lock, NOT the global
699     * activity manager lock!
700     */
701    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
702
703    /**
704     * All of the processes that have been forced to be foreground.  The key
705     * is the pid of the caller who requested it (we hold a death
706     * link on it).
707     */
708    abstract class ForegroundToken implements IBinder.DeathRecipient {
709        int pid;
710        IBinder token;
711    }
712    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
713
714    /**
715     * List of records for processes that someone had tried to start before the
716     * system was ready.  We don't start them at that point, but ensure they
717     * are started by the time booting is complete.
718     */
719    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
720
721    /**
722     * List of persistent applications that are in the process
723     * of being started.
724     */
725    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
726
727    /**
728     * Processes that are being forcibly torn down.
729     */
730    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
731
732    /**
733     * List of running applications, sorted by recent usage.
734     * The first entry in the list is the least recently used.
735     */
736    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
737
738    /**
739     * Where in mLruProcesses that the processes hosting activities start.
740     */
741    int mLruProcessActivityStart = 0;
742
743    /**
744     * Where in mLruProcesses that the processes hosting services start.
745     * This is after (lower index) than mLruProcessesActivityStart.
746     */
747    int mLruProcessServiceStart = 0;
748
749    /**
750     * List of processes that should gc as soon as things are idle.
751     */
752    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
753
754    /**
755     * Processes we want to collect PSS data from.
756     */
757    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
758
759    private boolean mBinderTransactionTrackingEnabled = false;
760
761    /**
762     * Last time we requested PSS data of all processes.
763     */
764    long mLastFullPssTime = SystemClock.uptimeMillis();
765
766    /**
767     * If set, the next time we collect PSS data we should do a full collection
768     * with data from native processes and the kernel.
769     */
770    boolean mFullPssPending = false;
771
772    /**
773     * This is the process holding what we currently consider to be
774     * the "home" activity.
775     */
776    ProcessRecord mHomeProcess;
777
778    /**
779     * This is the process holding the activity the user last visited that
780     * is in a different process from the one they are currently in.
781     */
782    ProcessRecord mPreviousProcess;
783
784    /**
785     * The time at which the previous process was last visible.
786     */
787    long mPreviousProcessVisibleTime;
788
789    /**
790     * Track all uids that have actively running processes.
791     */
792    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
793
794    /**
795     * This is for verifying the UID report flow.
796     */
797    static final boolean VALIDATE_UID_STATES = true;
798    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
799
800    /**
801     * Packages that the user has asked to have run in screen size
802     * compatibility mode instead of filling the screen.
803     */
804    final CompatModePackages mCompatModePackages;
805
806    /**
807     * Set of IntentSenderRecord objects that are currently active.
808     */
809    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
810            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
811
812    /**
813     * Fingerprints (hashCode()) of stack traces that we've
814     * already logged DropBox entries for.  Guarded by itself.  If
815     * something (rogue user app) forces this over
816     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
817     */
818    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
819    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
820
821    /**
822     * Strict Mode background batched logging state.
823     *
824     * The string buffer is guarded by itself, and its lock is also
825     * used to determine if another batched write is already
826     * in-flight.
827     */
828    private final StringBuilder mStrictModeBuffer = new StringBuilder();
829
830    /**
831     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
832     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
833     */
834    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
835
836    /**
837     * Resolver for broadcast intents to registered receivers.
838     * Holds BroadcastFilter (subclass of IntentFilter).
839     */
840    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
841            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
842        @Override
843        protected boolean allowFilterResult(
844                BroadcastFilter filter, List<BroadcastFilter> dest) {
845            IBinder target = filter.receiverList.receiver.asBinder();
846            for (int i = dest.size() - 1; i >= 0; i--) {
847                if (dest.get(i).receiverList.receiver.asBinder() == target) {
848                    return false;
849                }
850            }
851            return true;
852        }
853
854        @Override
855        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
856            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
857                    || userId == filter.owningUserId) {
858                return super.newResult(filter, match, userId);
859            }
860            return null;
861        }
862
863        @Override
864        protected BroadcastFilter[] newArray(int size) {
865            return new BroadcastFilter[size];
866        }
867
868        @Override
869        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
870            return packageName.equals(filter.packageName);
871        }
872    };
873
874    /**
875     * State of all active sticky broadcasts per user.  Keys are the action of the
876     * sticky Intent, values are an ArrayList of all broadcasted intents with
877     * that action (which should usually be one).  The SparseArray is keyed
878     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
879     * for stickies that are sent to all users.
880     */
881    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
882            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
883
884    final ActiveServices mServices;
885
886    final static class Association {
887        final int mSourceUid;
888        final String mSourceProcess;
889        final int mTargetUid;
890        final ComponentName mTargetComponent;
891        final String mTargetProcess;
892
893        int mCount;
894        long mTime;
895
896        int mNesting;
897        long mStartTime;
898
899        // states of the source process when the bind occurred.
900        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
901        long mLastStateUptime;
902        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
903                - ActivityManager.MIN_PROCESS_STATE+1];
904
905        Association(int sourceUid, String sourceProcess, int targetUid,
906                ComponentName targetComponent, String targetProcess) {
907            mSourceUid = sourceUid;
908            mSourceProcess = sourceProcess;
909            mTargetUid = targetUid;
910            mTargetComponent = targetComponent;
911            mTargetProcess = targetProcess;
912        }
913    }
914
915    /**
916     * When service association tracking is enabled, this is all of the associations we
917     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
918     * -> association data.
919     */
920    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
921            mAssociations = new SparseArray<>();
922    boolean mTrackingAssociations;
923
924    /**
925     * Backup/restore process management
926     */
927    String mBackupAppName = null;
928    BackupRecord mBackupTarget = null;
929
930    final ProviderMap mProviderMap;
931
932    /**
933     * List of content providers who have clients waiting for them.  The
934     * application is currently being launched and the provider will be
935     * removed from this list once it is published.
936     */
937    final ArrayList<ContentProviderRecord> mLaunchingProviders
938            = new ArrayList<ContentProviderRecord>();
939
940    /**
941     * File storing persisted {@link #mGrantedUriPermissions}.
942     */
943    private final AtomicFile mGrantFile;
944
945    /** XML constants used in {@link #mGrantFile} */
946    private static final String TAG_URI_GRANTS = "uri-grants";
947    private static final String TAG_URI_GRANT = "uri-grant";
948    private static final String ATTR_USER_HANDLE = "userHandle";
949    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
950    private static final String ATTR_TARGET_USER_ID = "targetUserId";
951    private static final String ATTR_SOURCE_PKG = "sourcePkg";
952    private static final String ATTR_TARGET_PKG = "targetPkg";
953    private static final String ATTR_URI = "uri";
954    private static final String ATTR_MODE_FLAGS = "modeFlags";
955    private static final String ATTR_CREATED_TIME = "createdTime";
956    private static final String ATTR_PREFIX = "prefix";
957
958    /**
959     * Global set of specific {@link Uri} permissions that have been granted.
960     * This optimized lookup structure maps from {@link UriPermission#targetUid}
961     * to {@link UriPermission#uri} to {@link UriPermission}.
962     */
963    @GuardedBy("this")
964    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
965            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
966
967    public static class GrantUri {
968        public final int sourceUserId;
969        public final Uri uri;
970        public boolean prefix;
971
972        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
973            this.sourceUserId = sourceUserId;
974            this.uri = uri;
975            this.prefix = prefix;
976        }
977
978        @Override
979        public int hashCode() {
980            int hashCode = 1;
981            hashCode = 31 * hashCode + sourceUserId;
982            hashCode = 31 * hashCode + uri.hashCode();
983            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
984            return hashCode;
985        }
986
987        @Override
988        public boolean equals(Object o) {
989            if (o instanceof GrantUri) {
990                GrantUri other = (GrantUri) o;
991                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
992                        && prefix == other.prefix;
993            }
994            return false;
995        }
996
997        @Override
998        public String toString() {
999            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1000            if (prefix) result += " [prefix]";
1001            return result;
1002        }
1003
1004        public String toSafeString() {
1005            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1006            if (prefix) result += " [prefix]";
1007            return result;
1008        }
1009
1010        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1011            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1012                    ContentProvider.getUriWithoutUserId(uri), false);
1013        }
1014    }
1015
1016    CoreSettingsObserver mCoreSettingsObserver;
1017
1018    FontScaleSettingObserver mFontScaleSettingObserver;
1019
1020    private final class FontScaleSettingObserver extends ContentObserver {
1021        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1022
1023        public FontScaleSettingObserver() {
1024            super(mHandler);
1025            ContentResolver resolver = mContext.getContentResolver();
1026            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1027        }
1028
1029        @Override
1030        public void onChange(boolean selfChange, Uri uri) {
1031            if (mFontScaleUri.equals(uri)) {
1032                updateFontScaleIfNeeded();
1033            }
1034        }
1035    }
1036
1037    /**
1038     * Thread-local storage used to carry caller permissions over through
1039     * indirect content-provider access.
1040     */
1041    private class Identity {
1042        public final IBinder token;
1043        public final int pid;
1044        public final int uid;
1045
1046        Identity(IBinder _token, int _pid, int _uid) {
1047            token = _token;
1048            pid = _pid;
1049            uid = _uid;
1050        }
1051    }
1052
1053    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1054
1055    /**
1056     * All information we have collected about the runtime performance of
1057     * any user id that can impact battery performance.
1058     */
1059    final BatteryStatsService mBatteryStatsService;
1060
1061    /**
1062     * Information about component usage
1063     */
1064    UsageStatsManagerInternal mUsageStatsService;
1065
1066    /**
1067     * Access to DeviceIdleController service.
1068     */
1069    DeviceIdleController.LocalService mLocalDeviceIdleController;
1070
1071    /**
1072     * Information about and control over application operations
1073     */
1074    final AppOpsService mAppOpsService;
1075
1076    /**
1077     * Current configuration information.  HistoryRecord objects are given
1078     * a reference to this object to indicate which configuration they are
1079     * currently running in, so this object must be kept immutable.
1080     */
1081    Configuration mConfiguration = new Configuration();
1082
1083    /**
1084     * Current sequencing integer of the configuration, for skipping old
1085     * configurations.
1086     */
1087    int mConfigurationSeq = 0;
1088
1089    boolean mSuppressResizeConfigChanges = false;
1090
1091    /**
1092     * Hardware-reported OpenGLES version.
1093     */
1094    final int GL_ES_VERSION;
1095
1096    /**
1097     * List of initialization arguments to pass to all processes when binding applications to them.
1098     * For example, references to the commonly used services.
1099     */
1100    HashMap<String, IBinder> mAppBindArgs;
1101
1102    /**
1103     * Temporary to avoid allocations.  Protected by main lock.
1104     */
1105    final StringBuilder mStringBuilder = new StringBuilder(256);
1106
1107    /**
1108     * Used to control how we initialize the service.
1109     */
1110    ComponentName mTopComponent;
1111    String mTopAction = Intent.ACTION_MAIN;
1112    String mTopData;
1113
1114    volatile boolean mProcessesReady = false;
1115    volatile boolean mSystemReady = false;
1116    volatile boolean mOnBattery = false;
1117    volatile int mFactoryTest;
1118
1119    @GuardedBy("this") boolean mBooting = false;
1120    @GuardedBy("this") boolean mCallFinishBooting = false;
1121    @GuardedBy("this") boolean mBootAnimationComplete = false;
1122    @GuardedBy("this") boolean mLaunchWarningShown = false;
1123    @GuardedBy("this") boolean mCheckedForSetup = false;
1124
1125    Context mContext;
1126
1127    /**
1128     * The time at which we will allow normal application switches again,
1129     * after a call to {@link #stopAppSwitches()}.
1130     */
1131    long mAppSwitchesAllowedTime;
1132
1133    /**
1134     * This is set to true after the first switch after mAppSwitchesAllowedTime
1135     * is set; any switches after that will clear the time.
1136     */
1137    boolean mDidAppSwitch;
1138
1139    /**
1140     * Last time (in realtime) at which we checked for power usage.
1141     */
1142    long mLastPowerCheckRealtime;
1143
1144    /**
1145     * Last time (in uptime) at which we checked for power usage.
1146     */
1147    long mLastPowerCheckUptime;
1148
1149    /**
1150     * Set while we are wanting to sleep, to prevent any
1151     * activities from being started/resumed.
1152     */
1153    private boolean mSleeping = false;
1154
1155    /**
1156     * The process state used for processes that are running the top activities.
1157     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1158     */
1159    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1160
1161    /**
1162     * Set while we are running a voice interaction.  This overrides
1163     * sleeping while it is active.
1164     */
1165    private IVoiceInteractionSession mRunningVoice;
1166
1167    /**
1168     * For some direct access we need to power manager.
1169     */
1170    PowerManagerInternal mLocalPowerManager;
1171
1172    /**
1173     * We want to hold a wake lock while running a voice interaction session, since
1174     * this may happen with the screen off and we need to keep the CPU running to
1175     * be able to continue to interact with the user.
1176     */
1177    PowerManager.WakeLock mVoiceWakeLock;
1178
1179    /**
1180     * State of external calls telling us if the device is awake or asleep.
1181     */
1182    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1183
1184    /**
1185     * A list of tokens that cause the top activity to be put to sleep.
1186     * They are used by components that may hide and block interaction with underlying
1187     * activities.
1188     */
1189    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1190
1191    static final int LOCK_SCREEN_HIDDEN = 0;
1192    static final int LOCK_SCREEN_LEAVING = 1;
1193    static final int LOCK_SCREEN_SHOWN = 2;
1194    /**
1195     * State of external call telling us if the lock screen is shown.
1196     */
1197    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1198
1199    /**
1200     * Set if we are shutting down the system, similar to sleeping.
1201     */
1202    boolean mShuttingDown = false;
1203
1204    /**
1205     * Current sequence id for oom_adj computation traversal.
1206     */
1207    int mAdjSeq = 0;
1208
1209    /**
1210     * Current sequence id for process LRU updating.
1211     */
1212    int mLruSeq = 0;
1213
1214    /**
1215     * Keep track of the non-cached/empty process we last found, to help
1216     * determine how to distribute cached/empty processes next time.
1217     */
1218    int mNumNonCachedProcs = 0;
1219
1220    /**
1221     * Keep track of the number of cached hidden procs, to balance oom adj
1222     * distribution between those and empty procs.
1223     */
1224    int mNumCachedHiddenProcs = 0;
1225
1226    /**
1227     * Keep track of the number of service processes we last found, to
1228     * determine on the next iteration which should be B services.
1229     */
1230    int mNumServiceProcs = 0;
1231    int mNewNumAServiceProcs = 0;
1232    int mNewNumServiceProcs = 0;
1233
1234    /**
1235     * Allow the current computed overall memory level of the system to go down?
1236     * This is set to false when we are killing processes for reasons other than
1237     * memory management, so that the now smaller process list will not be taken as
1238     * an indication that memory is tighter.
1239     */
1240    boolean mAllowLowerMemLevel = false;
1241
1242    /**
1243     * The last computed memory level, for holding when we are in a state that
1244     * processes are going away for other reasons.
1245     */
1246    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1247
1248    /**
1249     * The last total number of process we have, to determine if changes actually look
1250     * like a shrinking number of process due to lower RAM.
1251     */
1252    int mLastNumProcesses;
1253
1254    /**
1255     * The uptime of the last time we performed idle maintenance.
1256     */
1257    long mLastIdleTime = SystemClock.uptimeMillis();
1258
1259    /**
1260     * Total time spent with RAM that has been added in the past since the last idle time.
1261     */
1262    long mLowRamTimeSinceLastIdle = 0;
1263
1264    /**
1265     * If RAM is currently low, when that horrible situation started.
1266     */
1267    long mLowRamStartTime = 0;
1268
1269    /**
1270     * For reporting to battery stats the current top application.
1271     */
1272    private String mCurResumedPackage = null;
1273    private int mCurResumedUid = -1;
1274
1275    /**
1276     * For reporting to battery stats the apps currently running foreground
1277     * service.  The ProcessMap is package/uid tuples; each of these contain
1278     * an array of the currently foreground processes.
1279     */
1280    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1281            = new ProcessMap<ArrayList<ProcessRecord>>();
1282
1283    /**
1284     * This is set if we had to do a delayed dexopt of an app before launching
1285     * it, to increase the ANR timeouts in that case.
1286     */
1287    boolean mDidDexOpt;
1288
1289    /**
1290     * Set if the systemServer made a call to enterSafeMode.
1291     */
1292    boolean mSafeMode;
1293
1294    /**
1295     * If true, we are running under a test environment so will sample PSS from processes
1296     * much more rapidly to try to collect better data when the tests are rapidly
1297     * running through apps.
1298     */
1299    boolean mTestPssMode = false;
1300
1301    String mDebugApp = null;
1302    boolean mWaitForDebugger = false;
1303    boolean mDebugTransient = false;
1304    String mOrigDebugApp = null;
1305    boolean mOrigWaitForDebugger = false;
1306    boolean mAlwaysFinishActivities = false;
1307    boolean mLenientBackgroundCheck = false;
1308    boolean mForceResizableActivities;
1309    boolean mSupportsMultiWindow;
1310    boolean mSupportsFreeformWindowManagement;
1311    boolean mSupportsPictureInPicture;
1312    Rect mDefaultPinnedStackBounds;
1313    IActivityController mController = null;
1314    boolean mControllerIsAMonkey = false;
1315    String mProfileApp = null;
1316    ProcessRecord mProfileProc = null;
1317    String mProfileFile;
1318    ParcelFileDescriptor mProfileFd;
1319    int mSamplingInterval = 0;
1320    boolean mAutoStopProfiler = false;
1321    int mProfileType = 0;
1322    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1323    String mMemWatchDumpProcName;
1324    String mMemWatchDumpFile;
1325    int mMemWatchDumpPid;
1326    int mMemWatchDumpUid;
1327    String mTrackAllocationApp = null;
1328    String mNativeDebuggingApp = null;
1329
1330    final long[] mTmpLong = new long[2];
1331
1332    static final class ProcessChangeItem {
1333        static final int CHANGE_ACTIVITIES = 1<<0;
1334        static final int CHANGE_PROCESS_STATE = 1<<1;
1335        int changes;
1336        int uid;
1337        int pid;
1338        int processState;
1339        boolean foregroundActivities;
1340    }
1341
1342    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1343    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1344
1345    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1346    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1347
1348    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1349    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1350
1351    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1352    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1353
1354    /**
1355     * Runtime CPU use collection thread.  This object's lock is used to
1356     * perform synchronization with the thread (notifying it to run).
1357     */
1358    final Thread mProcessCpuThread;
1359
1360    /**
1361     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1362     * Must acquire this object's lock when accessing it.
1363     * NOTE: this lock will be held while doing long operations (trawling
1364     * through all processes in /proc), so it should never be acquired by
1365     * any critical paths such as when holding the main activity manager lock.
1366     */
1367    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1368            MONITOR_THREAD_CPU_USAGE);
1369    final AtomicLong mLastCpuTime = new AtomicLong(0);
1370    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1371
1372    long mLastWriteTime = 0;
1373
1374    /**
1375     * Used to retain an update lock when the foreground activity is in
1376     * immersive mode.
1377     */
1378    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1379
1380    /**
1381     * Set to true after the system has finished booting.
1382     */
1383    boolean mBooted = false;
1384
1385    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1386    int mProcessLimitOverride = -1;
1387
1388    WindowManagerService mWindowManager;
1389    final ActivityThread mSystemThread;
1390
1391    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1392        final ProcessRecord mApp;
1393        final int mPid;
1394        final IApplicationThread mAppThread;
1395
1396        AppDeathRecipient(ProcessRecord app, int pid,
1397                IApplicationThread thread) {
1398            if (DEBUG_ALL) Slog.v(
1399                TAG, "New death recipient " + this
1400                + " for thread " + thread.asBinder());
1401            mApp = app;
1402            mPid = pid;
1403            mAppThread = thread;
1404        }
1405
1406        @Override
1407        public void binderDied() {
1408            if (DEBUG_ALL) Slog.v(
1409                TAG, "Death received in " + this
1410                + " for thread " + mAppThread.asBinder());
1411            synchronized(ActivityManagerService.this) {
1412                appDiedLocked(mApp, mPid, mAppThread, true);
1413            }
1414        }
1415    }
1416
1417    static final int SHOW_ERROR_UI_MSG = 1;
1418    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1419    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1420    static final int UPDATE_CONFIGURATION_MSG = 4;
1421    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1422    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1423    static final int SERVICE_TIMEOUT_MSG = 12;
1424    static final int UPDATE_TIME_ZONE = 13;
1425    static final int SHOW_UID_ERROR_UI_MSG = 14;
1426    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1427    static final int PROC_START_TIMEOUT_MSG = 20;
1428    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1429    static final int KILL_APPLICATION_MSG = 22;
1430    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1431    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1432    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1433    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1434    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1435    static final int CLEAR_DNS_CACHE_MSG = 28;
1436    static final int UPDATE_HTTP_PROXY_MSG = 29;
1437    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1438    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1439    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1440    static final int REPORT_MEM_USAGE_MSG = 33;
1441    static final int REPORT_USER_SWITCH_MSG = 34;
1442    static final int CONTINUE_USER_SWITCH_MSG = 35;
1443    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1444    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1445    static final int PERSIST_URI_GRANTS_MSG = 38;
1446    static final int REQUEST_ALL_PSS_MSG = 39;
1447    static final int START_PROFILES_MSG = 40;
1448    static final int UPDATE_TIME = 41;
1449    static final int SYSTEM_USER_START_MSG = 42;
1450    static final int SYSTEM_USER_CURRENT_MSG = 43;
1451    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1452    static final int FINISH_BOOTING_MSG = 45;
1453    static final int START_USER_SWITCH_UI_MSG = 46;
1454    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1455    static final int DISMISS_DIALOG_UI_MSG = 48;
1456    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1457    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1458    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1459    static final int DELETE_DUMPHEAP_MSG = 52;
1460    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1461    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1462    static final int REPORT_TIME_TRACKER_MSG = 55;
1463    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1464    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1465    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1466    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1467    static final int IDLE_UIDS_MSG = 60;
1468    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1469    static final int LOG_STACK_STATE = 62;
1470    static final int VR_MODE_CHANGE_MSG = 63;
1471    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1472    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1473    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1474    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1475    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1476    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1477
1478    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1479    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1480    static final int FIRST_COMPAT_MODE_MSG = 300;
1481    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1482
1483    static ServiceThread sKillThread = null;
1484    static KillHandler sKillHandler = null;
1485
1486    CompatModeDialog mCompatModeDialog;
1487    long mLastMemUsageReportTime = 0;
1488
1489    /**
1490     * Flag whether the current user is a "monkey", i.e. whether
1491     * the UI is driven by a UI automation tool.
1492     */
1493    private boolean mUserIsMonkey;
1494
1495    /** Flag whether the device has a Recents UI */
1496    boolean mHasRecents;
1497
1498    /** The dimensions of the thumbnails in the Recents UI. */
1499    int mThumbnailWidth;
1500    int mThumbnailHeight;
1501    float mFullscreenThumbnailScale;
1502
1503    final ServiceThread mHandlerThread;
1504    final MainHandler mHandler;
1505    final UiHandler mUiHandler;
1506
1507    PackageManagerInternal mPackageManagerInt;
1508
1509    final class KillHandler extends Handler {
1510        static final int KILL_PROCESS_GROUP_MSG = 4000;
1511
1512        public KillHandler(Looper looper) {
1513            super(looper, null, true);
1514        }
1515
1516        @Override
1517        public void handleMessage(Message msg) {
1518            switch (msg.what) {
1519                case KILL_PROCESS_GROUP_MSG:
1520                {
1521                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1522                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1523                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1524                }
1525                break;
1526
1527                default:
1528                    super.handleMessage(msg);
1529            }
1530        }
1531    }
1532
1533    final class UiHandler extends Handler {
1534        public UiHandler() {
1535            super(com.android.server.UiThread.get().getLooper(), null, true);
1536        }
1537
1538        @Override
1539        public void handleMessage(Message msg) {
1540            switch (msg.what) {
1541            case SHOW_ERROR_UI_MSG: {
1542                mAppErrors.handleShowAppErrorUi(msg);
1543                ensureBootCompleted();
1544            } break;
1545            case SHOW_NOT_RESPONDING_UI_MSG: {
1546                mAppErrors.handleShowAnrUi(msg);
1547                ensureBootCompleted();
1548            } break;
1549            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1550                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1551                synchronized (ActivityManagerService.this) {
1552                    ProcessRecord proc = (ProcessRecord) data.get("app");
1553                    if (proc == null) {
1554                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1555                        break;
1556                    }
1557                    if (proc.crashDialog != null) {
1558                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1559                        return;
1560                    }
1561                    AppErrorResult res = (AppErrorResult) data.get("result");
1562                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1563                        Dialog d = new StrictModeViolationDialog(mContext,
1564                                ActivityManagerService.this, res, proc);
1565                        d.show();
1566                        proc.crashDialog = d;
1567                    } else {
1568                        // The device is asleep, so just pretend that the user
1569                        // saw a crash dialog and hit "force quit".
1570                        res.set(0);
1571                    }
1572                }
1573                ensureBootCompleted();
1574            } break;
1575            case SHOW_FACTORY_ERROR_UI_MSG: {
1576                Dialog d = new FactoryErrorDialog(
1577                    mContext, msg.getData().getCharSequence("msg"));
1578                d.show();
1579                ensureBootCompleted();
1580            } break;
1581            case WAIT_FOR_DEBUGGER_UI_MSG: {
1582                synchronized (ActivityManagerService.this) {
1583                    ProcessRecord app = (ProcessRecord)msg.obj;
1584                    if (msg.arg1 != 0) {
1585                        if (!app.waitedForDebugger) {
1586                            Dialog d = new AppWaitingForDebuggerDialog(
1587                                    ActivityManagerService.this,
1588                                    mContext, app);
1589                            app.waitDialog = d;
1590                            app.waitedForDebugger = true;
1591                            d.show();
1592                        }
1593                    } else {
1594                        if (app.waitDialog != null) {
1595                            app.waitDialog.dismiss();
1596                            app.waitDialog = null;
1597                        }
1598                    }
1599                }
1600            } break;
1601            case SHOW_UID_ERROR_UI_MSG: {
1602                if (mShowDialogs) {
1603                    AlertDialog d = new BaseErrorDialog(mContext);
1604                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1605                    d.setCancelable(false);
1606                    d.setTitle(mContext.getText(R.string.android_system_label));
1607                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1608                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1609                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1610                    d.show();
1611                }
1612            } break;
1613            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1626                synchronized (ActivityManagerService.this) {
1627                    ActivityRecord ar = (ActivityRecord) msg.obj;
1628                    if (mCompatModeDialog != null) {
1629                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1630                                ar.info.applicationInfo.packageName)) {
1631                            return;
1632                        }
1633                        mCompatModeDialog.dismiss();
1634                        mCompatModeDialog = null;
1635                    }
1636                    if (ar != null && false) {
1637                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1638                                ar.packageName)) {
1639                            int mode = mCompatModePackages.computeCompatModeLocked(
1640                                    ar.info.applicationInfo);
1641                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1642                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1643                                mCompatModeDialog = new CompatModeDialog(
1644                                        ActivityManagerService.this, mContext,
1645                                        ar.info.applicationInfo);
1646                                mCompatModeDialog.show();
1647                            }
1648                        }
1649                    }
1650                }
1651                break;
1652            }
1653            case START_USER_SWITCH_UI_MSG: {
1654                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1655                break;
1656            }
1657            case DISMISS_DIALOG_UI_MSG: {
1658                final Dialog d = (Dialog) msg.obj;
1659                d.dismiss();
1660                break;
1661            }
1662            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1663                dispatchProcessesChanged();
1664                break;
1665            }
1666            case DISPATCH_PROCESS_DIED_UI_MSG: {
1667                final int pid = msg.arg1;
1668                final int uid = msg.arg2;
1669                dispatchProcessDied(pid, uid);
1670                break;
1671            }
1672            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1673                dispatchUidsChanged();
1674            } break;
1675            }
1676        }
1677    }
1678
1679    final class MainHandler extends Handler {
1680        public MainHandler(Looper looper) {
1681            super(looper, null, true);
1682        }
1683
1684        @Override
1685        public void handleMessage(Message msg) {
1686            switch (msg.what) {
1687            case UPDATE_CONFIGURATION_MSG: {
1688                final ContentResolver resolver = mContext.getContentResolver();
1689                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1690                        msg.arg1);
1691            } break;
1692            case GC_BACKGROUND_PROCESSES_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    performAppGcsIfAppropriateLocked();
1695                }
1696            } break;
1697            case SERVICE_TIMEOUT_MSG: {
1698                if (mDidDexOpt) {
1699                    mDidDexOpt = false;
1700                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1701                    nmsg.obj = msg.obj;
1702                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1703                    return;
1704                }
1705                mServices.serviceTimeout((ProcessRecord)msg.obj);
1706            } break;
1707            case UPDATE_TIME_ZONE: {
1708                synchronized (ActivityManagerService.this) {
1709                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1710                        ProcessRecord r = mLruProcesses.get(i);
1711                        if (r.thread != null) {
1712                            try {
1713                                r.thread.updateTimeZone();
1714                            } catch (RemoteException ex) {
1715                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1716                            }
1717                        }
1718                    }
1719                }
1720            } break;
1721            case CLEAR_DNS_CACHE_MSG: {
1722                synchronized (ActivityManagerService.this) {
1723                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1724                        ProcessRecord r = mLruProcesses.get(i);
1725                        if (r.thread != null) {
1726                            try {
1727                                r.thread.clearDnsCache();
1728                            } catch (RemoteException ex) {
1729                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1730                            }
1731                        }
1732                    }
1733                }
1734            } break;
1735            case UPDATE_HTTP_PROXY_MSG: {
1736                ProxyInfo proxy = (ProxyInfo)msg.obj;
1737                String host = "";
1738                String port = "";
1739                String exclList = "";
1740                Uri pacFileUrl = Uri.EMPTY;
1741                if (proxy != null) {
1742                    host = proxy.getHost();
1743                    port = Integer.toString(proxy.getPort());
1744                    exclList = proxy.getExclusionListAsString();
1745                    pacFileUrl = proxy.getPacFileUrl();
1746                }
1747                synchronized (ActivityManagerService.this) {
1748                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1749                        ProcessRecord r = mLruProcesses.get(i);
1750                        if (r.thread != null) {
1751                            try {
1752                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1753                            } catch (RemoteException ex) {
1754                                Slog.w(TAG, "Failed to update http proxy for: " +
1755                                        r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760            } break;
1761            case PROC_START_TIMEOUT_MSG: {
1762                if (mDidDexOpt) {
1763                    mDidDexOpt = false;
1764                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1765                    nmsg.obj = msg.obj;
1766                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1767                    return;
1768                }
1769                ProcessRecord app = (ProcessRecord)msg.obj;
1770                synchronized (ActivityManagerService.this) {
1771                    processStartTimedOutLocked(app);
1772                }
1773            } break;
1774            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1775                ProcessRecord app = (ProcessRecord)msg.obj;
1776                synchronized (ActivityManagerService.this) {
1777                    processContentProviderPublishTimedOutLocked(app);
1778                }
1779            } break;
1780            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1783                }
1784            } break;
1785            case KILL_APPLICATION_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    int appid = msg.arg1;
1788                    boolean restart = (msg.arg2 == 1);
1789                    Bundle bundle = (Bundle)msg.obj;
1790                    String pkg = bundle.getString("pkg");
1791                    String reason = bundle.getString("reason");
1792                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1793                            false, UserHandle.USER_ALL, reason);
1794                }
1795            } break;
1796            case FINALIZE_PENDING_INTENT_MSG: {
1797                ((PendingIntentRecord)msg.obj).completeFinalize();
1798            } break;
1799            case POST_HEAVY_NOTIFICATION_MSG: {
1800                INotificationManager inm = NotificationManager.getService();
1801                if (inm == null) {
1802                    return;
1803                }
1804
1805                ActivityRecord root = (ActivityRecord)msg.obj;
1806                ProcessRecord process = root.app;
1807                if (process == null) {
1808                    return;
1809                }
1810
1811                try {
1812                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1813                    String text = mContext.getString(R.string.heavy_weight_notification,
1814                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1815                    Notification notification = new Notification.Builder(context)
1816                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1817                            .setWhen(0)
1818                            .setOngoing(true)
1819                            .setTicker(text)
1820                            .setColor(mContext.getColor(
1821                                    com.android.internal.R.color.system_notification_accent_color))
1822                            .setContentTitle(text)
1823                            .setContentText(
1824                                    mContext.getText(R.string.heavy_weight_notification_detail))
1825                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1826                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1827                                    new UserHandle(root.userId)))
1828                            .build();
1829                    try {
1830                        int[] outId = new int[1];
1831                        inm.enqueueNotificationWithTag("android", "android", null,
1832                                R.string.heavy_weight_notification,
1833                                notification, outId, root.userId);
1834                    } catch (RuntimeException e) {
1835                        Slog.w(ActivityManagerService.TAG,
1836                                "Error showing notification for heavy-weight app", e);
1837                    } catch (RemoteException e) {
1838                    }
1839                } catch (NameNotFoundException e) {
1840                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1841                }
1842            } break;
1843            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1844                INotificationManager inm = NotificationManager.getService();
1845                if (inm == null) {
1846                    return;
1847                }
1848                try {
1849                    inm.cancelNotificationWithTag("android", null,
1850                            R.string.heavy_weight_notification,  msg.arg1);
1851                } catch (RuntimeException e) {
1852                    Slog.w(ActivityManagerService.TAG,
1853                            "Error canceling notification for service", e);
1854                } catch (RemoteException e) {
1855                }
1856            } break;
1857            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    checkExcessivePowerUsageLocked(true);
1860                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1861                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1863                }
1864            } break;
1865            case REPORT_MEM_USAGE_MSG: {
1866                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1867                Thread thread = new Thread() {
1868                    @Override public void run() {
1869                        reportMemUsage(memInfos);
1870                    }
1871                };
1872                thread.start();
1873                break;
1874            }
1875            case REPORT_USER_SWITCH_MSG: {
1876                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1877                break;
1878            }
1879            case CONTINUE_USER_SWITCH_MSG: {
1880                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1881                break;
1882            }
1883            case USER_SWITCH_TIMEOUT_MSG: {
1884                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1885                break;
1886            }
1887            case IMMERSIVE_MODE_LOCK_MSG: {
1888                final boolean nextState = (msg.arg1 != 0);
1889                if (mUpdateLock.isHeld() != nextState) {
1890                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1891                            "Applying new update lock state '" + nextState
1892                            + "' for " + (ActivityRecord)msg.obj);
1893                    if (nextState) {
1894                        mUpdateLock.acquire();
1895                    } else {
1896                        mUpdateLock.release();
1897                    }
1898                }
1899                break;
1900            }
1901            case PERSIST_URI_GRANTS_MSG: {
1902                writeGrantedUriPermissions();
1903                break;
1904            }
1905            case REQUEST_ALL_PSS_MSG: {
1906                synchronized (ActivityManagerService.this) {
1907                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1908                }
1909                break;
1910            }
1911            case START_PROFILES_MSG: {
1912                synchronized (ActivityManagerService.this) {
1913                    mUserController.startProfilesLocked();
1914                }
1915                break;
1916            }
1917            case UPDATE_TIME: {
1918                synchronized (ActivityManagerService.this) {
1919                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1920                        ProcessRecord r = mLruProcesses.get(i);
1921                        if (r.thread != null) {
1922                            try {
1923                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1924                            } catch (RemoteException ex) {
1925                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1926                            }
1927                        }
1928                    }
1929                }
1930                break;
1931            }
1932            case SYSTEM_USER_START_MSG: {
1933                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1934                        Integer.toString(msg.arg1), msg.arg1);
1935                mSystemServiceManager.startUser(msg.arg1);
1936                break;
1937            }
1938            case SYSTEM_USER_UNLOCK_MSG: {
1939                final int userId = msg.arg1;
1940                mSystemServiceManager.unlockUser(userId);
1941                synchronized (ActivityManagerService.this) {
1942                    mRecentTasks.loadUserRecentsLocked(userId);
1943                }
1944                if (userId == UserHandle.USER_SYSTEM) {
1945                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1946                }
1947                installEncryptionUnawareProviders(userId);
1948                if (msg.obj instanceof ProgressReporter) {
1949                    ((ProgressReporter) msg.obj).finish();
1950                }
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) {
3354        IPackageManager pm = AppGlobals.getPackageManager();
3355        try {
3356            pm.notifyPackageUse(packageName);
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            if (DEBUG_PROCESSES) {
3691                checkTime(startTime, "startProcess: building log message");
3692                StringBuilder buf = mStringBuilder;
3693                buf.setLength(0);
3694                buf.append("Start proc ");
3695                buf.append(startResult.pid);
3696                buf.append(':');
3697                buf.append(app.processName);
3698                buf.append('/');
3699                UserHandle.formatUid(buf, uid);
3700                if (!isActivityProcess) {
3701                    buf.append(" [");
3702                    buf.append(entryPoint);
3703                    buf.append("]");
3704                }
3705                buf.append(" for ");
3706                buf.append(hostingType);
3707                if (hostingNameStr != null) {
3708                    buf.append(" ");
3709                    buf.append(hostingNameStr);
3710                }
3711                Slog.i(TAG, buf.toString());
3712            }
3713            app.setPid(startResult.pid);
3714            app.usingWrapper = startResult.usingWrapper;
3715            app.removed = false;
3716            app.killed = false;
3717            app.killedByAm = false;
3718            checkTime(startTime, "startProcess: starting to update pids map");
3719            synchronized (mPidsSelfLocked) {
3720                this.mPidsSelfLocked.put(startResult.pid, app);
3721                if (isActivityProcess) {
3722                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3723                    msg.obj = app;
3724                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3725                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3726                }
3727            }
3728            checkTime(startTime, "startProcess: done updating pids map");
3729        } catch (RuntimeException e) {
3730            // XXX do better error recovery.
3731            app.setPid(0);
3732            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3733            if (app.isolated) {
3734                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3735            }
3736            Slog.e(TAG, "Failure starting process " + app.processName, e);
3737        }
3738    }
3739
3740    void updateUsageStats(ActivityRecord component, boolean resumed) {
3741        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3742                "updateUsageStats: comp=" + component + "res=" + resumed);
3743        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3744        if (resumed) {
3745            if (mUsageStatsService != null) {
3746                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3747                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3748            }
3749            synchronized (stats) {
3750                stats.noteActivityResumedLocked(component.app.uid);
3751            }
3752        } else {
3753            if (mUsageStatsService != null) {
3754                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3755                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3756            }
3757            synchronized (stats) {
3758                stats.noteActivityPausedLocked(component.app.uid);
3759            }
3760        }
3761    }
3762
3763    Intent getHomeIntent() {
3764        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3765        intent.setComponent(mTopComponent);
3766        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3767        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3768            intent.addCategory(Intent.CATEGORY_HOME);
3769        }
3770        return intent;
3771    }
3772
3773    boolean startHomeActivityLocked(int userId, String reason) {
3774        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3775                && mTopAction == null) {
3776            // We are running in factory test mode, but unable to find
3777            // the factory test app, so just sit around displaying the
3778            // error message and don't try to start anything.
3779            return false;
3780        }
3781        Intent intent = getHomeIntent();
3782        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3783        if (aInfo != null) {
3784            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3785            // Don't do this if the home app is currently being
3786            // instrumented.
3787            aInfo = new ActivityInfo(aInfo);
3788            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3789            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3790                    aInfo.applicationInfo.uid, true);
3791            if (app == null || app.instrumentationClass == null) {
3792                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3793                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3794            }
3795        }
3796
3797        return true;
3798    }
3799
3800    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3801        ActivityInfo ai = null;
3802        ComponentName comp = intent.getComponent();
3803        try {
3804            if (comp != null) {
3805                // Factory test.
3806                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3807            } else {
3808                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3809                        intent,
3810                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3811                        flags, userId);
3812
3813                if (info != null) {
3814                    ai = info.activityInfo;
3815                }
3816            }
3817        } catch (RemoteException e) {
3818            // ignore
3819        }
3820
3821        return ai;
3822    }
3823
3824    /**
3825     * Starts the "new version setup screen" if appropriate.
3826     */
3827    void startSetupActivityLocked() {
3828        // Only do this once per boot.
3829        if (mCheckedForSetup) {
3830            return;
3831        }
3832
3833        // We will show this screen if the current one is a different
3834        // version than the last one shown, and we are not running in
3835        // low-level factory test mode.
3836        final ContentResolver resolver = mContext.getContentResolver();
3837        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3838                Settings.Global.getInt(resolver,
3839                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3840            mCheckedForSetup = true;
3841
3842            // See if we should be showing the platform update setup UI.
3843            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3844            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3845                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3846            if (!ris.isEmpty()) {
3847                final ResolveInfo ri = ris.get(0);
3848                String vers = ri.activityInfo.metaData != null
3849                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3850                        : null;
3851                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3852                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3853                            Intent.METADATA_SETUP_VERSION);
3854                }
3855                String lastVers = Settings.Secure.getString(
3856                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3857                if (vers != null && !vers.equals(lastVers)) {
3858                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3859                    intent.setComponent(new ComponentName(
3860                            ri.activityInfo.packageName, ri.activityInfo.name));
3861                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3862                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3863                            null, 0, 0, 0, null, false, false, null, null, null);
3864                }
3865            }
3866        }
3867    }
3868
3869    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3870        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3871    }
3872
3873    void enforceNotIsolatedCaller(String caller) {
3874        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3875            throw new SecurityException("Isolated process not allowed to call " + caller);
3876        }
3877    }
3878
3879    void enforceShellRestriction(String restriction, int userHandle) {
3880        if (Binder.getCallingUid() == Process.SHELL_UID) {
3881            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3882                throw new SecurityException("Shell does not have permission to access user "
3883                        + userHandle);
3884            }
3885        }
3886    }
3887
3888    @Override
3889    public int getFrontActivityScreenCompatMode() {
3890        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3891        synchronized (this) {
3892            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3893        }
3894    }
3895
3896    @Override
3897    public void setFrontActivityScreenCompatMode(int mode) {
3898        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3899                "setFrontActivityScreenCompatMode");
3900        synchronized (this) {
3901            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3902        }
3903    }
3904
3905    @Override
3906    public int getPackageScreenCompatMode(String packageName) {
3907        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3908        synchronized (this) {
3909            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3910        }
3911    }
3912
3913    @Override
3914    public void setPackageScreenCompatMode(String packageName, int mode) {
3915        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3916                "setPackageScreenCompatMode");
3917        synchronized (this) {
3918            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3919        }
3920    }
3921
3922    @Override
3923    public boolean getPackageAskScreenCompat(String packageName) {
3924        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3925        synchronized (this) {
3926            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3927        }
3928    }
3929
3930    @Override
3931    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3932        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3933                "setPackageAskScreenCompat");
3934        synchronized (this) {
3935            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3936        }
3937    }
3938
3939    private boolean hasUsageStatsPermission(String callingPackage) {
3940        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3941                Binder.getCallingUid(), callingPackage);
3942        if (mode == AppOpsManager.MODE_DEFAULT) {
3943            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3944                    == PackageManager.PERMISSION_GRANTED;
3945        }
3946        return mode == AppOpsManager.MODE_ALLOWED;
3947    }
3948
3949    @Override
3950    public int getPackageProcessState(String packageName, String callingPackage) {
3951        if (!hasUsageStatsPermission(callingPackage)) {
3952            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3953                    "getPackageProcessState");
3954        }
3955
3956        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3957        synchronized (this) {
3958            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3959                final ProcessRecord proc = mLruProcesses.get(i);
3960                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3961                        || procState > proc.setProcState) {
3962                    boolean found = false;
3963                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3964                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3965                            procState = proc.setProcState;
3966                            found = true;
3967                        }
3968                    }
3969                    if (proc.pkgDeps != null && !found) {
3970                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3971                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3972                                procState = proc.setProcState;
3973                                break;
3974                            }
3975                        }
3976                    }
3977                }
3978            }
3979        }
3980        return procState;
3981    }
3982
3983    @Override
3984    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3985        synchronized (this) {
3986            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3987            if (app == null) {
3988                return false;
3989            }
3990            if (app.trimMemoryLevel < level && app.thread != null &&
3991                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3992                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3993                try {
3994                    app.thread.scheduleTrimMemory(level);
3995                    app.trimMemoryLevel = level;
3996                    return true;
3997                } catch (RemoteException e) {
3998                    // Fallthrough to failure case.
3999                }
4000            }
4001        }
4002        return false;
4003    }
4004
4005    private void dispatchProcessesChanged() {
4006        int N;
4007        synchronized (this) {
4008            N = mPendingProcessChanges.size();
4009            if (mActiveProcessChanges.length < N) {
4010                mActiveProcessChanges = new ProcessChangeItem[N];
4011            }
4012            mPendingProcessChanges.toArray(mActiveProcessChanges);
4013            mPendingProcessChanges.clear();
4014            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4015                    "*** Delivering " + N + " process changes");
4016        }
4017
4018        int i = mProcessObservers.beginBroadcast();
4019        while (i > 0) {
4020            i--;
4021            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4022            if (observer != null) {
4023                try {
4024                    for (int j=0; j<N; j++) {
4025                        ProcessChangeItem item = mActiveProcessChanges[j];
4026                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4027                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4028                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4029                                    + item.uid + ": " + item.foregroundActivities);
4030                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4031                                    item.foregroundActivities);
4032                        }
4033                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4035                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4036                                    + ": " + item.processState);
4037                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4038                        }
4039                    }
4040                } catch (RemoteException e) {
4041                }
4042            }
4043        }
4044        mProcessObservers.finishBroadcast();
4045
4046        synchronized (this) {
4047            for (int j=0; j<N; j++) {
4048                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4049            }
4050        }
4051    }
4052
4053    private void dispatchProcessDied(int pid, int uid) {
4054        int i = mProcessObservers.beginBroadcast();
4055        while (i > 0) {
4056            i--;
4057            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4058            if (observer != null) {
4059                try {
4060                    observer.onProcessDied(pid, uid);
4061                } catch (RemoteException e) {
4062                }
4063            }
4064        }
4065        mProcessObservers.finishBroadcast();
4066    }
4067
4068    private void dispatchUidsChanged() {
4069        int N;
4070        synchronized (this) {
4071            N = mPendingUidChanges.size();
4072            if (mActiveUidChanges.length < N) {
4073                mActiveUidChanges = new UidRecord.ChangeItem[N];
4074            }
4075            for (int i=0; i<N; i++) {
4076                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4077                mActiveUidChanges[i] = change;
4078                if (change.uidRecord != null) {
4079                    change.uidRecord.pendingChange = null;
4080                    change.uidRecord = null;
4081                }
4082            }
4083            mPendingUidChanges.clear();
4084            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4085                    "*** Delivering " + N + " uid changes");
4086        }
4087
4088        if (mLocalPowerManager != null) {
4089            for (int j=0; j<N; j++) {
4090                UidRecord.ChangeItem item = mActiveUidChanges[j];
4091                if (item.change == UidRecord.CHANGE_GONE
4092                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4093                    mLocalPowerManager.uidGone(item.uid);
4094                } else {
4095                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4096                }
4097            }
4098        }
4099
4100        int i = mUidObservers.beginBroadcast();
4101        while (i > 0) {
4102            i--;
4103            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4104            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4105            if (observer != null) {
4106                try {
4107                    for (int j=0; j<N; j++) {
4108                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4109                        final int change = item.change;
4110                        UidRecord validateUid = null;
4111                        if (VALIDATE_UID_STATES && i == 0) {
4112                            validateUid = mValidateUids.get(item.uid);
4113                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4114                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4115                                validateUid = new UidRecord(item.uid);
4116                                mValidateUids.put(item.uid, validateUid);
4117                            }
4118                        }
4119                        if (change == UidRecord.CHANGE_IDLE
4120                                || change == UidRecord.CHANGE_GONE_IDLE) {
4121                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4122                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4123                                        "UID idle uid=" + item.uid);
4124                                observer.onUidIdle(item.uid);
4125                            }
4126                            if (VALIDATE_UID_STATES && i == 0) {
4127                                if (validateUid != null) {
4128                                    validateUid.idle = true;
4129                                }
4130                            }
4131                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4132                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4133                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4134                                        "UID active uid=" + item.uid);
4135                                observer.onUidActive(item.uid);
4136                            }
4137                            if (VALIDATE_UID_STATES && i == 0) {
4138                                validateUid.idle = false;
4139                            }
4140                        }
4141                        if (change == UidRecord.CHANGE_GONE
4142                                || change == UidRecord.CHANGE_GONE_IDLE) {
4143                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4144                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4145                                        "UID gone uid=" + item.uid);
4146                                observer.onUidGone(item.uid);
4147                            }
4148                            if (VALIDATE_UID_STATES && i == 0) {
4149                                if (validateUid != null) {
4150                                    mValidateUids.remove(item.uid);
4151                                }
4152                            }
4153                        } else {
4154                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4155                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4156                                        "UID CHANGED uid=" + item.uid
4157                                                + ": " + item.processState);
4158                                observer.onUidStateChanged(item.uid, item.processState);
4159                            }
4160                            if (VALIDATE_UID_STATES && i == 0) {
4161                                validateUid.curProcState = validateUid.setProcState
4162                                        = item.processState;
4163                            }
4164                        }
4165                    }
4166                } catch (RemoteException e) {
4167                }
4168            }
4169        }
4170        mUidObservers.finishBroadcast();
4171
4172        synchronized (this) {
4173            for (int j=0; j<N; j++) {
4174                mAvailUidChanges.add(mActiveUidChanges[j]);
4175            }
4176        }
4177    }
4178
4179    @Override
4180    public final int startActivity(IApplicationThread caller, String callingPackage,
4181            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4182            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4183        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4184                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4185                UserHandle.getCallingUserId());
4186    }
4187
4188    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4189        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4190        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4191                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4192                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4193
4194        // TODO: Switch to user app stacks here.
4195        String mimeType = intent.getType();
4196        final Uri data = intent.getData();
4197        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4198            mimeType = getProviderMimeType(data, userId);
4199        }
4200        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4201
4202        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4203        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4204                null, 0, 0, null, null, null, null, false, userId, container, null);
4205    }
4206
4207    @Override
4208    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4209            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4210            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4211        enforceNotIsolatedCaller("startActivity");
4212        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4213                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4214        // TODO: Switch to user app stacks here.
4215        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4216                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4217                profilerInfo, null, null, bOptions, false, userId, null, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4224            int userId) {
4225
4226        // This is very dangerous -- it allows you to perform a start activity (including
4227        // permission grants) as any app that may launch one of your own activities.  So
4228        // we will only allow this to be done from activities that are part of the core framework,
4229        // and then only when they are running as the system.
4230        final ActivityRecord sourceRecord;
4231        final int targetUid;
4232        final String targetPackage;
4233        synchronized (this) {
4234            if (resultTo == null) {
4235                throw new SecurityException("Must be called from an activity");
4236            }
4237            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4238            if (sourceRecord == null) {
4239                throw new SecurityException("Called with bad activity token: " + resultTo);
4240            }
4241            if (!sourceRecord.info.packageName.equals("android")) {
4242                throw new SecurityException(
4243                        "Must be called from an activity that is declared in the android package");
4244            }
4245            if (sourceRecord.app == null) {
4246                throw new SecurityException("Called without a process attached to activity");
4247            }
4248            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4249                // This is still okay, as long as this activity is running under the
4250                // uid of the original calling activity.
4251                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4252                    throw new SecurityException(
4253                            "Calling activity in uid " + sourceRecord.app.uid
4254                                    + " must be system uid or original calling uid "
4255                                    + sourceRecord.launchedFromUid);
4256                }
4257            }
4258            if (ignoreTargetSecurity) {
4259                if (intent.getComponent() == null) {
4260                    throw new SecurityException(
4261                            "Component must be specified with ignoreTargetSecurity");
4262                }
4263                if (intent.getSelector() != null) {
4264                    throw new SecurityException(
4265                            "Selector not allowed with ignoreTargetSecurity");
4266                }
4267            }
4268            targetUid = sourceRecord.launchedFromUid;
4269            targetPackage = sourceRecord.launchedFromPackage;
4270        }
4271
4272        if (userId == UserHandle.USER_NULL) {
4273            userId = UserHandle.getUserId(sourceRecord.app.uid);
4274        }
4275
4276        // TODO: Switch to user app stacks here.
4277        try {
4278            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4279                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4280                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4281            return ret;
4282        } catch (SecurityException e) {
4283            // XXX need to figure out how to propagate to original app.
4284            // A SecurityException here is generally actually a fault of the original
4285            // calling activity (such as a fairly granting permissions), so propagate it
4286            // back to them.
4287            /*
4288            StringBuilder msg = new StringBuilder();
4289            msg.append("While launching");
4290            msg.append(intent.toString());
4291            msg.append(": ");
4292            msg.append(e.getMessage());
4293            */
4294            throw e;
4295        }
4296    }
4297
4298    @Override
4299    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4300            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4301            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4302        enforceNotIsolatedCaller("startActivityAndWait");
4303        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4304                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4305        WaitResult res = new WaitResult();
4306        // TODO: Switch to user app stacks here.
4307        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4308                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4309                bOptions, false, userId, null, null);
4310        return res;
4311    }
4312
4313    @Override
4314    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4315            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4316            int startFlags, Configuration config, Bundle bOptions, int userId) {
4317        enforceNotIsolatedCaller("startActivityWithConfig");
4318        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4319                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4320        // TODO: Switch to user app stacks here.
4321        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4322                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4323                null, null, config, bOptions, false, userId, null, null);
4324        return ret;
4325    }
4326
4327    @Override
4328    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4329            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4330            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4331            throws TransactionTooLargeException {
4332        enforceNotIsolatedCaller("startActivityIntentSender");
4333        // Refuse possible leaked file descriptors
4334        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4335            throw new IllegalArgumentException("File descriptors passed in Intent");
4336        }
4337
4338        IIntentSender sender = intent.getTarget();
4339        if (!(sender instanceof PendingIntentRecord)) {
4340            throw new IllegalArgumentException("Bad PendingIntent object");
4341        }
4342
4343        PendingIntentRecord pir = (PendingIntentRecord)sender;
4344
4345        synchronized (this) {
4346            // If this is coming from the currently resumed activity, it is
4347            // effectively saying that app switches are allowed at this point.
4348            final ActivityStack stack = getFocusedStack();
4349            if (stack.mResumedActivity != null &&
4350                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4351                mAppSwitchesAllowedTime = 0;
4352            }
4353        }
4354        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4355                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4356        return ret;
4357    }
4358
4359    @Override
4360    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4361            Intent intent, String resolvedType, IVoiceInteractionSession session,
4362            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4363            Bundle bOptions, int userId) {
4364        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4365                != PackageManager.PERMISSION_GRANTED) {
4366            String msg = "Permission Denial: startVoiceActivity() from pid="
4367                    + Binder.getCallingPid()
4368                    + ", uid=" + Binder.getCallingUid()
4369                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4370            Slog.w(TAG, msg);
4371            throw new SecurityException(msg);
4372        }
4373        if (session == null || interactor == null) {
4374            throw new NullPointerException("null session or interactor");
4375        }
4376        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4377                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4378        // TODO: Switch to user app stacks here.
4379        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4380                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4381                null, bOptions, false, userId, null, null);
4382    }
4383
4384    @Override
4385    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4386            throws RemoteException {
4387        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4388        synchronized (this) {
4389            ActivityRecord activity = getFocusedStack().topActivity();
4390            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4391                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4392            }
4393            if (mRunningVoice != null || activity.task.voiceSession != null
4394                    || activity.voiceSession != null) {
4395                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4396                return;
4397            }
4398            if (activity.pendingVoiceInteractionStart) {
4399                Slog.w(TAG, "Pending start of voice interaction already.");
4400                return;
4401            }
4402            activity.pendingVoiceInteractionStart = true;
4403        }
4404        LocalServices.getService(VoiceInteractionManagerInternal.class)
4405                .startLocalVoiceInteraction(callingActivity, options);
4406    }
4407
4408    @Override
4409    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4410        LocalServices.getService(VoiceInteractionManagerInternal.class)
4411                .stopLocalVoiceInteraction(callingActivity);
4412    }
4413
4414    @Override
4415    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4416        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4417                .supportsLocalVoiceInteraction();
4418    }
4419
4420    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4421            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4422        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4423        if (activityToCallback == null) return;
4424        activityToCallback.setVoiceSessionLocked(voiceSession);
4425
4426        // Inform the activity
4427        try {
4428            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4429                    voiceInteractor);
4430            long token = Binder.clearCallingIdentity();
4431            try {
4432                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4433            } finally {
4434                Binder.restoreCallingIdentity(token);
4435            }
4436            // TODO: VI Should we cache the activity so that it's easier to find later
4437            // rather than scan through all the stacks and activities?
4438        } catch (RemoteException re) {
4439            activityToCallback.clearVoiceSessionLocked();
4440            // TODO: VI Should this terminate the voice session?
4441        }
4442    }
4443
4444    @Override
4445    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4446        synchronized (this) {
4447            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4448                if (keepAwake) {
4449                    mVoiceWakeLock.acquire();
4450                } else {
4451                    mVoiceWakeLock.release();
4452                }
4453            }
4454        }
4455    }
4456
4457    @Override
4458    public boolean startNextMatchingActivity(IBinder callingActivity,
4459            Intent intent, Bundle bOptions) {
4460        // Refuse possible leaked file descriptors
4461        if (intent != null && intent.hasFileDescriptors() == true) {
4462            throw new IllegalArgumentException("File descriptors passed in Intent");
4463        }
4464        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4465
4466        synchronized (this) {
4467            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4468            if (r == null) {
4469                ActivityOptions.abort(options);
4470                return false;
4471            }
4472            if (r.app == null || r.app.thread == null) {
4473                // The caller is not running...  d'oh!
4474                ActivityOptions.abort(options);
4475                return false;
4476            }
4477            intent = new Intent(intent);
4478            // The caller is not allowed to change the data.
4479            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4480            // And we are resetting to find the next component...
4481            intent.setComponent(null);
4482
4483            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4484
4485            ActivityInfo aInfo = null;
4486            try {
4487                List<ResolveInfo> resolves =
4488                    AppGlobals.getPackageManager().queryIntentActivities(
4489                            intent, r.resolvedType,
4490                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4491                            UserHandle.getCallingUserId()).getList();
4492
4493                // Look for the original activity in the list...
4494                final int N = resolves != null ? resolves.size() : 0;
4495                for (int i=0; i<N; i++) {
4496                    ResolveInfo rInfo = resolves.get(i);
4497                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4498                            && rInfo.activityInfo.name.equals(r.info.name)) {
4499                        // We found the current one...  the next matching is
4500                        // after it.
4501                        i++;
4502                        if (i<N) {
4503                            aInfo = resolves.get(i).activityInfo;
4504                        }
4505                        if (debug) {
4506                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4507                                    + "/" + r.info.name);
4508                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4509                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4510                        }
4511                        break;
4512                    }
4513                }
4514            } catch (RemoteException e) {
4515            }
4516
4517            if (aInfo == null) {
4518                // Nobody who is next!
4519                ActivityOptions.abort(options);
4520                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4521                return false;
4522            }
4523
4524            intent.setComponent(new ComponentName(
4525                    aInfo.applicationInfo.packageName, aInfo.name));
4526            intent.setFlags(intent.getFlags()&~(
4527                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4528                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4529                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4530                    Intent.FLAG_ACTIVITY_NEW_TASK));
4531
4532            // Okay now we need to start the new activity, replacing the
4533            // currently running activity.  This is a little tricky because
4534            // we want to start the new one as if the current one is finished,
4535            // but not finish the current one first so that there is no flicker.
4536            // And thus...
4537            final boolean wasFinishing = r.finishing;
4538            r.finishing = true;
4539
4540            // Propagate reply information over to the new activity.
4541            final ActivityRecord resultTo = r.resultTo;
4542            final String resultWho = r.resultWho;
4543            final int requestCode = r.requestCode;
4544            r.resultTo = null;
4545            if (resultTo != null) {
4546                resultTo.removeResultsLocked(r, resultWho, requestCode);
4547            }
4548
4549            final long origId = Binder.clearCallingIdentity();
4550            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4551                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4552                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4553                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4554                    false, false, null, null, null);
4555            Binder.restoreCallingIdentity(origId);
4556
4557            r.finishing = wasFinishing;
4558            if (res != ActivityManager.START_SUCCESS) {
4559                return false;
4560            }
4561            return true;
4562        }
4563    }
4564
4565    @Override
4566    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4567        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4568            String msg = "Permission Denial: startActivityFromRecents called without " +
4569                    START_TASKS_FROM_RECENTS;
4570            Slog.w(TAG, msg);
4571            throw new SecurityException(msg);
4572        }
4573        final long origId = Binder.clearCallingIdentity();
4574        try {
4575            synchronized (this) {
4576                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4577            }
4578        } finally {
4579            Binder.restoreCallingIdentity(origId);
4580        }
4581    }
4582
4583    final int startActivityInPackage(int uid, String callingPackage,
4584            Intent intent, String resolvedType, IBinder resultTo,
4585            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4586            IActivityContainer container, TaskRecord inTask) {
4587
4588        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4589                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4590
4591        // TODO: Switch to user app stacks here.
4592        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4593                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4594                null, null, null, bOptions, false, userId, container, inTask);
4595        return ret;
4596    }
4597
4598    @Override
4599    public final int startActivities(IApplicationThread caller, String callingPackage,
4600            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4601            int userId) {
4602        enforceNotIsolatedCaller("startActivities");
4603        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4604                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4605        // TODO: Switch to user app stacks here.
4606        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4607                resolvedTypes, resultTo, bOptions, userId);
4608        return ret;
4609    }
4610
4611    final int startActivitiesInPackage(int uid, String callingPackage,
4612            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4613            Bundle bOptions, int userId) {
4614
4615        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4616                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4617        // TODO: Switch to user app stacks here.
4618        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4619                resultTo, bOptions, userId);
4620        return ret;
4621    }
4622
4623    @Override
4624    public void reportActivityFullyDrawn(IBinder token) {
4625        synchronized (this) {
4626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4627            if (r == null) {
4628                return;
4629            }
4630            r.reportFullyDrawnLocked();
4631        }
4632    }
4633
4634    @Override
4635    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4636        synchronized (this) {
4637            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4638            if (r == null) {
4639                return;
4640            }
4641            TaskRecord task = r.task;
4642            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4643                // Fixed screen orientation isn't supported when activities aren't in full screen
4644                // mode.
4645                return;
4646            }
4647            final long origId = Binder.clearCallingIdentity();
4648            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4649            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4650                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4651            if (config != null) {
4652                r.frozenBeforeDestroy = true;
4653                if (!updateConfigurationLocked(config, r, false)) {
4654                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4655                }
4656            }
4657            Binder.restoreCallingIdentity(origId);
4658        }
4659    }
4660
4661    @Override
4662    public int getRequestedOrientation(IBinder token) {
4663        synchronized (this) {
4664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4665            if (r == null) {
4666                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4667            }
4668            return mWindowManager.getAppOrientation(r.appToken);
4669        }
4670    }
4671
4672    /**
4673     * This is the internal entry point for handling Activity.finish().
4674     *
4675     * @param token The Binder token referencing the Activity we want to finish.
4676     * @param resultCode Result code, if any, from this Activity.
4677     * @param resultData Result data (Intent), if any, from this Activity.
4678     * @param finishTask Whether to finish the task associated with this Activity.
4679     *
4680     * @return Returns true if the activity successfully finished, or false if it is still running.
4681     */
4682    @Override
4683    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4684            int finishTask) {
4685        // Refuse possible leaked file descriptors
4686        if (resultData != null && resultData.hasFileDescriptors() == true) {
4687            throw new IllegalArgumentException("File descriptors passed in Intent");
4688        }
4689
4690        synchronized(this) {
4691            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4692            if (r == null) {
4693                return true;
4694            }
4695            // Keep track of the root activity of the task before we finish it
4696            TaskRecord tr = r.task;
4697            ActivityRecord rootR = tr.getRootActivity();
4698            if (rootR == null) {
4699                Slog.w(TAG, "Finishing task with all activities already finished");
4700            }
4701            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4702            // finish.
4703            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4704                    mStackSupervisor.isLastLockedTask(tr)) {
4705                Slog.i(TAG, "Not finishing task in lock task mode");
4706                mStackSupervisor.showLockTaskToast();
4707                return false;
4708            }
4709            if (mController != null) {
4710                // Find the first activity that is not finishing.
4711                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4712                if (next != null) {
4713                    // ask watcher if this is allowed
4714                    boolean resumeOK = true;
4715                    try {
4716                        resumeOK = mController.activityResuming(next.packageName);
4717                    } catch (RemoteException e) {
4718                        mController = null;
4719                        Watchdog.getInstance().setActivityController(null);
4720                    }
4721
4722                    if (!resumeOK) {
4723                        Slog.i(TAG, "Not finishing activity because controller resumed");
4724                        return false;
4725                    }
4726                }
4727            }
4728            final long origId = Binder.clearCallingIdentity();
4729            try {
4730                boolean res;
4731                final boolean finishWithRootActivity =
4732                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4733                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4734                        || (finishWithRootActivity && r == rootR)) {
4735                    // If requested, remove the task that is associated to this activity only if it
4736                    // was the root activity in the task. The result code and data is ignored
4737                    // because we don't support returning them across task boundaries. Also, to
4738                    // keep backwards compatibility we remove the task from recents when finishing
4739                    // task with root activity.
4740                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4741                    if (!res) {
4742                        Slog.i(TAG, "Removing task failed to finish activity");
4743                    }
4744                } else {
4745                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4746                            resultData, "app-request", true);
4747                    if (!res) {
4748                        Slog.i(TAG, "Failed to finish by app-request");
4749                    }
4750                }
4751                return res;
4752            } finally {
4753                Binder.restoreCallingIdentity(origId);
4754            }
4755        }
4756    }
4757
4758    @Override
4759    public final void finishHeavyWeightApp() {
4760        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4761                != PackageManager.PERMISSION_GRANTED) {
4762            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4763                    + Binder.getCallingPid()
4764                    + ", uid=" + Binder.getCallingUid()
4765                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4766            Slog.w(TAG, msg);
4767            throw new SecurityException(msg);
4768        }
4769
4770        synchronized(this) {
4771            if (mHeavyWeightProcess == null) {
4772                return;
4773            }
4774
4775            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4776            for (int i = 0; i < activities.size(); i++) {
4777                ActivityRecord r = activities.get(i);
4778                if (!r.finishing && r.isInStackLocked()) {
4779                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4780                            null, "finish-heavy", true);
4781                }
4782            }
4783
4784            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4785                    mHeavyWeightProcess.userId, 0));
4786            mHeavyWeightProcess = null;
4787        }
4788    }
4789
4790    @Override
4791    public void crashApplication(int uid, int initialPid, String packageName,
4792            String message) {
4793        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4794                != PackageManager.PERMISSION_GRANTED) {
4795            String msg = "Permission Denial: crashApplication() from pid="
4796                    + Binder.getCallingPid()
4797                    + ", uid=" + Binder.getCallingUid()
4798                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4799            Slog.w(TAG, msg);
4800            throw new SecurityException(msg);
4801        }
4802
4803        synchronized(this) {
4804            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4805        }
4806    }
4807
4808    @Override
4809    public final void finishSubActivity(IBinder token, String resultWho,
4810            int requestCode) {
4811        synchronized(this) {
4812            final long origId = Binder.clearCallingIdentity();
4813            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4814            if (r != null) {
4815                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4816            }
4817            Binder.restoreCallingIdentity(origId);
4818        }
4819    }
4820
4821    @Override
4822    public boolean finishActivityAffinity(IBinder token) {
4823        synchronized(this) {
4824            final long origId = Binder.clearCallingIdentity();
4825            try {
4826                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4827                if (r == null) {
4828                    return false;
4829                }
4830
4831                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4832                // can finish.
4833                final TaskRecord task = r.task;
4834                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4835                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4836                    mStackSupervisor.showLockTaskToast();
4837                    return false;
4838                }
4839                return task.stack.finishActivityAffinityLocked(r);
4840            } finally {
4841                Binder.restoreCallingIdentity(origId);
4842            }
4843        }
4844    }
4845
4846    @Override
4847    public void finishVoiceTask(IVoiceInteractionSession session) {
4848        synchronized (this) {
4849            final long origId = Binder.clearCallingIdentity();
4850            try {
4851                // TODO: VI Consider treating local voice interactions and voice tasks
4852                // differently here
4853                mStackSupervisor.finishVoiceTask(session);
4854            } finally {
4855                Binder.restoreCallingIdentity(origId);
4856            }
4857        }
4858
4859    }
4860
4861    @Override
4862    public boolean releaseActivityInstance(IBinder token) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            try {
4866                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4867                if (r == null) {
4868                    return false;
4869                }
4870                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4871            } finally {
4872                Binder.restoreCallingIdentity(origId);
4873            }
4874        }
4875    }
4876
4877    @Override
4878    public void releaseSomeActivities(IApplicationThread appInt) {
4879        synchronized(this) {
4880            final long origId = Binder.clearCallingIdentity();
4881            try {
4882                ProcessRecord app = getRecordForAppLocked(appInt);
4883                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public boolean willActivityBeVisible(IBinder token) {
4892        synchronized(this) {
4893            ActivityStack stack = ActivityRecord.getStackLocked(token);
4894            if (stack != null) {
4895                return stack.willActivityBeVisibleLocked(token);
4896            }
4897            return false;
4898        }
4899    }
4900
4901    @Override
4902    public void overridePendingTransition(IBinder token, String packageName,
4903            int enterAnim, int exitAnim) {
4904        synchronized(this) {
4905            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4906            if (self == null) {
4907                return;
4908            }
4909
4910            final long origId = Binder.clearCallingIdentity();
4911
4912            if (self.state == ActivityState.RESUMED
4913                    || self.state == ActivityState.PAUSING) {
4914                mWindowManager.overridePendingAppTransition(packageName,
4915                        enterAnim, exitAnim, null);
4916            }
4917
4918            Binder.restoreCallingIdentity(origId);
4919        }
4920    }
4921
4922    /**
4923     * Main function for removing an existing process from the activity manager
4924     * as a result of that process going away.  Clears out all connections
4925     * to the process.
4926     */
4927    private final void handleAppDiedLocked(ProcessRecord app,
4928            boolean restarting, boolean allowRestart) {
4929        int pid = app.pid;
4930        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4931        if (!kept && !restarting) {
4932            removeLruProcessLocked(app);
4933            if (pid > 0) {
4934                ProcessList.remove(pid);
4935            }
4936        }
4937
4938        if (mProfileProc == app) {
4939            clearProfilerLocked();
4940        }
4941
4942        // Remove this application's activities from active lists.
4943        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4944
4945        app.activities.clear();
4946
4947        if (app.instrumentationClass != null) {
4948            Slog.w(TAG, "Crash of app " + app.processName
4949                  + " running instrumentation " + app.instrumentationClass);
4950            Bundle info = new Bundle();
4951            info.putString("shortMsg", "Process crashed.");
4952            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4953        }
4954
4955        if (!restarting && hasVisibleActivities
4956                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4957            // If there was nothing to resume, and we are not already restarting this process, but
4958            // there is a visible activity that is hosted by the process...  then make sure all
4959            // visible activities are running, taking care of restarting this process.
4960            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4961        }
4962    }
4963
4964    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4965        IBinder threadBinder = thread.asBinder();
4966        // Find the application record.
4967        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4968            ProcessRecord rec = mLruProcesses.get(i);
4969            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4970                return i;
4971            }
4972        }
4973        return -1;
4974    }
4975
4976    final ProcessRecord getRecordForAppLocked(
4977            IApplicationThread thread) {
4978        if (thread == null) {
4979            return null;
4980        }
4981
4982        int appIndex = getLRURecordIndexForAppLocked(thread);
4983        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4984    }
4985
4986    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4987        // If there are no longer any background processes running,
4988        // and the app that died was not running instrumentation,
4989        // then tell everyone we are now low on memory.
4990        boolean haveBg = false;
4991        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4992            ProcessRecord rec = mLruProcesses.get(i);
4993            if (rec.thread != null
4994                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4995                haveBg = true;
4996                break;
4997            }
4998        }
4999
5000        if (!haveBg) {
5001            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5002            if (doReport) {
5003                long now = SystemClock.uptimeMillis();
5004                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5005                    doReport = false;
5006                } else {
5007                    mLastMemUsageReportTime = now;
5008                }
5009            }
5010            final ArrayList<ProcessMemInfo> memInfos
5011                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5012            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5013            long now = SystemClock.uptimeMillis();
5014            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5015                ProcessRecord rec = mLruProcesses.get(i);
5016                if (rec == dyingProc || rec.thread == null) {
5017                    continue;
5018                }
5019                if (doReport) {
5020                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5021                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5022                }
5023                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5024                    // The low memory report is overriding any current
5025                    // state for a GC request.  Make sure to do
5026                    // heavy/important/visible/foreground processes first.
5027                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5028                        rec.lastRequestedGc = 0;
5029                    } else {
5030                        rec.lastRequestedGc = rec.lastLowMemory;
5031                    }
5032                    rec.reportLowMemory = true;
5033                    rec.lastLowMemory = now;
5034                    mProcessesToGc.remove(rec);
5035                    addProcessToGcListLocked(rec);
5036                }
5037            }
5038            if (doReport) {
5039                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5040                mHandler.sendMessage(msg);
5041            }
5042            scheduleAppGcsLocked();
5043        }
5044    }
5045
5046    final void appDiedLocked(ProcessRecord app) {
5047       appDiedLocked(app, app.pid, app.thread, false);
5048    }
5049
5050    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5051            boolean fromBinderDied) {
5052        // First check if this ProcessRecord is actually active for the pid.
5053        synchronized (mPidsSelfLocked) {
5054            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5055            if (curProc != app) {
5056                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5057                return;
5058            }
5059        }
5060
5061        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5062        synchronized (stats) {
5063            stats.noteProcessDiedLocked(app.info.uid, pid);
5064        }
5065
5066        if (!app.killed) {
5067            if (!fromBinderDied) {
5068                Process.killProcessQuiet(pid);
5069            }
5070            killProcessGroup(app.uid, pid);
5071            app.killed = true;
5072        }
5073
5074        // Clean up already done if the process has been re-started.
5075        if (app.pid == pid && app.thread != null &&
5076                app.thread.asBinder() == thread.asBinder()) {
5077            boolean doLowMem = app.instrumentationClass == null;
5078            boolean doOomAdj = doLowMem;
5079            if (!app.killedByAm) {
5080                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5081                        + ") has died");
5082                mAllowLowerMemLevel = true;
5083            } else {
5084                // Note that we always want to do oom adj to update our state with the
5085                // new number of procs.
5086                mAllowLowerMemLevel = false;
5087                doLowMem = false;
5088            }
5089            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5090            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5091                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5092            handleAppDiedLocked(app, false, true);
5093
5094            if (doOomAdj) {
5095                updateOomAdjLocked();
5096            }
5097            if (doLowMem) {
5098                doLowMemReportIfNeededLocked(app);
5099            }
5100        } else if (app.pid != pid) {
5101            // A new process has already been started.
5102            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5103                    + ") has died and restarted (pid " + app.pid + ").");
5104            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5105        } else if (DEBUG_PROCESSES) {
5106            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5107                    + thread.asBinder());
5108        }
5109    }
5110
5111    /**
5112     * If a stack trace dump file is configured, dump process stack traces.
5113     * @param clearTraces causes the dump file to be erased prior to the new
5114     *    traces being written, if true; when false, the new traces will be
5115     *    appended to any existing file content.
5116     * @param firstPids of dalvik VM processes to dump stack traces for first
5117     * @param lastPids of dalvik VM processes to dump stack traces for last
5118     * @param nativeProcs optional list of native process names to dump stack crawls
5119     * @return file containing stack traces, or null if no dump file is configured
5120     */
5121    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5122            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5123        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5124        if (tracesPath == null || tracesPath.length() == 0) {
5125            return null;
5126        }
5127
5128        File tracesFile = new File(tracesPath);
5129        try {
5130            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5131            tracesFile.createNewFile();
5132            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5133        } catch (IOException e) {
5134            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5135            return null;
5136        }
5137
5138        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5139        return tracesFile;
5140    }
5141
5142    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5143            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5144        // Use a FileObserver to detect when traces finish writing.
5145        // The order of traces is considered important to maintain for legibility.
5146        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5147            @Override
5148            public synchronized void onEvent(int event, String path) { notify(); }
5149        };
5150
5151        try {
5152            observer.startWatching();
5153
5154            // First collect all of the stacks of the most important pids.
5155            if (firstPids != null) {
5156                try {
5157                    int num = firstPids.size();
5158                    for (int i = 0; i < num; i++) {
5159                        synchronized (observer) {
5160                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5161                                    + firstPids.get(i));
5162                            final long sime = SystemClock.elapsedRealtime();
5163                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5164                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5165                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5166                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5167                        }
5168                    }
5169                } catch (InterruptedException e) {
5170                    Slog.wtf(TAG, e);
5171                }
5172            }
5173
5174            // Next collect the stacks of the native pids
5175            if (nativeProcs != null) {
5176                int[] pids = Process.getPidsForCommands(nativeProcs);
5177                if (pids != null) {
5178                    for (int pid : pids) {
5179                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5180                        final long sime = SystemClock.elapsedRealtime();
5181                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5182                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5183                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5184                    }
5185                }
5186            }
5187
5188            // Lastly, measure CPU usage.
5189            if (processCpuTracker != null) {
5190                processCpuTracker.init();
5191                System.gc();
5192                processCpuTracker.update();
5193                try {
5194                    synchronized (processCpuTracker) {
5195                        processCpuTracker.wait(500); // measure over 1/2 second.
5196                    }
5197                } catch (InterruptedException e) {
5198                }
5199                processCpuTracker.update();
5200
5201                // We'll take the stack crawls of just the top apps using CPU.
5202                final int N = processCpuTracker.countWorkingStats();
5203                int numProcs = 0;
5204                for (int i=0; i<N && numProcs<5; i++) {
5205                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5206                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5207                        numProcs++;
5208                        try {
5209                            synchronized (observer) {
5210                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5211                                        + stats.pid);
5212                                final long stime = SystemClock.elapsedRealtime();
5213                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5214                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5215                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5216                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5217                            }
5218                        } catch (InterruptedException e) {
5219                            Slog.wtf(TAG, e);
5220                        }
5221                    } else if (DEBUG_ANR) {
5222                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5223                                + stats.pid);
5224                    }
5225                }
5226            }
5227        } finally {
5228            observer.stopWatching();
5229        }
5230    }
5231
5232    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5233        if (true || IS_USER_BUILD) {
5234            return;
5235        }
5236        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5237        if (tracesPath == null || tracesPath.length() == 0) {
5238            return;
5239        }
5240
5241        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5242        StrictMode.allowThreadDiskWrites();
5243        try {
5244            final File tracesFile = new File(tracesPath);
5245            final File tracesDir = tracesFile.getParentFile();
5246            final File tracesTmp = new File(tracesDir, "__tmp__");
5247            try {
5248                if (tracesFile.exists()) {
5249                    tracesTmp.delete();
5250                    tracesFile.renameTo(tracesTmp);
5251                }
5252                StringBuilder sb = new StringBuilder();
5253                Time tobj = new Time();
5254                tobj.set(System.currentTimeMillis());
5255                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5256                sb.append(": ");
5257                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5258                sb.append(" since ");
5259                sb.append(msg);
5260                FileOutputStream fos = new FileOutputStream(tracesFile);
5261                fos.write(sb.toString().getBytes());
5262                if (app == null) {
5263                    fos.write("\n*** No application process!".getBytes());
5264                }
5265                fos.close();
5266                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5267            } catch (IOException e) {
5268                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5269                return;
5270            }
5271
5272            if (app != null) {
5273                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5274                firstPids.add(app.pid);
5275                dumpStackTraces(tracesPath, firstPids, null, null, null);
5276            }
5277
5278            File lastTracesFile = null;
5279            File curTracesFile = null;
5280            for (int i=9; i>=0; i--) {
5281                String name = String.format(Locale.US, "slow%02d.txt", i);
5282                curTracesFile = new File(tracesDir, name);
5283                if (curTracesFile.exists()) {
5284                    if (lastTracesFile != null) {
5285                        curTracesFile.renameTo(lastTracesFile);
5286                    } else {
5287                        curTracesFile.delete();
5288                    }
5289                }
5290                lastTracesFile = curTracesFile;
5291            }
5292            tracesFile.renameTo(curTracesFile);
5293            if (tracesTmp.exists()) {
5294                tracesTmp.renameTo(tracesFile);
5295            }
5296        } finally {
5297            StrictMode.setThreadPolicy(oldPolicy);
5298        }
5299    }
5300
5301    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5302        if (!mLaunchWarningShown) {
5303            mLaunchWarningShown = true;
5304            mUiHandler.post(new Runnable() {
5305                @Override
5306                public void run() {
5307                    synchronized (ActivityManagerService.this) {
5308                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5309                        d.show();
5310                        mUiHandler.postDelayed(new Runnable() {
5311                            @Override
5312                            public void run() {
5313                                synchronized (ActivityManagerService.this) {
5314                                    d.dismiss();
5315                                    mLaunchWarningShown = false;
5316                                }
5317                            }
5318                        }, 4000);
5319                    }
5320                }
5321            });
5322        }
5323    }
5324
5325    @Override
5326    public boolean clearApplicationUserData(final String packageName,
5327            final IPackageDataObserver observer, int userId) {
5328        enforceNotIsolatedCaller("clearApplicationUserData");
5329        int uid = Binder.getCallingUid();
5330        int pid = Binder.getCallingPid();
5331        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5332                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5333
5334        final DevicePolicyManagerInternal dpmi = LocalServices
5335                .getService(DevicePolicyManagerInternal.class);
5336        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5337            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5338        }
5339
5340        long callingId = Binder.clearCallingIdentity();
5341        try {
5342            IPackageManager pm = AppGlobals.getPackageManager();
5343            int pkgUid = -1;
5344            synchronized(this) {
5345                try {
5346                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5347                } catch (RemoteException e) {
5348                }
5349                if (pkgUid == -1) {
5350                    Slog.w(TAG, "Invalid packageName: " + packageName);
5351                    if (observer != null) {
5352                        try {
5353                            observer.onRemoveCompleted(packageName, false);
5354                        } catch (RemoteException e) {
5355                            Slog.i(TAG, "Observer no longer exists.");
5356                        }
5357                    }
5358                    return false;
5359                }
5360                if (uid == pkgUid || checkComponentPermission(
5361                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5362                        pid, uid, -1, true)
5363                        == PackageManager.PERMISSION_GRANTED) {
5364                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5365                } else {
5366                    throw new SecurityException("PID " + pid + " does not have permission "
5367                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5368                                    + " of package " + packageName);
5369                }
5370
5371                // Remove all tasks match the cleared application package and user
5372                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5373                    final TaskRecord tr = mRecentTasks.get(i);
5374                    final String taskPackageName =
5375                            tr.getBaseIntent().getComponent().getPackageName();
5376                    if (tr.userId != userId) continue;
5377                    if (!taskPackageName.equals(packageName)) continue;
5378                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5379                }
5380            }
5381
5382            try {
5383                // Clear application user data
5384                pm.clearApplicationUserData(packageName, observer, userId);
5385
5386                synchronized(this) {
5387                    // Remove all permissions granted from/to this package
5388                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5389                }
5390
5391                // Remove all zen rules created by this package; revoke it's zen access.
5392                INotificationManager inm = NotificationManager.getService();
5393                inm.removeAutomaticZenRules(packageName);
5394                inm.setNotificationPolicyAccessGranted(packageName, false);
5395
5396                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5397                        Uri.fromParts("package", packageName, null));
5398                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5399                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5400                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5401                        null, null, 0, null, null, null, null, false, false, userId);
5402            } catch (RemoteException e) {
5403            }
5404        } finally {
5405            Binder.restoreCallingIdentity(callingId);
5406        }
5407        return true;
5408    }
5409
5410    @Override
5411    public void killBackgroundProcesses(final String packageName, int userId) {
5412        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5413                != PackageManager.PERMISSION_GRANTED &&
5414                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5415                        != PackageManager.PERMISSION_GRANTED) {
5416            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5417                    + Binder.getCallingPid()
5418                    + ", uid=" + Binder.getCallingUid()
5419                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5420            Slog.w(TAG, msg);
5421            throw new SecurityException(msg);
5422        }
5423
5424        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5425                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5426        long callingId = Binder.clearCallingIdentity();
5427        try {
5428            IPackageManager pm = AppGlobals.getPackageManager();
5429            synchronized(this) {
5430                int appId = -1;
5431                try {
5432                    appId = UserHandle.getAppId(
5433                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5434                } catch (RemoteException e) {
5435                }
5436                if (appId == -1) {
5437                    Slog.w(TAG, "Invalid packageName: " + packageName);
5438                    return;
5439                }
5440                killPackageProcessesLocked(packageName, appId, userId,
5441                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5442            }
5443        } finally {
5444            Binder.restoreCallingIdentity(callingId);
5445        }
5446    }
5447
5448    @Override
5449    public void killAllBackgroundProcesses() {
5450        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5451                != PackageManager.PERMISSION_GRANTED) {
5452            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5453                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5454                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5455            Slog.w(TAG, msg);
5456            throw new SecurityException(msg);
5457        }
5458
5459        final long callingId = Binder.clearCallingIdentity();
5460        try {
5461            synchronized (this) {
5462                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5463                final int NP = mProcessNames.getMap().size();
5464                for (int ip = 0; ip < NP; ip++) {
5465                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5466                    final int NA = apps.size();
5467                    for (int ia = 0; ia < NA; ia++) {
5468                        final ProcessRecord app = apps.valueAt(ia);
5469                        if (app.persistent) {
5470                            // We don't kill persistent processes.
5471                            continue;
5472                        }
5473                        if (app.removed) {
5474                            procs.add(app);
5475                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5476                            app.removed = true;
5477                            procs.add(app);
5478                        }
5479                    }
5480                }
5481
5482                final int N = procs.size();
5483                for (int i = 0; i < N; i++) {
5484                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5485                }
5486
5487                mAllowLowerMemLevel = true;
5488
5489                updateOomAdjLocked();
5490                doLowMemReportIfNeededLocked(null);
5491            }
5492        } finally {
5493            Binder.restoreCallingIdentity(callingId);
5494        }
5495    }
5496
5497    /**
5498     * Kills all background processes, except those matching any of the
5499     * specified properties.
5500     *
5501     * @param minTargetSdk the target SDK version at or above which to preserve
5502     *                     processes, or {@code -1} to ignore the target SDK
5503     * @param maxProcState the process state at or below which to preserve
5504     *                     processes, or {@code -1} to ignore the process state
5505     */
5506    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5507        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5508                != PackageManager.PERMISSION_GRANTED) {
5509            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5510                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5511                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5512            Slog.w(TAG, msg);
5513            throw new SecurityException(msg);
5514        }
5515
5516        final long callingId = Binder.clearCallingIdentity();
5517        try {
5518            synchronized (this) {
5519                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5520                final int NP = mProcessNames.getMap().size();
5521                for (int ip = 0; ip < NP; ip++) {
5522                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5523                    final int NA = apps.size();
5524                    for (int ia = 0; ia < NA; ia++) {
5525                        final ProcessRecord app = apps.valueAt(ia);
5526                        if (app.removed) {
5527                            procs.add(app);
5528                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5529                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5530                            app.removed = true;
5531                            procs.add(app);
5532                        }
5533                    }
5534                }
5535
5536                final int N = procs.size();
5537                for (int i = 0; i < N; i++) {
5538                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5539                }
5540            }
5541        } finally {
5542            Binder.restoreCallingIdentity(callingId);
5543        }
5544    }
5545
5546    @Override
5547    public void forceStopPackage(final String packageName, int userId) {
5548        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5549                != PackageManager.PERMISSION_GRANTED) {
5550            String msg = "Permission Denial: forceStopPackage() from pid="
5551                    + Binder.getCallingPid()
5552                    + ", uid=" + Binder.getCallingUid()
5553                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5554            Slog.w(TAG, msg);
5555            throw new SecurityException(msg);
5556        }
5557        final int callingPid = Binder.getCallingPid();
5558        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5559                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5560        long callingId = Binder.clearCallingIdentity();
5561        try {
5562            IPackageManager pm = AppGlobals.getPackageManager();
5563            synchronized(this) {
5564                int[] users = userId == UserHandle.USER_ALL
5565                        ? mUserController.getUsers() : new int[] { userId };
5566                for (int user : users) {
5567                    int pkgUid = -1;
5568                    try {
5569                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5570                                user);
5571                    } catch (RemoteException e) {
5572                    }
5573                    if (pkgUid == -1) {
5574                        Slog.w(TAG, "Invalid packageName: " + packageName);
5575                        continue;
5576                    }
5577                    try {
5578                        pm.setPackageStoppedState(packageName, true, user);
5579                    } catch (RemoteException e) {
5580                    } catch (IllegalArgumentException e) {
5581                        Slog.w(TAG, "Failed trying to unstop package "
5582                                + packageName + ": " + e);
5583                    }
5584                    if (mUserController.isUserRunningLocked(user, 0)) {
5585                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5586                    }
5587                }
5588            }
5589        } finally {
5590            Binder.restoreCallingIdentity(callingId);
5591        }
5592    }
5593
5594    @Override
5595    public void addPackageDependency(String packageName) {
5596        synchronized (this) {
5597            int callingPid = Binder.getCallingPid();
5598            if (callingPid == Process.myPid()) {
5599                //  Yeah, um, no.
5600                return;
5601            }
5602            ProcessRecord proc;
5603            synchronized (mPidsSelfLocked) {
5604                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5605            }
5606            if (proc != null) {
5607                if (proc.pkgDeps == null) {
5608                    proc.pkgDeps = new ArraySet<String>(1);
5609                }
5610                proc.pkgDeps.add(packageName);
5611            }
5612        }
5613    }
5614
5615    /*
5616     * The pkg name and app id have to be specified.
5617     */
5618    @Override
5619    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5620        if (pkg == null) {
5621            return;
5622        }
5623        // Make sure the uid is valid.
5624        if (appid < 0) {
5625            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5626            return;
5627        }
5628        int callerUid = Binder.getCallingUid();
5629        // Only the system server can kill an application
5630        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5631            // Post an aysnc message to kill the application
5632            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5633            msg.arg1 = appid;
5634            msg.arg2 = 0;
5635            Bundle bundle = new Bundle();
5636            bundle.putString("pkg", pkg);
5637            bundle.putString("reason", reason);
5638            msg.obj = bundle;
5639            mHandler.sendMessage(msg);
5640        } else {
5641            throw new SecurityException(callerUid + " cannot kill pkg: " +
5642                    pkg);
5643        }
5644    }
5645
5646    @Override
5647    public void closeSystemDialogs(String reason) {
5648        enforceNotIsolatedCaller("closeSystemDialogs");
5649
5650        final int pid = Binder.getCallingPid();
5651        final int uid = Binder.getCallingUid();
5652        final long origId = Binder.clearCallingIdentity();
5653        try {
5654            synchronized (this) {
5655                // Only allow this from foreground processes, so that background
5656                // applications can't abuse it to prevent system UI from being shown.
5657                if (uid >= Process.FIRST_APPLICATION_UID) {
5658                    ProcessRecord proc;
5659                    synchronized (mPidsSelfLocked) {
5660                        proc = mPidsSelfLocked.get(pid);
5661                    }
5662                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5663                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5664                                + " from background process " + proc);
5665                        return;
5666                    }
5667                }
5668                closeSystemDialogsLocked(reason);
5669            }
5670        } finally {
5671            Binder.restoreCallingIdentity(origId);
5672        }
5673    }
5674
5675    void closeSystemDialogsLocked(String reason) {
5676        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5677        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                | Intent.FLAG_RECEIVER_FOREGROUND);
5679        if (reason != null) {
5680            intent.putExtra("reason", reason);
5681        }
5682        mWindowManager.closeSystemDialogs(reason);
5683
5684        mStackSupervisor.closeSystemDialogsLocked();
5685
5686        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5687                AppOpsManager.OP_NONE, null, false, false,
5688                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5689    }
5690
5691    @Override
5692    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5693        enforceNotIsolatedCaller("getProcessMemoryInfo");
5694        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5695        for (int i=pids.length-1; i>=0; i--) {
5696            ProcessRecord proc;
5697            int oomAdj;
5698            synchronized (this) {
5699                synchronized (mPidsSelfLocked) {
5700                    proc = mPidsSelfLocked.get(pids[i]);
5701                    oomAdj = proc != null ? proc.setAdj : 0;
5702                }
5703            }
5704            infos[i] = new Debug.MemoryInfo();
5705            Debug.getMemoryInfo(pids[i], infos[i]);
5706            if (proc != null) {
5707                synchronized (this) {
5708                    if (proc.thread != null && proc.setAdj == oomAdj) {
5709                        // Record this for posterity if the process has been stable.
5710                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5711                                infos[i].getTotalUss(), false, proc.pkgList);
5712                    }
5713                }
5714            }
5715        }
5716        return infos;
5717    }
5718
5719    @Override
5720    public long[] getProcessPss(int[] pids) {
5721        enforceNotIsolatedCaller("getProcessPss");
5722        long[] pss = new long[pids.length];
5723        for (int i=pids.length-1; i>=0; i--) {
5724            ProcessRecord proc;
5725            int oomAdj;
5726            synchronized (this) {
5727                synchronized (mPidsSelfLocked) {
5728                    proc = mPidsSelfLocked.get(pids[i]);
5729                    oomAdj = proc != null ? proc.setAdj : 0;
5730                }
5731            }
5732            long[] tmpUss = new long[1];
5733            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5734            if (proc != null) {
5735                synchronized (this) {
5736                    if (proc.thread != null && proc.setAdj == oomAdj) {
5737                        // Record this for posterity if the process has been stable.
5738                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5739                    }
5740                }
5741            }
5742        }
5743        return pss;
5744    }
5745
5746    @Override
5747    public void killApplicationProcess(String processName, int uid) {
5748        if (processName == null) {
5749            return;
5750        }
5751
5752        int callerUid = Binder.getCallingUid();
5753        // Only the system server can kill an application
5754        if (callerUid == Process.SYSTEM_UID) {
5755            synchronized (this) {
5756                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5757                if (app != null && app.thread != null) {
5758                    try {
5759                        app.thread.scheduleSuicide();
5760                    } catch (RemoteException e) {
5761                        // If the other end already died, then our work here is done.
5762                    }
5763                } else {
5764                    Slog.w(TAG, "Process/uid not found attempting kill of "
5765                            + processName + " / " + uid);
5766                }
5767            }
5768        } else {
5769            throw new SecurityException(callerUid + " cannot kill app process: " +
5770                    processName);
5771        }
5772    }
5773
5774    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5775        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5776                false, true, false, false, UserHandle.getUserId(uid), reason);
5777        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5778                Uri.fromParts("package", packageName, null));
5779        if (!mProcessesReady) {
5780            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5781                    | Intent.FLAG_RECEIVER_FOREGROUND);
5782        }
5783        intent.putExtra(Intent.EXTRA_UID, uid);
5784        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5785        broadcastIntentLocked(null, null, intent,
5786                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5787                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5788    }
5789
5790
5791    private final boolean killPackageProcessesLocked(String packageName, int appId,
5792            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5793            boolean doit, boolean evenPersistent, String reason) {
5794        ArrayList<ProcessRecord> procs = new ArrayList<>();
5795
5796        // Remove all processes this package may have touched: all with the
5797        // same UID (except for the system or root user), and all whose name
5798        // matches the package name.
5799        final int NP = mProcessNames.getMap().size();
5800        for (int ip=0; ip<NP; ip++) {
5801            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5802            final int NA = apps.size();
5803            for (int ia=0; ia<NA; ia++) {
5804                ProcessRecord app = apps.valueAt(ia);
5805                if (app.persistent && !evenPersistent) {
5806                    // we don't kill persistent processes
5807                    continue;
5808                }
5809                if (app.removed) {
5810                    if (doit) {
5811                        procs.add(app);
5812                    }
5813                    continue;
5814                }
5815
5816                // Skip process if it doesn't meet our oom adj requirement.
5817                if (app.setAdj < minOomAdj) {
5818                    continue;
5819                }
5820
5821                // If no package is specified, we call all processes under the
5822                // give user id.
5823                if (packageName == null) {
5824                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5825                        continue;
5826                    }
5827                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5828                        continue;
5829                    }
5830                // Package has been specified, we want to hit all processes
5831                // that match it.  We need to qualify this by the processes
5832                // that are running under the specified app and user ID.
5833                } else {
5834                    final boolean isDep = app.pkgDeps != null
5835                            && app.pkgDeps.contains(packageName);
5836                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5837                        continue;
5838                    }
5839                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5840                        continue;
5841                    }
5842                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5843                        continue;
5844                    }
5845                }
5846
5847                // Process has passed all conditions, kill it!
5848                if (!doit) {
5849                    return true;
5850                }
5851                app.removed = true;
5852                procs.add(app);
5853            }
5854        }
5855
5856        int N = procs.size();
5857        for (int i=0; i<N; i++) {
5858            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5859        }
5860        updateOomAdjLocked();
5861        return N > 0;
5862    }
5863
5864    private void cleanupDisabledPackageComponentsLocked(
5865            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5866
5867        Set<String> disabledClasses = null;
5868        boolean packageDisabled = false;
5869        IPackageManager pm = AppGlobals.getPackageManager();
5870
5871        if (changedClasses == null) {
5872            // Nothing changed...
5873            return;
5874        }
5875
5876        // Determine enable/disable state of the package and its components.
5877        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5878        for (int i = changedClasses.length - 1; i >= 0; i--) {
5879            final String changedClass = changedClasses[i];
5880
5881            if (changedClass.equals(packageName)) {
5882                try {
5883                    // Entire package setting changed
5884                    enabled = pm.getApplicationEnabledSetting(packageName,
5885                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5886                } catch (Exception e) {
5887                    // No such package/component; probably racing with uninstall.  In any
5888                    // event it means we have nothing further to do here.
5889                    return;
5890                }
5891                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5892                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5893                if (packageDisabled) {
5894                    // Entire package is disabled.
5895                    // No need to continue to check component states.
5896                    disabledClasses = null;
5897                    break;
5898                }
5899            } else {
5900                try {
5901                    enabled = pm.getComponentEnabledSetting(
5902                            new ComponentName(packageName, changedClass),
5903                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5904                } catch (Exception e) {
5905                    // As above, probably racing with uninstall.
5906                    return;
5907                }
5908                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5909                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5910                    if (disabledClasses == null) {
5911                        disabledClasses = new ArraySet<>(changedClasses.length);
5912                    }
5913                    disabledClasses.add(changedClass);
5914                }
5915            }
5916        }
5917
5918        if (!packageDisabled && disabledClasses == null) {
5919            // Nothing to do here...
5920            return;
5921        }
5922
5923        // Clean-up disabled activities.
5924        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5925                packageName, disabledClasses, true, false, userId) && mBooted) {
5926            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5927            mStackSupervisor.scheduleIdleLocked();
5928        }
5929
5930        // Clean-up disabled tasks
5931        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5932
5933        // Clean-up disabled services.
5934        mServices.bringDownDisabledPackageServicesLocked(
5935                packageName, disabledClasses, userId, false, killProcess, true);
5936
5937        // Clean-up disabled providers.
5938        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5939        mProviderMap.collectPackageProvidersLocked(
5940                packageName, disabledClasses, true, false, userId, providers);
5941        for (int i = providers.size() - 1; i >= 0; i--) {
5942            removeDyingProviderLocked(null, providers.get(i), true);
5943        }
5944
5945        // Clean-up disabled broadcast receivers.
5946        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5947            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5948                    packageName, disabledClasses, userId, true);
5949        }
5950
5951    }
5952
5953    final boolean forceStopPackageLocked(String packageName, int appId,
5954            boolean callerWillRestart, boolean purgeCache, boolean doit,
5955            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5956        int i;
5957
5958        if (userId == UserHandle.USER_ALL && packageName == null) {
5959            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5960        }
5961
5962        if (appId < 0 && packageName != null) {
5963            try {
5964                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5965                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5966            } catch (RemoteException e) {
5967            }
5968        }
5969
5970        if (doit) {
5971            if (packageName != null) {
5972                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5973                        + " user=" + userId + ": " + reason);
5974            } else {
5975                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5976            }
5977
5978            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5979        }
5980
5981        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5982                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5983                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5984
5985        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5986                packageName, null, doit, evenPersistent, userId)) {
5987            if (!doit) {
5988                return true;
5989            }
5990            didSomething = true;
5991        }
5992
5993        if (mServices.bringDownDisabledPackageServicesLocked(
5994                packageName, null, userId, evenPersistent, true, doit)) {
5995            if (!doit) {
5996                return true;
5997            }
5998            didSomething = true;
5999        }
6000
6001        if (packageName == null) {
6002            // Remove all sticky broadcasts from this user.
6003            mStickyBroadcasts.remove(userId);
6004        }
6005
6006        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6007        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6008                userId, providers)) {
6009            if (!doit) {
6010                return true;
6011            }
6012            didSomething = true;
6013        }
6014        for (i = providers.size() - 1; i >= 0; i--) {
6015            removeDyingProviderLocked(null, providers.get(i), true);
6016        }
6017
6018        // Remove transient permissions granted from/to this package/user
6019        removeUriPermissionsForPackageLocked(packageName, userId, false);
6020
6021        if (doit) {
6022            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6023                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6024                        packageName, null, userId, doit);
6025            }
6026        }
6027
6028        if (packageName == null || uninstalling) {
6029            // Remove pending intents.  For now we only do this when force
6030            // stopping users, because we have some problems when doing this
6031            // for packages -- app widgets are not currently cleaned up for
6032            // such packages, so they can be left with bad pending intents.
6033            if (mIntentSenderRecords.size() > 0) {
6034                Iterator<WeakReference<PendingIntentRecord>> it
6035                        = mIntentSenderRecords.values().iterator();
6036                while (it.hasNext()) {
6037                    WeakReference<PendingIntentRecord> wpir = it.next();
6038                    if (wpir == null) {
6039                        it.remove();
6040                        continue;
6041                    }
6042                    PendingIntentRecord pir = wpir.get();
6043                    if (pir == null) {
6044                        it.remove();
6045                        continue;
6046                    }
6047                    if (packageName == null) {
6048                        // Stopping user, remove all objects for the user.
6049                        if (pir.key.userId != userId) {
6050                            // Not the same user, skip it.
6051                            continue;
6052                        }
6053                    } else {
6054                        if (UserHandle.getAppId(pir.uid) != appId) {
6055                            // Different app id, skip it.
6056                            continue;
6057                        }
6058                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6059                            // Different user, skip it.
6060                            continue;
6061                        }
6062                        if (!pir.key.packageName.equals(packageName)) {
6063                            // Different package, skip it.
6064                            continue;
6065                        }
6066                    }
6067                    if (!doit) {
6068                        return true;
6069                    }
6070                    didSomething = true;
6071                    it.remove();
6072                    pir.canceled = true;
6073                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6074                        pir.key.activity.pendingResults.remove(pir.ref);
6075                    }
6076                }
6077            }
6078        }
6079
6080        if (doit) {
6081            if (purgeCache && packageName != null) {
6082                AttributeCache ac = AttributeCache.instance();
6083                if (ac != null) {
6084                    ac.removePackage(packageName);
6085                }
6086            }
6087            if (mBooted) {
6088                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6089                mStackSupervisor.scheduleIdleLocked();
6090            }
6091        }
6092
6093        return didSomething;
6094    }
6095
6096    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6097        ProcessRecord old = mProcessNames.remove(name, uid);
6098        if (old != null) {
6099            old.uidRecord.numProcs--;
6100            if (old.uidRecord.numProcs == 0) {
6101                // No more processes using this uid, tell clients it is gone.
6102                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6103                        "No more processes in " + old.uidRecord);
6104                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6105                mActiveUids.remove(uid);
6106                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6107            }
6108            old.uidRecord = null;
6109        }
6110        mIsolatedProcesses.remove(uid);
6111        return old;
6112    }
6113
6114    private final void addProcessNameLocked(ProcessRecord proc) {
6115        // We shouldn't already have a process under this name, but just in case we
6116        // need to clean up whatever may be there now.
6117        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6118        if (old == proc && proc.persistent) {
6119            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6120            Slog.w(TAG, "Re-adding persistent process " + proc);
6121        } else if (old != null) {
6122            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6123        }
6124        UidRecord uidRec = mActiveUids.get(proc.uid);
6125        if (uidRec == null) {
6126            uidRec = new UidRecord(proc.uid);
6127            // This is the first appearance of the uid, report it now!
6128            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6129                    "Creating new process uid: " + uidRec);
6130            mActiveUids.put(proc.uid, uidRec);
6131            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6132            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6133        }
6134        proc.uidRecord = uidRec;
6135        uidRec.numProcs++;
6136        mProcessNames.put(proc.processName, proc.uid, proc);
6137        if (proc.isolated) {
6138            mIsolatedProcesses.put(proc.uid, proc);
6139        }
6140    }
6141
6142    boolean removeProcessLocked(ProcessRecord app,
6143            boolean callerWillRestart, boolean allowRestart, String reason) {
6144        final String name = app.processName;
6145        final int uid = app.uid;
6146        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6147            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6148
6149        removeProcessNameLocked(name, uid);
6150        if (mHeavyWeightProcess == app) {
6151            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6152                    mHeavyWeightProcess.userId, 0));
6153            mHeavyWeightProcess = null;
6154        }
6155        boolean needRestart = false;
6156        if (app.pid > 0 && app.pid != MY_PID) {
6157            int pid = app.pid;
6158            synchronized (mPidsSelfLocked) {
6159                mPidsSelfLocked.remove(pid);
6160                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6161            }
6162            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6163            if (app.isolated) {
6164                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6165            }
6166            boolean willRestart = false;
6167            if (app.persistent && !app.isolated) {
6168                if (!callerWillRestart) {
6169                    willRestart = true;
6170                } else {
6171                    needRestart = true;
6172                }
6173            }
6174            app.kill(reason, true);
6175            handleAppDiedLocked(app, willRestart, allowRestart);
6176            if (willRestart) {
6177                removeLruProcessLocked(app);
6178                addAppLocked(app.info, false, null /* ABI override */);
6179            }
6180        } else {
6181            mRemovedProcesses.add(app);
6182        }
6183
6184        return needRestart;
6185    }
6186
6187    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6188        cleanupAppInLaunchingProvidersLocked(app, true);
6189        removeProcessLocked(app, false, true, "timeout publishing content providers");
6190    }
6191
6192    private final void processStartTimedOutLocked(ProcessRecord app) {
6193        final int pid = app.pid;
6194        boolean gone = false;
6195        synchronized (mPidsSelfLocked) {
6196            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6197            if (knownApp != null && knownApp.thread == null) {
6198                mPidsSelfLocked.remove(pid);
6199                gone = true;
6200            }
6201        }
6202
6203        if (gone) {
6204            Slog.w(TAG, "Process " + app + " failed to attach");
6205            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6206                    pid, app.uid, app.processName);
6207            removeProcessNameLocked(app.processName, app.uid);
6208            if (mHeavyWeightProcess == app) {
6209                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6210                        mHeavyWeightProcess.userId, 0));
6211                mHeavyWeightProcess = null;
6212            }
6213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6214            if (app.isolated) {
6215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6216            }
6217            // Take care of any launching providers waiting for this process.
6218            cleanupAppInLaunchingProvidersLocked(app, true);
6219            // Take care of any services that are waiting for the process.
6220            mServices.processStartTimedOutLocked(app);
6221            app.kill("start timeout", true);
6222            removeLruProcessLocked(app);
6223            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6224                Slog.w(TAG, "Unattached app died before backup, skipping");
6225                try {
6226                    IBackupManager bm = IBackupManager.Stub.asInterface(
6227                            ServiceManager.getService(Context.BACKUP_SERVICE));
6228                    bm.agentDisconnected(app.info.packageName);
6229                } catch (RemoteException e) {
6230                    // Can't happen; the backup manager is local
6231                }
6232            }
6233            if (isPendingBroadcastProcessLocked(pid)) {
6234                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6235                skipPendingBroadcastLocked(pid);
6236            }
6237        } else {
6238            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6239        }
6240    }
6241
6242    private final boolean attachApplicationLocked(IApplicationThread thread,
6243            int pid) {
6244
6245        // Find the application record that is being attached...  either via
6246        // the pid if we are running in multiple processes, or just pull the
6247        // next app record if we are emulating process with anonymous threads.
6248        ProcessRecord app;
6249        if (pid != MY_PID && pid >= 0) {
6250            synchronized (mPidsSelfLocked) {
6251                app = mPidsSelfLocked.get(pid);
6252            }
6253        } else {
6254            app = null;
6255        }
6256
6257        if (app == null) {
6258            Slog.w(TAG, "No pending application record for pid " + pid
6259                    + " (IApplicationThread " + thread + "); dropping process");
6260            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6261            if (pid > 0 && pid != MY_PID) {
6262                Process.killProcessQuiet(pid);
6263                //TODO: killProcessGroup(app.info.uid, pid);
6264            } else {
6265                try {
6266                    thread.scheduleExit();
6267                } catch (Exception e) {
6268                    // Ignore exceptions.
6269                }
6270            }
6271            return false;
6272        }
6273
6274        // If this application record is still attached to a previous
6275        // process, clean it up now.
6276        if (app.thread != null) {
6277            handleAppDiedLocked(app, true, true);
6278        }
6279
6280        // Tell the process all about itself.
6281
6282        if (DEBUG_ALL) Slog.v(
6283                TAG, "Binding process pid " + pid + " to record " + app);
6284
6285        final String processName = app.processName;
6286        try {
6287            AppDeathRecipient adr = new AppDeathRecipient(
6288                    app, pid, thread);
6289            thread.asBinder().linkToDeath(adr, 0);
6290            app.deathRecipient = adr;
6291        } catch (RemoteException e) {
6292            app.resetPackageList(mProcessStats);
6293            startProcessLocked(app, "link fail", processName);
6294            return false;
6295        }
6296
6297        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6298
6299        app.makeActive(thread, mProcessStats);
6300        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6301        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6302        app.forcingToForeground = null;
6303        updateProcessForegroundLocked(app, false, false);
6304        app.hasShownUi = false;
6305        app.debugging = false;
6306        app.cached = false;
6307        app.killedByAm = false;
6308        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6309
6310        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6311
6312        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6313        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6314
6315        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6316            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6317            msg.obj = app;
6318            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6319        }
6320
6321        if (!normalMode) {
6322            Slog.i(TAG, "Launching preboot mode app: " + app);
6323        }
6324
6325        if (DEBUG_ALL) Slog.v(
6326            TAG, "New app record " + app
6327            + " thread=" + thread.asBinder() + " pid=" + pid);
6328        try {
6329            int testMode = IApplicationThread.DEBUG_OFF;
6330            if (mDebugApp != null && mDebugApp.equals(processName)) {
6331                testMode = mWaitForDebugger
6332                    ? IApplicationThread.DEBUG_WAIT
6333                    : IApplicationThread.DEBUG_ON;
6334                app.debugging = true;
6335                if (mDebugTransient) {
6336                    mDebugApp = mOrigDebugApp;
6337                    mWaitForDebugger = mOrigWaitForDebugger;
6338                }
6339            }
6340            String profileFile = app.instrumentationProfileFile;
6341            ParcelFileDescriptor profileFd = null;
6342            int samplingInterval = 0;
6343            boolean profileAutoStop = false;
6344            if (mProfileApp != null && mProfileApp.equals(processName)) {
6345                mProfileProc = app;
6346                profileFile = mProfileFile;
6347                profileFd = mProfileFd;
6348                samplingInterval = mSamplingInterval;
6349                profileAutoStop = mAutoStopProfiler;
6350            }
6351            boolean enableTrackAllocation = false;
6352            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6353                enableTrackAllocation = true;
6354                mTrackAllocationApp = null;
6355            }
6356
6357            // If the app is being launched for restore or full backup, set it up specially
6358            boolean isRestrictedBackupMode = false;
6359            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6360                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6361                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6362                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6363                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6364            }
6365
6366            notifyPackageUse(app.instrumentationInfo != null
6367                    ? app.instrumentationInfo.packageName
6368                    : app.info.packageName);
6369            if (app.instrumentationClass != null) {
6370                notifyPackageUse(app.instrumentationClass.getPackageName());
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            try {
6452                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6453                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6454                        mBackupTarget.backupMode);
6455            } catch (Exception e) {
6456                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6457                badApp = true;
6458            }
6459        }
6460
6461        if (badApp) {
6462            app.kill("error during init", true);
6463            handleAppDiedLocked(app, false, true);
6464            return false;
6465        }
6466
6467        if (!didSomething) {
6468            updateOomAdjLocked();
6469        }
6470
6471        return true;
6472    }
6473
6474    @Override
6475    public final void attachApplication(IApplicationThread thread) {
6476        synchronized (this) {
6477            int callingPid = Binder.getCallingPid();
6478            final long origId = Binder.clearCallingIdentity();
6479            attachApplicationLocked(thread, callingPid);
6480            Binder.restoreCallingIdentity(origId);
6481        }
6482    }
6483
6484    @Override
6485    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6486        final long origId = Binder.clearCallingIdentity();
6487        synchronized (this) {
6488            ActivityStack stack = ActivityRecord.getStackLocked(token);
6489            if (stack != null) {
6490                ActivityRecord r =
6491                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6492                if (stopProfiling) {
6493                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6494                        try {
6495                            mProfileFd.close();
6496                        } catch (IOException e) {
6497                        }
6498                        clearProfilerLocked();
6499                    }
6500                }
6501            }
6502        }
6503        Binder.restoreCallingIdentity(origId);
6504    }
6505
6506    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6507        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6508                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6509    }
6510
6511    void enableScreenAfterBoot() {
6512        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6513                SystemClock.uptimeMillis());
6514        mWindowManager.enableScreenAfterBoot();
6515
6516        synchronized (this) {
6517            updateEventDispatchingLocked();
6518        }
6519    }
6520
6521    @Override
6522    public void showBootMessage(final CharSequence msg, final boolean always) {
6523        if (Binder.getCallingUid() != Process.myUid()) {
6524            // These days only the core system can call this, so apps can't get in
6525            // the way of what we show about running them.
6526        }
6527        mWindowManager.showBootMessage(msg, always);
6528    }
6529
6530    @Override
6531    public void keyguardWaitingForActivityDrawn() {
6532        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6533        final long token = Binder.clearCallingIdentity();
6534        try {
6535            synchronized (this) {
6536                if (DEBUG_LOCKSCREEN) logLockScreen("");
6537                mWindowManager.keyguardWaitingForActivityDrawn();
6538                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6539                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6540                    updateSleepIfNeededLocked();
6541                }
6542            }
6543        } finally {
6544            Binder.restoreCallingIdentity(token);
6545        }
6546    }
6547
6548    @Override
6549    public void keyguardGoingAway(int flags) {
6550        enforceNotIsolatedCaller("keyguardGoingAway");
6551        final long token = Binder.clearCallingIdentity();
6552        try {
6553            synchronized (this) {
6554                if (DEBUG_LOCKSCREEN) logLockScreen("");
6555                mWindowManager.keyguardGoingAway(flags);
6556                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6557                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6558                    updateSleepIfNeededLocked();
6559
6560                    // Some stack visibility might change (e.g. docked stack)
6561                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6562                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6563                }
6564            }
6565        } finally {
6566            Binder.restoreCallingIdentity(token);
6567        }
6568    }
6569
6570    final void finishBooting() {
6571        synchronized (this) {
6572            if (!mBootAnimationComplete) {
6573                mCallFinishBooting = true;
6574                return;
6575            }
6576            mCallFinishBooting = false;
6577        }
6578
6579        ArraySet<String> completedIsas = new ArraySet<String>();
6580        for (String abi : Build.SUPPORTED_ABIS) {
6581            Process.establishZygoteConnectionForAbi(abi);
6582            final String instructionSet = VMRuntime.getInstructionSet(abi);
6583            if (!completedIsas.contains(instructionSet)) {
6584                try {
6585                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6586                } catch (InstallerException e) {
6587                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6588                }
6589                completedIsas.add(instructionSet);
6590            }
6591        }
6592
6593        IntentFilter pkgFilter = new IntentFilter();
6594        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6595        pkgFilter.addDataScheme("package");
6596        mContext.registerReceiver(new BroadcastReceiver() {
6597            @Override
6598            public void onReceive(Context context, Intent intent) {
6599                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6600                if (pkgs != null) {
6601                    for (String pkg : pkgs) {
6602                        synchronized (ActivityManagerService.this) {
6603                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6604                                    0, "query restart")) {
6605                                setResultCode(Activity.RESULT_OK);
6606                                return;
6607                            }
6608                        }
6609                    }
6610                }
6611            }
6612        }, pkgFilter);
6613
6614        IntentFilter dumpheapFilter = new IntentFilter();
6615        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6616        mContext.registerReceiver(new BroadcastReceiver() {
6617            @Override
6618            public void onReceive(Context context, Intent intent) {
6619                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6620                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6621                } else {
6622                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6623                }
6624            }
6625        }, dumpheapFilter);
6626
6627        // Let system services know.
6628        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6629
6630        synchronized (this) {
6631            // Ensure that any processes we had put on hold are now started
6632            // up.
6633            final int NP = mProcessesOnHold.size();
6634            if (NP > 0) {
6635                ArrayList<ProcessRecord> procs =
6636                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6637                for (int ip=0; ip<NP; ip++) {
6638                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6639                            + procs.get(ip));
6640                    startProcessLocked(procs.get(ip), "on-hold", null);
6641                }
6642            }
6643
6644            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6645                // Start looking for apps that are abusing wake locks.
6646                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6647                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6648                // Tell anyone interested that we are done booting!
6649                SystemProperties.set("sys.boot_completed", "1");
6650
6651                // And trigger dev.bootcomplete if we are not showing encryption progress
6652                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6653                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6654                    SystemProperties.set("dev.bootcomplete", "1");
6655                }
6656                mUserController.sendBootCompletedLocked(
6657                        new IIntentReceiver.Stub() {
6658                            @Override
6659                            public void performReceive(Intent intent, int resultCode,
6660                                    String data, Bundle extras, boolean ordered,
6661                                    boolean sticky, int sendingUser) {
6662                                synchronized (ActivityManagerService.this) {
6663                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6664                                            true, false);
6665                                }
6666                            }
6667                        });
6668                scheduleStartProfilesLocked();
6669            }
6670        }
6671    }
6672
6673    @Override
6674    public void bootAnimationComplete() {
6675        final boolean callFinishBooting;
6676        synchronized (this) {
6677            callFinishBooting = mCallFinishBooting;
6678            mBootAnimationComplete = true;
6679        }
6680        if (callFinishBooting) {
6681            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6682            finishBooting();
6683            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6684        }
6685    }
6686
6687    final void ensureBootCompleted() {
6688        boolean booting;
6689        boolean enableScreen;
6690        synchronized (this) {
6691            booting = mBooting;
6692            mBooting = false;
6693            enableScreen = !mBooted;
6694            mBooted = true;
6695        }
6696
6697        if (booting) {
6698            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6699            finishBooting();
6700            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6701        }
6702
6703        if (enableScreen) {
6704            enableScreenAfterBoot();
6705        }
6706    }
6707
6708    @Override
6709    public final void activityResumed(IBinder token) {
6710        final long origId = Binder.clearCallingIdentity();
6711        synchronized(this) {
6712            ActivityStack stack = ActivityRecord.getStackLocked(token);
6713            if (stack != null) {
6714                stack.activityResumedLocked(token);
6715            }
6716        }
6717        Binder.restoreCallingIdentity(origId);
6718    }
6719
6720    @Override
6721    public final void activityPaused(IBinder token) {
6722        final long origId = Binder.clearCallingIdentity();
6723        synchronized(this) {
6724            ActivityStack stack = ActivityRecord.getStackLocked(token);
6725            if (stack != null) {
6726                stack.activityPausedLocked(token, false);
6727            }
6728        }
6729        Binder.restoreCallingIdentity(origId);
6730    }
6731
6732    @Override
6733    public final void activityStopped(IBinder token, Bundle icicle,
6734            PersistableBundle persistentState, CharSequence description) {
6735        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6736
6737        // Refuse possible leaked file descriptors
6738        if (icicle != null && icicle.hasFileDescriptors()) {
6739            throw new IllegalArgumentException("File descriptors passed in Bundle");
6740        }
6741
6742        final long origId = Binder.clearCallingIdentity();
6743
6744        synchronized (this) {
6745            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6746            if (r != null) {
6747                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6748            }
6749        }
6750
6751        trimApplications();
6752
6753        Binder.restoreCallingIdentity(origId);
6754    }
6755
6756    @Override
6757    public final void activityDestroyed(IBinder token) {
6758        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6759        synchronized (this) {
6760            ActivityStack stack = ActivityRecord.getStackLocked(token);
6761            if (stack != null) {
6762                stack.activityDestroyedLocked(token, "activityDestroyed");
6763            }
6764        }
6765    }
6766
6767    @Override
6768    public final void activityRelaunched(IBinder token) {
6769        final long origId = Binder.clearCallingIdentity();
6770        synchronized (this) {
6771            mStackSupervisor.activityRelaunchedLocked(token);
6772        }
6773        Binder.restoreCallingIdentity(origId);
6774    }
6775
6776    @Override
6777    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6778            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6779        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6780                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6781        synchronized (this) {
6782            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6783            if (record == null) {
6784                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6785                        + "found for: " + token);
6786            }
6787            record.setSizeConfigurations(horizontalSizeConfiguration,
6788                    verticalSizeConfigurations, smallestSizeConfigurations);
6789        }
6790    }
6791
6792    @Override
6793    public final void backgroundResourcesReleased(IBinder token) {
6794        final long origId = Binder.clearCallingIdentity();
6795        try {
6796            synchronized (this) {
6797                ActivityStack stack = ActivityRecord.getStackLocked(token);
6798                if (stack != null) {
6799                    stack.backgroundResourcesReleased();
6800                }
6801            }
6802        } finally {
6803            Binder.restoreCallingIdentity(origId);
6804        }
6805    }
6806
6807    @Override
6808    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6809        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6810    }
6811
6812    @Override
6813    public final void notifyEnterAnimationComplete(IBinder token) {
6814        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6815    }
6816
6817    @Override
6818    public String getCallingPackage(IBinder token) {
6819        synchronized (this) {
6820            ActivityRecord r = getCallingRecordLocked(token);
6821            return r != null ? r.info.packageName : null;
6822        }
6823    }
6824
6825    @Override
6826    public ComponentName getCallingActivity(IBinder token) {
6827        synchronized (this) {
6828            ActivityRecord r = getCallingRecordLocked(token);
6829            return r != null ? r.intent.getComponent() : null;
6830        }
6831    }
6832
6833    private ActivityRecord getCallingRecordLocked(IBinder token) {
6834        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6835        if (r == null) {
6836            return null;
6837        }
6838        return r.resultTo;
6839    }
6840
6841    @Override
6842    public ComponentName getActivityClassForToken(IBinder token) {
6843        synchronized(this) {
6844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6845            if (r == null) {
6846                return null;
6847            }
6848            return r.intent.getComponent();
6849        }
6850    }
6851
6852    @Override
6853    public String getPackageForToken(IBinder token) {
6854        synchronized(this) {
6855            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6856            if (r == null) {
6857                return null;
6858            }
6859            return r.packageName;
6860        }
6861    }
6862
6863    @Override
6864    public boolean isRootVoiceInteraction(IBinder token) {
6865        synchronized(this) {
6866            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6867            if (r == null) {
6868                return false;
6869            }
6870            return r.rootVoiceInteraction;
6871        }
6872    }
6873
6874    @Override
6875    public IIntentSender getIntentSender(int type,
6876            String packageName, IBinder token, String resultWho,
6877            int requestCode, Intent[] intents, String[] resolvedTypes,
6878            int flags, Bundle bOptions, int userId) {
6879        enforceNotIsolatedCaller("getIntentSender");
6880        // Refuse possible leaked file descriptors
6881        if (intents != null) {
6882            if (intents.length < 1) {
6883                throw new IllegalArgumentException("Intents array length must be >= 1");
6884            }
6885            for (int i=0; i<intents.length; i++) {
6886                Intent intent = intents[i];
6887                if (intent != null) {
6888                    if (intent.hasFileDescriptors()) {
6889                        throw new IllegalArgumentException("File descriptors passed in Intent");
6890                    }
6891                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6892                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6893                        throw new IllegalArgumentException(
6894                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6895                    }
6896                    intents[i] = new Intent(intent);
6897                }
6898            }
6899            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6900                throw new IllegalArgumentException(
6901                        "Intent array length does not match resolvedTypes length");
6902            }
6903        }
6904        if (bOptions != null) {
6905            if (bOptions.hasFileDescriptors()) {
6906                throw new IllegalArgumentException("File descriptors passed in options");
6907            }
6908        }
6909
6910        synchronized(this) {
6911            int callingUid = Binder.getCallingUid();
6912            int origUserId = userId;
6913            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6914                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6915                    ALLOW_NON_FULL, "getIntentSender", null);
6916            if (origUserId == UserHandle.USER_CURRENT) {
6917                // We don't want to evaluate this until the pending intent is
6918                // actually executed.  However, we do want to always do the
6919                // security checking for it above.
6920                userId = UserHandle.USER_CURRENT;
6921            }
6922            try {
6923                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6924                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6925                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6926                    if (!UserHandle.isSameApp(callingUid, uid)) {
6927                        String msg = "Permission Denial: getIntentSender() from pid="
6928                            + Binder.getCallingPid()
6929                            + ", uid=" + Binder.getCallingUid()
6930                            + ", (need uid=" + uid + ")"
6931                            + " is not allowed to send as package " + packageName;
6932                        Slog.w(TAG, msg);
6933                        throw new SecurityException(msg);
6934                    }
6935                }
6936
6937                return getIntentSenderLocked(type, packageName, callingUid, userId,
6938                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6939
6940            } catch (RemoteException e) {
6941                throw new SecurityException(e);
6942            }
6943        }
6944    }
6945
6946    IIntentSender getIntentSenderLocked(int type, String packageName,
6947            int callingUid, int userId, IBinder token, String resultWho,
6948            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6949            Bundle bOptions) {
6950        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6951        ActivityRecord activity = null;
6952        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6953            activity = ActivityRecord.isInStackLocked(token);
6954            if (activity == null) {
6955                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6956                return null;
6957            }
6958            if (activity.finishing) {
6959                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6960                return null;
6961            }
6962        }
6963
6964        // We're going to be splicing together extras before sending, so we're
6965        // okay poking into any contained extras.
6966        if (intents != null) {
6967            for (int i = 0; i < intents.length; i++) {
6968                intents[i].setDefusable(true);
6969            }
6970        }
6971        Bundle.setDefusable(bOptions, true);
6972
6973        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6974        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6975        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6976        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6977                |PendingIntent.FLAG_UPDATE_CURRENT);
6978
6979        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6980                type, packageName, activity, resultWho,
6981                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6982        WeakReference<PendingIntentRecord> ref;
6983        ref = mIntentSenderRecords.get(key);
6984        PendingIntentRecord rec = ref != null ? ref.get() : null;
6985        if (rec != null) {
6986            if (!cancelCurrent) {
6987                if (updateCurrent) {
6988                    if (rec.key.requestIntent != null) {
6989                        rec.key.requestIntent.replaceExtras(intents != null ?
6990                                intents[intents.length - 1] : null);
6991                    }
6992                    if (intents != null) {
6993                        intents[intents.length-1] = rec.key.requestIntent;
6994                        rec.key.allIntents = intents;
6995                        rec.key.allResolvedTypes = resolvedTypes;
6996                    } else {
6997                        rec.key.allIntents = null;
6998                        rec.key.allResolvedTypes = null;
6999                    }
7000                }
7001                return rec;
7002            }
7003            rec.canceled = true;
7004            mIntentSenderRecords.remove(key);
7005        }
7006        if (noCreate) {
7007            return rec;
7008        }
7009        rec = new PendingIntentRecord(this, key, callingUid);
7010        mIntentSenderRecords.put(key, rec.ref);
7011        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7012            if (activity.pendingResults == null) {
7013                activity.pendingResults
7014                        = new HashSet<WeakReference<PendingIntentRecord>>();
7015            }
7016            activity.pendingResults.add(rec.ref);
7017        }
7018        return rec;
7019    }
7020
7021    @Override
7022    public void cancelIntentSender(IIntentSender sender) {
7023        if (!(sender instanceof PendingIntentRecord)) {
7024            return;
7025        }
7026        synchronized(this) {
7027            PendingIntentRecord rec = (PendingIntentRecord)sender;
7028            try {
7029                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7030                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7031                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7032                    String msg = "Permission Denial: cancelIntentSender() from pid="
7033                        + Binder.getCallingPid()
7034                        + ", uid=" + Binder.getCallingUid()
7035                        + " is not allowed to cancel packges "
7036                        + rec.key.packageName;
7037                    Slog.w(TAG, msg);
7038                    throw new SecurityException(msg);
7039                }
7040            } catch (RemoteException e) {
7041                throw new SecurityException(e);
7042            }
7043            cancelIntentSenderLocked(rec, true);
7044        }
7045    }
7046
7047    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7048        rec.canceled = true;
7049        mIntentSenderRecords.remove(rec.key);
7050        if (cleanActivity && rec.key.activity != null) {
7051            rec.key.activity.pendingResults.remove(rec.ref);
7052        }
7053    }
7054
7055    @Override
7056    public String getPackageForIntentSender(IIntentSender pendingResult) {
7057        if (!(pendingResult instanceof PendingIntentRecord)) {
7058            return null;
7059        }
7060        try {
7061            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7062            return res.key.packageName;
7063        } catch (ClassCastException e) {
7064        }
7065        return null;
7066    }
7067
7068    @Override
7069    public int getUidForIntentSender(IIntentSender sender) {
7070        if (sender instanceof PendingIntentRecord) {
7071            try {
7072                PendingIntentRecord res = (PendingIntentRecord)sender;
7073                return res.uid;
7074            } catch (ClassCastException e) {
7075            }
7076        }
7077        return -1;
7078    }
7079
7080    @Override
7081    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7082        if (!(pendingResult instanceof PendingIntentRecord)) {
7083            return false;
7084        }
7085        try {
7086            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7087            if (res.key.allIntents == null) {
7088                return false;
7089            }
7090            for (int i=0; i<res.key.allIntents.length; i++) {
7091                Intent intent = res.key.allIntents[i];
7092                if (intent.getPackage() != null && intent.getComponent() != null) {
7093                    return false;
7094                }
7095            }
7096            return true;
7097        } catch (ClassCastException e) {
7098        }
7099        return false;
7100    }
7101
7102    @Override
7103    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7104        if (!(pendingResult instanceof PendingIntentRecord)) {
7105            return false;
7106        }
7107        try {
7108            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7109            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7110                return true;
7111            }
7112            return false;
7113        } catch (ClassCastException e) {
7114        }
7115        return false;
7116    }
7117
7118    @Override
7119    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7120        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7121                "getIntentForIntentSender()");
7122        if (!(pendingResult instanceof PendingIntentRecord)) {
7123            return null;
7124        }
7125        try {
7126            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7127            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7128        } catch (ClassCastException e) {
7129        }
7130        return null;
7131    }
7132
7133    @Override
7134    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7135        if (!(pendingResult instanceof PendingIntentRecord)) {
7136            return null;
7137        }
7138        try {
7139            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7140            synchronized (this) {
7141                return getTagForIntentSenderLocked(res, prefix);
7142            }
7143        } catch (ClassCastException e) {
7144        }
7145        return null;
7146    }
7147
7148    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7149        final Intent intent = res.key.requestIntent;
7150        if (intent != null) {
7151            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7152                    || res.lastTagPrefix.equals(prefix))) {
7153                return res.lastTag;
7154            }
7155            res.lastTagPrefix = prefix;
7156            final StringBuilder sb = new StringBuilder(128);
7157            if (prefix != null) {
7158                sb.append(prefix);
7159            }
7160            if (intent.getAction() != null) {
7161                sb.append(intent.getAction());
7162            } else if (intent.getComponent() != null) {
7163                intent.getComponent().appendShortString(sb);
7164            } else {
7165                sb.append("?");
7166            }
7167            return res.lastTag = sb.toString();
7168        }
7169        return null;
7170    }
7171
7172    @Override
7173    public void setProcessLimit(int max) {
7174        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7175                "setProcessLimit()");
7176        synchronized (this) {
7177            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7178            mProcessLimitOverride = max;
7179        }
7180        trimApplications();
7181    }
7182
7183    @Override
7184    public int getProcessLimit() {
7185        synchronized (this) {
7186            return mProcessLimitOverride;
7187        }
7188    }
7189
7190    void foregroundTokenDied(ForegroundToken token) {
7191        synchronized (ActivityManagerService.this) {
7192            synchronized (mPidsSelfLocked) {
7193                ForegroundToken cur
7194                    = mForegroundProcesses.get(token.pid);
7195                if (cur != token) {
7196                    return;
7197                }
7198                mForegroundProcesses.remove(token.pid);
7199                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7200                if (pr == null) {
7201                    return;
7202                }
7203                pr.forcingToForeground = null;
7204                updateProcessForegroundLocked(pr, false, false);
7205            }
7206            updateOomAdjLocked();
7207        }
7208    }
7209
7210    @Override
7211    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7212        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7213                "setProcessForeground()");
7214        synchronized(this) {
7215            boolean changed = false;
7216
7217            synchronized (mPidsSelfLocked) {
7218                ProcessRecord pr = mPidsSelfLocked.get(pid);
7219                if (pr == null && isForeground) {
7220                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7221                    return;
7222                }
7223                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7224                if (oldToken != null) {
7225                    oldToken.token.unlinkToDeath(oldToken, 0);
7226                    mForegroundProcesses.remove(pid);
7227                    if (pr != null) {
7228                        pr.forcingToForeground = null;
7229                    }
7230                    changed = true;
7231                }
7232                if (isForeground && token != null) {
7233                    ForegroundToken newToken = new ForegroundToken() {
7234                        @Override
7235                        public void binderDied() {
7236                            foregroundTokenDied(this);
7237                        }
7238                    };
7239                    newToken.pid = pid;
7240                    newToken.token = token;
7241                    try {
7242                        token.linkToDeath(newToken, 0);
7243                        mForegroundProcesses.put(pid, newToken);
7244                        pr.forcingToForeground = token;
7245                        changed = true;
7246                    } catch (RemoteException e) {
7247                        // If the process died while doing this, we will later
7248                        // do the cleanup with the process death link.
7249                    }
7250                }
7251            }
7252
7253            if (changed) {
7254                updateOomAdjLocked();
7255            }
7256        }
7257    }
7258
7259    @Override
7260    public boolean isAppForeground(int uid) throws RemoteException {
7261        synchronized (this) {
7262            UidRecord uidRec = mActiveUids.get(uid);
7263            if (uidRec == null || uidRec.idle) {
7264                return false;
7265            }
7266            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7267        }
7268    }
7269
7270    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7271    // be guarded by permission checking.
7272    int getUidState(int uid) {
7273        synchronized (this) {
7274            UidRecord uidRec = mActiveUids.get(uid);
7275            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7276        }
7277    }
7278
7279    @Override
7280    public boolean isInMultiWindowMode(IBinder token) {
7281        final long origId = Binder.clearCallingIdentity();
7282        try {
7283            synchronized(this) {
7284                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7285                if (r == null) {
7286                    return false;
7287                }
7288                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7289                return !r.task.mFullscreen;
7290            }
7291        } finally {
7292            Binder.restoreCallingIdentity(origId);
7293        }
7294    }
7295
7296    @Override
7297    public boolean isInPictureInPictureMode(IBinder token) {
7298        final long origId = Binder.clearCallingIdentity();
7299        try {
7300            synchronized(this) {
7301                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7302                if (stack == null) {
7303                    return false;
7304                }
7305                return stack.mStackId == PINNED_STACK_ID;
7306            }
7307        } finally {
7308            Binder.restoreCallingIdentity(origId);
7309        }
7310    }
7311
7312    @Override
7313    public void enterPictureInPictureMode(IBinder token) {
7314        final long origId = Binder.clearCallingIdentity();
7315        try {
7316            synchronized(this) {
7317                if (!mSupportsPictureInPicture) {
7318                    throw new IllegalStateException("enterPictureInPictureMode: "
7319                            + "Device doesn't support picture-in-picture mode.");
7320                }
7321
7322                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7323
7324                if (r == null) {
7325                    throw new IllegalStateException("enterPictureInPictureMode: "
7326                            + "Can't find activity for token=" + token);
7327                }
7328
7329                if (!r.supportsPictureInPicture()) {
7330                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7331                            + "Picture-In-Picture not supported for r=" + r);
7332                }
7333
7334                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7335                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7336                        ? mDefaultPinnedStackBounds : null;
7337
7338                mStackSupervisor.moveActivityToPinnedStackLocked(
7339                        r, "enterPictureInPictureMode", bounds);
7340            }
7341        } finally {
7342            Binder.restoreCallingIdentity(origId);
7343        }
7344    }
7345
7346    // =========================================================
7347    // PROCESS INFO
7348    // =========================================================
7349
7350    static class ProcessInfoService extends IProcessInfoService.Stub {
7351        final ActivityManagerService mActivityManagerService;
7352        ProcessInfoService(ActivityManagerService activityManagerService) {
7353            mActivityManagerService = activityManagerService;
7354        }
7355
7356        @Override
7357        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7358            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7359                    /*in*/ pids, /*out*/ states, null);
7360        }
7361
7362        @Override
7363        public void getProcessStatesAndOomScoresFromPids(
7364                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7365            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7366                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7367        }
7368    }
7369
7370    /**
7371     * For each PID in the given input array, write the current process state
7372     * for that process into the states array, or -1 to indicate that no
7373     * process with the given PID exists. If scores array is provided, write
7374     * the oom score for the process into the scores array, with INVALID_ADJ
7375     * indicating the PID doesn't exist.
7376     */
7377    public void getProcessStatesAndOomScoresForPIDs(
7378            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7379        if (scores != null) {
7380            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7381                    "getProcessStatesAndOomScoresForPIDs()");
7382        }
7383
7384        if (pids == null) {
7385            throw new NullPointerException("pids");
7386        } else if (states == null) {
7387            throw new NullPointerException("states");
7388        } else if (pids.length != states.length) {
7389            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7390        } else if (scores != null && pids.length != scores.length) {
7391            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7392        }
7393
7394        synchronized (mPidsSelfLocked) {
7395            for (int i = 0; i < pids.length; i++) {
7396                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7397                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7398                        pr.curProcState;
7399                if (scores != null) {
7400                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7401                }
7402            }
7403        }
7404    }
7405
7406    // =========================================================
7407    // PERMISSIONS
7408    // =========================================================
7409
7410    static class PermissionController extends IPermissionController.Stub {
7411        ActivityManagerService mActivityManagerService;
7412        PermissionController(ActivityManagerService activityManagerService) {
7413            mActivityManagerService = activityManagerService;
7414        }
7415
7416        @Override
7417        public boolean checkPermission(String permission, int pid, int uid) {
7418            return mActivityManagerService.checkPermission(permission, pid,
7419                    uid) == PackageManager.PERMISSION_GRANTED;
7420        }
7421
7422        @Override
7423        public String[] getPackagesForUid(int uid) {
7424            return mActivityManagerService.mContext.getPackageManager()
7425                    .getPackagesForUid(uid);
7426        }
7427
7428        @Override
7429        public boolean isRuntimePermission(String permission) {
7430            try {
7431                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7432                        .getPermissionInfo(permission, 0);
7433                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7434            } catch (NameNotFoundException nnfe) {
7435                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7436            }
7437            return false;
7438        }
7439    }
7440
7441    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7442        @Override
7443        public int checkComponentPermission(String permission, int pid, int uid,
7444                int owningUid, boolean exported) {
7445            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7446                    owningUid, exported);
7447        }
7448
7449        @Override
7450        public Object getAMSLock() {
7451            return ActivityManagerService.this;
7452        }
7453    }
7454
7455    /**
7456     * This can be called with or without the global lock held.
7457     */
7458    int checkComponentPermission(String permission, int pid, int uid,
7459            int owningUid, boolean exported) {
7460        if (pid == MY_PID) {
7461            return PackageManager.PERMISSION_GRANTED;
7462        }
7463        return ActivityManager.checkComponentPermission(permission, uid,
7464                owningUid, exported);
7465    }
7466
7467    /**
7468     * As the only public entry point for permissions checking, this method
7469     * can enforce the semantic that requesting a check on a null global
7470     * permission is automatically denied.  (Internally a null permission
7471     * string is used when calling {@link #checkComponentPermission} in cases
7472     * when only uid-based security is needed.)
7473     *
7474     * This can be called with or without the global lock held.
7475     */
7476    @Override
7477    public int checkPermission(String permission, int pid, int uid) {
7478        if (permission == null) {
7479            return PackageManager.PERMISSION_DENIED;
7480        }
7481        return checkComponentPermission(permission, pid, uid, -1, true);
7482    }
7483
7484    @Override
7485    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7486        if (permission == null) {
7487            return PackageManager.PERMISSION_DENIED;
7488        }
7489
7490        // We might be performing an operation on behalf of an indirect binder
7491        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7492        // client identity accordingly before proceeding.
7493        Identity tlsIdentity = sCallerIdentity.get();
7494        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7495            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7496                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7497            uid = tlsIdentity.uid;
7498            pid = tlsIdentity.pid;
7499        }
7500
7501        return checkComponentPermission(permission, pid, uid, -1, true);
7502    }
7503
7504    /**
7505     * Binder IPC calls go through the public entry point.
7506     * This can be called with or without the global lock held.
7507     */
7508    int checkCallingPermission(String permission) {
7509        return checkPermission(permission,
7510                Binder.getCallingPid(),
7511                UserHandle.getAppId(Binder.getCallingUid()));
7512    }
7513
7514    /**
7515     * This can be called with or without the global lock held.
7516     */
7517    void enforceCallingPermission(String permission, String func) {
7518        if (checkCallingPermission(permission)
7519                == PackageManager.PERMISSION_GRANTED) {
7520            return;
7521        }
7522
7523        String msg = "Permission Denial: " + func + " from pid="
7524                + Binder.getCallingPid()
7525                + ", uid=" + Binder.getCallingUid()
7526                + " requires " + permission;
7527        Slog.w(TAG, msg);
7528        throw new SecurityException(msg);
7529    }
7530
7531    /**
7532     * Determine if UID is holding permissions required to access {@link Uri} in
7533     * the given {@link ProviderInfo}. Final permission checking is always done
7534     * in {@link ContentProvider}.
7535     */
7536    private final boolean checkHoldingPermissionsLocked(
7537            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7538        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7539                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7540        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7541            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7542                    != PERMISSION_GRANTED) {
7543                return false;
7544            }
7545        }
7546        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7547    }
7548
7549    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7550            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7551        if (pi.applicationInfo.uid == uid) {
7552            return true;
7553        } else if (!pi.exported) {
7554            return false;
7555        }
7556
7557        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7558        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7559        try {
7560            // check if target holds top-level <provider> permissions
7561            if (!readMet && pi.readPermission != null && considerUidPermissions
7562                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7563                readMet = true;
7564            }
7565            if (!writeMet && pi.writePermission != null && considerUidPermissions
7566                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7567                writeMet = true;
7568            }
7569
7570            // track if unprotected read/write is allowed; any denied
7571            // <path-permission> below removes this ability
7572            boolean allowDefaultRead = pi.readPermission == null;
7573            boolean allowDefaultWrite = pi.writePermission == null;
7574
7575            // check if target holds any <path-permission> that match uri
7576            final PathPermission[] pps = pi.pathPermissions;
7577            if (pps != null) {
7578                final String path = grantUri.uri.getPath();
7579                int i = pps.length;
7580                while (i > 0 && (!readMet || !writeMet)) {
7581                    i--;
7582                    PathPermission pp = pps[i];
7583                    if (pp.match(path)) {
7584                        if (!readMet) {
7585                            final String pprperm = pp.getReadPermission();
7586                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7587                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7588                                    + ": match=" + pp.match(path)
7589                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7590                            if (pprperm != null) {
7591                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7592                                        == PERMISSION_GRANTED) {
7593                                    readMet = true;
7594                                } else {
7595                                    allowDefaultRead = false;
7596                                }
7597                            }
7598                        }
7599                        if (!writeMet) {
7600                            final String ppwperm = pp.getWritePermission();
7601                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7602                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7603                                    + ": match=" + pp.match(path)
7604                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7605                            if (ppwperm != null) {
7606                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7607                                        == PERMISSION_GRANTED) {
7608                                    writeMet = true;
7609                                } else {
7610                                    allowDefaultWrite = false;
7611                                }
7612                            }
7613                        }
7614                    }
7615                }
7616            }
7617
7618            // grant unprotected <provider> read/write, if not blocked by
7619            // <path-permission> above
7620            if (allowDefaultRead) readMet = true;
7621            if (allowDefaultWrite) writeMet = true;
7622
7623        } catch (RemoteException e) {
7624            return false;
7625        }
7626
7627        return readMet && writeMet;
7628    }
7629
7630    public int getAppStartMode(int uid, String packageName) {
7631        synchronized (this) {
7632            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7633        }
7634    }
7635
7636    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7637            boolean allowWhenForeground) {
7638        UidRecord uidRec = mActiveUids.get(uid);
7639        if (!mLenientBackgroundCheck) {
7640            if (!allowWhenForeground || uidRec == null
7641                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7642                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7643                        packageName) != AppOpsManager.MODE_ALLOWED) {
7644                    return ActivityManager.APP_START_MODE_DELAYED;
7645                }
7646            }
7647
7648        } else if (uidRec == null || uidRec.idle) {
7649            if (callingPid >= 0) {
7650                ProcessRecord proc;
7651                synchronized (mPidsSelfLocked) {
7652                    proc = mPidsSelfLocked.get(callingPid);
7653                }
7654                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7655                    // Whoever is instigating this is in the foreground, so we will allow it
7656                    // to go through.
7657                    return ActivityManager.APP_START_MODE_NORMAL;
7658                }
7659            }
7660            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7661                    != AppOpsManager.MODE_ALLOWED) {
7662                return ActivityManager.APP_START_MODE_DELAYED;
7663            }
7664        }
7665        return ActivityManager.APP_START_MODE_NORMAL;
7666    }
7667
7668    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7669        ProviderInfo pi = null;
7670        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7671        if (cpr != null) {
7672            pi = cpr.info;
7673        } else {
7674            try {
7675                pi = AppGlobals.getPackageManager().resolveContentProvider(
7676                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7677            } catch (RemoteException ex) {
7678            }
7679        }
7680        return pi;
7681    }
7682
7683    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7684        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7685        if (targetUris != null) {
7686            return targetUris.get(grantUri);
7687        }
7688        return null;
7689    }
7690
7691    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7692            String targetPkg, int targetUid, GrantUri grantUri) {
7693        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7694        if (targetUris == null) {
7695            targetUris = Maps.newArrayMap();
7696            mGrantedUriPermissions.put(targetUid, targetUris);
7697        }
7698
7699        UriPermission perm = targetUris.get(grantUri);
7700        if (perm == null) {
7701            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7702            targetUris.put(grantUri, perm);
7703        }
7704
7705        return perm;
7706    }
7707
7708    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7709            final int modeFlags) {
7710        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7711        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7712                : UriPermission.STRENGTH_OWNED;
7713
7714        // Root gets to do everything.
7715        if (uid == 0) {
7716            return true;
7717        }
7718
7719        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7720        if (perms == null) return false;
7721
7722        // First look for exact match
7723        final UriPermission exactPerm = perms.get(grantUri);
7724        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7725            return true;
7726        }
7727
7728        // No exact match, look for prefixes
7729        final int N = perms.size();
7730        for (int i = 0; i < N; i++) {
7731            final UriPermission perm = perms.valueAt(i);
7732            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7733                    && perm.getStrength(modeFlags) >= minStrength) {
7734                return true;
7735            }
7736        }
7737
7738        return false;
7739    }
7740
7741    /**
7742     * @param uri This uri must NOT contain an embedded userId.
7743     * @param userId The userId in which the uri is to be resolved.
7744     */
7745    @Override
7746    public int checkUriPermission(Uri uri, int pid, int uid,
7747            final int modeFlags, int userId, IBinder callerToken) {
7748        enforceNotIsolatedCaller("checkUriPermission");
7749
7750        // Another redirected-binder-call permissions check as in
7751        // {@link checkPermissionWithToken}.
7752        Identity tlsIdentity = sCallerIdentity.get();
7753        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7754            uid = tlsIdentity.uid;
7755            pid = tlsIdentity.pid;
7756        }
7757
7758        // Our own process gets to do everything.
7759        if (pid == MY_PID) {
7760            return PackageManager.PERMISSION_GRANTED;
7761        }
7762        synchronized (this) {
7763            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7764                    ? PackageManager.PERMISSION_GRANTED
7765                    : PackageManager.PERMISSION_DENIED;
7766        }
7767    }
7768
7769    /**
7770     * Check if the targetPkg can be granted permission to access uri by
7771     * the callingUid using the given modeFlags.  Throws a security exception
7772     * if callingUid is not allowed to do this.  Returns the uid of the target
7773     * if the URI permission grant should be performed; returns -1 if it is not
7774     * needed (for example targetPkg already has permission to access the URI).
7775     * If you already know the uid of the target, you can supply it in
7776     * lastTargetUid else set that to -1.
7777     */
7778    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7779            final int modeFlags, int lastTargetUid) {
7780        if (!Intent.isAccessUriMode(modeFlags)) {
7781            return -1;
7782        }
7783
7784        if (targetPkg != null) {
7785            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7786                    "Checking grant " + targetPkg + " permission to " + grantUri);
7787        }
7788
7789        final IPackageManager pm = AppGlobals.getPackageManager();
7790
7791        // If this is not a content: uri, we can't do anything with it.
7792        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7793            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7794                    "Can't grant URI permission for non-content URI: " + grantUri);
7795            return -1;
7796        }
7797
7798        final String authority = grantUri.uri.getAuthority();
7799        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7800        if (pi == null) {
7801            Slog.w(TAG, "No content provider found for permission check: " +
7802                    grantUri.uri.toSafeString());
7803            return -1;
7804        }
7805
7806        int targetUid = lastTargetUid;
7807        if (targetUid < 0 && targetPkg != null) {
7808            try {
7809                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7810                        UserHandle.getUserId(callingUid));
7811                if (targetUid < 0) {
7812                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7813                            "Can't grant URI permission no uid for: " + targetPkg);
7814                    return -1;
7815                }
7816            } catch (RemoteException ex) {
7817                return -1;
7818            }
7819        }
7820
7821        if (targetUid >= 0) {
7822            // First...  does the target actually need this permission?
7823            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7824                // No need to grant the target this permission.
7825                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7826                        "Target " + targetPkg + " already has full permission to " + grantUri);
7827                return -1;
7828            }
7829        } else {
7830            // First...  there is no target package, so can anyone access it?
7831            boolean allowed = pi.exported;
7832            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7833                if (pi.readPermission != null) {
7834                    allowed = false;
7835                }
7836            }
7837            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7838                if (pi.writePermission != null) {
7839                    allowed = false;
7840                }
7841            }
7842            if (allowed) {
7843                return -1;
7844            }
7845        }
7846
7847        /* There is a special cross user grant if:
7848         * - The target is on another user.
7849         * - Apps on the current user can access the uri without any uid permissions.
7850         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7851         * grant uri permissions.
7852         */
7853        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7854                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7855                modeFlags, false /*without considering the uid permissions*/);
7856
7857        // Second...  is the provider allowing granting of URI permissions?
7858        if (!specialCrossUserGrant) {
7859            if (!pi.grantUriPermissions) {
7860                throw new SecurityException("Provider " + pi.packageName
7861                        + "/" + pi.name
7862                        + " does not allow granting of Uri permissions (uri "
7863                        + grantUri + ")");
7864            }
7865            if (pi.uriPermissionPatterns != null) {
7866                final int N = pi.uriPermissionPatterns.length;
7867                boolean allowed = false;
7868                for (int i=0; i<N; i++) {
7869                    if (pi.uriPermissionPatterns[i] != null
7870                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7871                        allowed = true;
7872                        break;
7873                    }
7874                }
7875                if (!allowed) {
7876                    throw new SecurityException("Provider " + pi.packageName
7877                            + "/" + pi.name
7878                            + " does not allow granting of permission to path of Uri "
7879                            + grantUri);
7880                }
7881            }
7882        }
7883
7884        // Third...  does the caller itself have permission to access
7885        // this uri?
7886        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7887            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7888                // Require they hold a strong enough Uri permission
7889                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7890                    throw new SecurityException("Uid " + callingUid
7891                            + " does not have permission to uri " + grantUri);
7892                }
7893            }
7894        }
7895        return targetUid;
7896    }
7897
7898    /**
7899     * @param uri This uri must NOT contain an embedded userId.
7900     * @param userId The userId in which the uri is to be resolved.
7901     */
7902    @Override
7903    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7904            final int modeFlags, int userId) {
7905        enforceNotIsolatedCaller("checkGrantUriPermission");
7906        synchronized(this) {
7907            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7908                    new GrantUri(userId, uri, false), modeFlags, -1);
7909        }
7910    }
7911
7912    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7913            final int modeFlags, UriPermissionOwner owner) {
7914        if (!Intent.isAccessUriMode(modeFlags)) {
7915            return;
7916        }
7917
7918        // So here we are: the caller has the assumed permission
7919        // to the uri, and the target doesn't.  Let's now give this to
7920        // the target.
7921
7922        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7923                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7924
7925        final String authority = grantUri.uri.getAuthority();
7926        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7927        if (pi == null) {
7928            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7929            return;
7930        }
7931
7932        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7933            grantUri.prefix = true;
7934        }
7935        final UriPermission perm = findOrCreateUriPermissionLocked(
7936                pi.packageName, targetPkg, targetUid, grantUri);
7937        perm.grantModes(modeFlags, owner);
7938    }
7939
7940    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7941            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7942        if (targetPkg == null) {
7943            throw new NullPointerException("targetPkg");
7944        }
7945        int targetUid;
7946        final IPackageManager pm = AppGlobals.getPackageManager();
7947        try {
7948            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7949        } catch (RemoteException ex) {
7950            return;
7951        }
7952
7953        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7954                targetUid);
7955        if (targetUid < 0) {
7956            return;
7957        }
7958
7959        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7960                owner);
7961    }
7962
7963    static class NeededUriGrants extends ArrayList<GrantUri> {
7964        final String targetPkg;
7965        final int targetUid;
7966        final int flags;
7967
7968        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7969            this.targetPkg = targetPkg;
7970            this.targetUid = targetUid;
7971            this.flags = flags;
7972        }
7973    }
7974
7975    /**
7976     * Like checkGrantUriPermissionLocked, but takes an Intent.
7977     */
7978    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7979            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7980        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7981                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7982                + " clip=" + (intent != null ? intent.getClipData() : null)
7983                + " from " + intent + "; flags=0x"
7984                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7985
7986        if (targetPkg == null) {
7987            throw new NullPointerException("targetPkg");
7988        }
7989
7990        if (intent == null) {
7991            return null;
7992        }
7993        Uri data = intent.getData();
7994        ClipData clip = intent.getClipData();
7995        if (data == null && clip == null) {
7996            return null;
7997        }
7998        // Default userId for uris in the intent (if they don't specify it themselves)
7999        int contentUserHint = intent.getContentUserHint();
8000        if (contentUserHint == UserHandle.USER_CURRENT) {
8001            contentUserHint = UserHandle.getUserId(callingUid);
8002        }
8003        final IPackageManager pm = AppGlobals.getPackageManager();
8004        int targetUid;
8005        if (needed != null) {
8006            targetUid = needed.targetUid;
8007        } else {
8008            try {
8009                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8010                        targetUserId);
8011            } catch (RemoteException ex) {
8012                return null;
8013            }
8014            if (targetUid < 0) {
8015                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8016                        "Can't grant URI permission no uid for: " + targetPkg
8017                        + " on user " + targetUserId);
8018                return null;
8019            }
8020        }
8021        if (data != null) {
8022            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8023            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8024                    targetUid);
8025            if (targetUid > 0) {
8026                if (needed == null) {
8027                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8028                }
8029                needed.add(grantUri);
8030            }
8031        }
8032        if (clip != null) {
8033            for (int i=0; i<clip.getItemCount(); i++) {
8034                Uri uri = clip.getItemAt(i).getUri();
8035                if (uri != null) {
8036                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8037                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8038                            targetUid);
8039                    if (targetUid > 0) {
8040                        if (needed == null) {
8041                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8042                        }
8043                        needed.add(grantUri);
8044                    }
8045                } else {
8046                    Intent clipIntent = clip.getItemAt(i).getIntent();
8047                    if (clipIntent != null) {
8048                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8049                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8050                        if (newNeeded != null) {
8051                            needed = newNeeded;
8052                        }
8053                    }
8054                }
8055            }
8056        }
8057
8058        return needed;
8059    }
8060
8061    /**
8062     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8063     */
8064    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8065            UriPermissionOwner owner) {
8066        if (needed != null) {
8067            for (int i=0; i<needed.size(); i++) {
8068                GrantUri grantUri = needed.get(i);
8069                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8070                        grantUri, needed.flags, owner);
8071            }
8072        }
8073    }
8074
8075    void grantUriPermissionFromIntentLocked(int callingUid,
8076            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8077        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8078                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8079        if (needed == null) {
8080            return;
8081        }
8082
8083        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8084    }
8085
8086    /**
8087     * @param uri This uri must NOT contain an embedded userId.
8088     * @param userId The userId in which the uri is to be resolved.
8089     */
8090    @Override
8091    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8092            final int modeFlags, int userId) {
8093        enforceNotIsolatedCaller("grantUriPermission");
8094        GrantUri grantUri = new GrantUri(userId, uri, false);
8095        synchronized(this) {
8096            final ProcessRecord r = getRecordForAppLocked(caller);
8097            if (r == null) {
8098                throw new SecurityException("Unable to find app for caller "
8099                        + caller
8100                        + " when granting permission to uri " + grantUri);
8101            }
8102            if (targetPkg == null) {
8103                throw new IllegalArgumentException("null target");
8104            }
8105            if (grantUri == null) {
8106                throw new IllegalArgumentException("null uri");
8107            }
8108
8109            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8110                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8111                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8112                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8113
8114            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8115                    UserHandle.getUserId(r.uid));
8116        }
8117    }
8118
8119    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8120        if (perm.modeFlags == 0) {
8121            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8122                    perm.targetUid);
8123            if (perms != null) {
8124                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8125                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8126
8127                perms.remove(perm.uri);
8128                if (perms.isEmpty()) {
8129                    mGrantedUriPermissions.remove(perm.targetUid);
8130                }
8131            }
8132        }
8133    }
8134
8135    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8136        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                "Revoking all granted permissions to " + grantUri);
8138
8139        final IPackageManager pm = AppGlobals.getPackageManager();
8140        final String authority = grantUri.uri.getAuthority();
8141        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8142        if (pi == null) {
8143            Slog.w(TAG, "No content provider found for permission revoke: "
8144                    + grantUri.toSafeString());
8145            return;
8146        }
8147
8148        // Does the caller have this permission on the URI?
8149        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8150            // If they don't have direct access to the URI, then revoke any
8151            // ownerless URI permissions that have been granted to them.
8152            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8153            if (perms != null) {
8154                boolean persistChanged = false;
8155                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8156                    final UriPermission perm = it.next();
8157                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8158                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8159                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8160                                "Revoking non-owned " + perm.targetUid
8161                                + " permission to " + perm.uri);
8162                        persistChanged |= perm.revokeModes(
8163                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8164                        if (perm.modeFlags == 0) {
8165                            it.remove();
8166                        }
8167                    }
8168                }
8169                if (perms.isEmpty()) {
8170                    mGrantedUriPermissions.remove(callingUid);
8171                }
8172                if (persistChanged) {
8173                    schedulePersistUriGrants();
8174                }
8175            }
8176            return;
8177        }
8178
8179        boolean persistChanged = false;
8180
8181        // Go through all of the permissions and remove any that match.
8182        int N = mGrantedUriPermissions.size();
8183        for (int i = 0; i < N; i++) {
8184            final int targetUid = mGrantedUriPermissions.keyAt(i);
8185            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8186
8187            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8188                final UriPermission perm = it.next();
8189                if (perm.uri.sourceUserId == grantUri.sourceUserId
8190                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8191                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8192                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8193                    persistChanged |= perm.revokeModes(
8194                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8195                    if (perm.modeFlags == 0) {
8196                        it.remove();
8197                    }
8198                }
8199            }
8200
8201            if (perms.isEmpty()) {
8202                mGrantedUriPermissions.remove(targetUid);
8203                N--;
8204                i--;
8205            }
8206        }
8207
8208        if (persistChanged) {
8209            schedulePersistUriGrants();
8210        }
8211    }
8212
8213    /**
8214     * @param uri This uri must NOT contain an embedded userId.
8215     * @param userId The userId in which the uri is to be resolved.
8216     */
8217    @Override
8218    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8219            int userId) {
8220        enforceNotIsolatedCaller("revokeUriPermission");
8221        synchronized(this) {
8222            final ProcessRecord r = getRecordForAppLocked(caller);
8223            if (r == null) {
8224                throw new SecurityException("Unable to find app for caller "
8225                        + caller
8226                        + " when revoking permission to uri " + uri);
8227            }
8228            if (uri == null) {
8229                Slog.w(TAG, "revokeUriPermission: null uri");
8230                return;
8231            }
8232
8233            if (!Intent.isAccessUriMode(modeFlags)) {
8234                return;
8235            }
8236
8237            final String authority = uri.getAuthority();
8238            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8239            if (pi == null) {
8240                Slog.w(TAG, "No content provider found for permission revoke: "
8241                        + uri.toSafeString());
8242                return;
8243            }
8244
8245            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8246        }
8247    }
8248
8249    /**
8250     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8251     * given package.
8252     *
8253     * @param packageName Package name to match, or {@code null} to apply to all
8254     *            packages.
8255     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8256     *            to all users.
8257     * @param persistable If persistable grants should be removed.
8258     */
8259    private void removeUriPermissionsForPackageLocked(
8260            String packageName, int userHandle, boolean persistable) {
8261        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8262            throw new IllegalArgumentException("Must narrow by either package or user");
8263        }
8264
8265        boolean persistChanged = false;
8266
8267        int N = mGrantedUriPermissions.size();
8268        for (int i = 0; i < N; i++) {
8269            final int targetUid = mGrantedUriPermissions.keyAt(i);
8270            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8271
8272            // Only inspect grants matching user
8273            if (userHandle == UserHandle.USER_ALL
8274                    || userHandle == UserHandle.getUserId(targetUid)) {
8275                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8276                    final UriPermission perm = it.next();
8277
8278                    // Only inspect grants matching package
8279                    if (packageName == null || perm.sourcePkg.equals(packageName)
8280                            || perm.targetPkg.equals(packageName)) {
8281                        persistChanged |= perm.revokeModes(persistable
8282                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8283
8284                        // Only remove when no modes remain; any persisted grants
8285                        // will keep this alive.
8286                        if (perm.modeFlags == 0) {
8287                            it.remove();
8288                        }
8289                    }
8290                }
8291
8292                if (perms.isEmpty()) {
8293                    mGrantedUriPermissions.remove(targetUid);
8294                    N--;
8295                    i--;
8296                }
8297            }
8298        }
8299
8300        if (persistChanged) {
8301            schedulePersistUriGrants();
8302        }
8303    }
8304
8305    @Override
8306    public IBinder newUriPermissionOwner(String name) {
8307        enforceNotIsolatedCaller("newUriPermissionOwner");
8308        synchronized(this) {
8309            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8310            return owner.getExternalTokenLocked();
8311        }
8312    }
8313
8314    @Override
8315    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8316        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8317        synchronized(this) {
8318            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8319            if (r == null) {
8320                throw new IllegalArgumentException("Activity does not exist; token="
8321                        + activityToken);
8322            }
8323            return r.getUriPermissionsLocked().getExternalTokenLocked();
8324        }
8325    }
8326    /**
8327     * @param uri This uri must NOT contain an embedded userId.
8328     * @param sourceUserId The userId in which the uri is to be resolved.
8329     * @param targetUserId The userId of the app that receives the grant.
8330     */
8331    @Override
8332    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8333            final int modeFlags, int sourceUserId, int targetUserId) {
8334        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8335                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8336                "grantUriPermissionFromOwner", null);
8337        synchronized(this) {
8338            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8339            if (owner == null) {
8340                throw new IllegalArgumentException("Unknown owner: " + token);
8341            }
8342            if (fromUid != Binder.getCallingUid()) {
8343                if (Binder.getCallingUid() != Process.myUid()) {
8344                    // Only system code can grant URI permissions on behalf
8345                    // of other users.
8346                    throw new SecurityException("nice try");
8347                }
8348            }
8349            if (targetPkg == null) {
8350                throw new IllegalArgumentException("null target");
8351            }
8352            if (uri == null) {
8353                throw new IllegalArgumentException("null uri");
8354            }
8355
8356            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8357                    modeFlags, owner, targetUserId);
8358        }
8359    }
8360
8361    /**
8362     * @param uri This uri must NOT contain an embedded userId.
8363     * @param userId The userId in which the uri is to be resolved.
8364     */
8365    @Override
8366    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8367        synchronized(this) {
8368            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8369            if (owner == null) {
8370                throw new IllegalArgumentException("Unknown owner: " + token);
8371            }
8372
8373            if (uri == null) {
8374                owner.removeUriPermissionsLocked(mode);
8375            } else {
8376                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8377            }
8378        }
8379    }
8380
8381    private void schedulePersistUriGrants() {
8382        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8383            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8384                    10 * DateUtils.SECOND_IN_MILLIS);
8385        }
8386    }
8387
8388    private void writeGrantedUriPermissions() {
8389        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8390
8391        // Snapshot permissions so we can persist without lock
8392        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8393        synchronized (this) {
8394            final int size = mGrantedUriPermissions.size();
8395            for (int i = 0; i < size; i++) {
8396                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8397                for (UriPermission perm : perms.values()) {
8398                    if (perm.persistedModeFlags != 0) {
8399                        persist.add(perm.snapshot());
8400                    }
8401                }
8402            }
8403        }
8404
8405        FileOutputStream fos = null;
8406        try {
8407            fos = mGrantFile.startWrite();
8408
8409            XmlSerializer out = new FastXmlSerializer();
8410            out.setOutput(fos, StandardCharsets.UTF_8.name());
8411            out.startDocument(null, true);
8412            out.startTag(null, TAG_URI_GRANTS);
8413            for (UriPermission.Snapshot perm : persist) {
8414                out.startTag(null, TAG_URI_GRANT);
8415                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8416                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8417                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8418                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8419                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8420                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8421                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8422                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8423                out.endTag(null, TAG_URI_GRANT);
8424            }
8425            out.endTag(null, TAG_URI_GRANTS);
8426            out.endDocument();
8427
8428            mGrantFile.finishWrite(fos);
8429        } catch (IOException e) {
8430            if (fos != null) {
8431                mGrantFile.failWrite(fos);
8432            }
8433        }
8434    }
8435
8436    private void readGrantedUriPermissionsLocked() {
8437        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8438
8439        final long now = System.currentTimeMillis();
8440
8441        FileInputStream fis = null;
8442        try {
8443            fis = mGrantFile.openRead();
8444            final XmlPullParser in = Xml.newPullParser();
8445            in.setInput(fis, StandardCharsets.UTF_8.name());
8446
8447            int type;
8448            while ((type = in.next()) != END_DOCUMENT) {
8449                final String tag = in.getName();
8450                if (type == START_TAG) {
8451                    if (TAG_URI_GRANT.equals(tag)) {
8452                        final int sourceUserId;
8453                        final int targetUserId;
8454                        final int userHandle = readIntAttribute(in,
8455                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8456                        if (userHandle != UserHandle.USER_NULL) {
8457                            // For backwards compatibility.
8458                            sourceUserId = userHandle;
8459                            targetUserId = userHandle;
8460                        } else {
8461                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8462                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8463                        }
8464                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8465                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8466                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8467                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8468                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8469                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8470
8471                        // Sanity check that provider still belongs to source package
8472                        final ProviderInfo pi = getProviderInfoLocked(
8473                                uri.getAuthority(), sourceUserId);
8474                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8475                            int targetUid = -1;
8476                            try {
8477                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8478                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8479                            } catch (RemoteException e) {
8480                            }
8481                            if (targetUid != -1) {
8482                                final UriPermission perm = findOrCreateUriPermissionLocked(
8483                                        sourcePkg, targetPkg, targetUid,
8484                                        new GrantUri(sourceUserId, uri, prefix));
8485                                perm.initPersistedModes(modeFlags, createdTime);
8486                            }
8487                        } else {
8488                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8489                                    + " but instead found " + pi);
8490                        }
8491                    }
8492                }
8493            }
8494        } catch (FileNotFoundException e) {
8495            // Missing grants is okay
8496        } catch (IOException e) {
8497            Slog.wtf(TAG, "Failed reading Uri grants", e);
8498        } catch (XmlPullParserException e) {
8499            Slog.wtf(TAG, "Failed reading Uri grants", e);
8500        } finally {
8501            IoUtils.closeQuietly(fis);
8502        }
8503    }
8504
8505    /**
8506     * @param uri This uri must NOT contain an embedded userId.
8507     * @param userId The userId in which the uri is to be resolved.
8508     */
8509    @Override
8510    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8511        enforceNotIsolatedCaller("takePersistableUriPermission");
8512
8513        Preconditions.checkFlagsArgument(modeFlags,
8514                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8515
8516        synchronized (this) {
8517            final int callingUid = Binder.getCallingUid();
8518            boolean persistChanged = false;
8519            GrantUri grantUri = new GrantUri(userId, uri, false);
8520
8521            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8522                    new GrantUri(userId, uri, false));
8523            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8524                    new GrantUri(userId, uri, true));
8525
8526            final boolean exactValid = (exactPerm != null)
8527                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8528            final boolean prefixValid = (prefixPerm != null)
8529                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8530
8531            if (!(exactValid || prefixValid)) {
8532                throw new SecurityException("No persistable permission grants found for UID "
8533                        + callingUid + " and Uri " + grantUri.toSafeString());
8534            }
8535
8536            if (exactValid) {
8537                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8538            }
8539            if (prefixValid) {
8540                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8541            }
8542
8543            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8544
8545            if (persistChanged) {
8546                schedulePersistUriGrants();
8547            }
8548        }
8549    }
8550
8551    /**
8552     * @param uri This uri must NOT contain an embedded userId.
8553     * @param userId The userId in which the uri is to be resolved.
8554     */
8555    @Override
8556    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8557        enforceNotIsolatedCaller("releasePersistableUriPermission");
8558
8559        Preconditions.checkFlagsArgument(modeFlags,
8560                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8561
8562        synchronized (this) {
8563            final int callingUid = Binder.getCallingUid();
8564            boolean persistChanged = false;
8565
8566            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8567                    new GrantUri(userId, uri, false));
8568            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8569                    new GrantUri(userId, uri, true));
8570            if (exactPerm == null && prefixPerm == null) {
8571                throw new SecurityException("No permission grants found for UID " + callingUid
8572                        + " and Uri " + uri.toSafeString());
8573            }
8574
8575            if (exactPerm != null) {
8576                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8577                removeUriPermissionIfNeededLocked(exactPerm);
8578            }
8579            if (prefixPerm != null) {
8580                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8581                removeUriPermissionIfNeededLocked(prefixPerm);
8582            }
8583
8584            if (persistChanged) {
8585                schedulePersistUriGrants();
8586            }
8587        }
8588    }
8589
8590    /**
8591     * Prune any older {@link UriPermission} for the given UID until outstanding
8592     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8593     *
8594     * @return if any mutations occured that require persisting.
8595     */
8596    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8597        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8598        if (perms == null) return false;
8599        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8600
8601        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8602        for (UriPermission perm : perms.values()) {
8603            if (perm.persistedModeFlags != 0) {
8604                persisted.add(perm);
8605            }
8606        }
8607
8608        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8609        if (trimCount <= 0) return false;
8610
8611        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8612        for (int i = 0; i < trimCount; i++) {
8613            final UriPermission perm = persisted.get(i);
8614
8615            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8616                    "Trimming grant created at " + perm.persistedCreateTime);
8617
8618            perm.releasePersistableModes(~0);
8619            removeUriPermissionIfNeededLocked(perm);
8620        }
8621
8622        return true;
8623    }
8624
8625    @Override
8626    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8627            String packageName, boolean incoming) {
8628        enforceNotIsolatedCaller("getPersistedUriPermissions");
8629        Preconditions.checkNotNull(packageName, "packageName");
8630
8631        final int callingUid = Binder.getCallingUid();
8632        final IPackageManager pm = AppGlobals.getPackageManager();
8633        try {
8634            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8635                    UserHandle.getUserId(callingUid));
8636            if (packageUid != callingUid) {
8637                throw new SecurityException(
8638                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8639            }
8640        } catch (RemoteException e) {
8641            throw new SecurityException("Failed to verify package name ownership");
8642        }
8643
8644        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8645        synchronized (this) {
8646            if (incoming) {
8647                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8648                        callingUid);
8649                if (perms == null) {
8650                    Slog.w(TAG, "No permission grants found for " + packageName);
8651                } else {
8652                    for (UriPermission perm : perms.values()) {
8653                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8654                            result.add(perm.buildPersistedPublicApiObject());
8655                        }
8656                    }
8657                }
8658            } else {
8659                final int size = mGrantedUriPermissions.size();
8660                for (int i = 0; i < size; i++) {
8661                    final ArrayMap<GrantUri, UriPermission> perms =
8662                            mGrantedUriPermissions.valueAt(i);
8663                    for (UriPermission perm : perms.values()) {
8664                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8665                            result.add(perm.buildPersistedPublicApiObject());
8666                        }
8667                    }
8668                }
8669            }
8670        }
8671        return new ParceledListSlice<android.content.UriPermission>(result);
8672    }
8673
8674    @Override
8675    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8676            String packageName, int userId) {
8677        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8678                "getGrantedUriPermissions");
8679
8680        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8681        synchronized (this) {
8682            final int size = mGrantedUriPermissions.size();
8683            for (int i = 0; i < size; i++) {
8684                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8685                for (UriPermission perm : perms.values()) {
8686                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8687                            && perm.persistedModeFlags != 0) {
8688                        result.add(perm.buildPersistedPublicApiObject());
8689                    }
8690                }
8691            }
8692        }
8693        return new ParceledListSlice<android.content.UriPermission>(result);
8694    }
8695
8696    @Override
8697    public void clearGrantedUriPermissions(String packageName, int userId) {
8698        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8699                "clearGrantedUriPermissions");
8700        removeUriPermissionsForPackageLocked(packageName, userId, true);
8701    }
8702
8703    @Override
8704    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8705        synchronized (this) {
8706            ProcessRecord app =
8707                who != null ? getRecordForAppLocked(who) : null;
8708            if (app == null) return;
8709
8710            Message msg = Message.obtain();
8711            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8712            msg.obj = app;
8713            msg.arg1 = waiting ? 1 : 0;
8714            mUiHandler.sendMessage(msg);
8715        }
8716    }
8717
8718    @Override
8719    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8720        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8721        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8722        outInfo.availMem = Process.getFreeMemory();
8723        outInfo.totalMem = Process.getTotalMemory();
8724        outInfo.threshold = homeAppMem;
8725        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8726        outInfo.hiddenAppThreshold = cachedAppMem;
8727        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8728                ProcessList.SERVICE_ADJ);
8729        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8730                ProcessList.VISIBLE_APP_ADJ);
8731        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8732                ProcessList.FOREGROUND_APP_ADJ);
8733    }
8734
8735    // =========================================================
8736    // TASK MANAGEMENT
8737    // =========================================================
8738
8739    @Override
8740    public List<IAppTask> getAppTasks(String callingPackage) {
8741        int callingUid = Binder.getCallingUid();
8742        long ident = Binder.clearCallingIdentity();
8743
8744        synchronized(this) {
8745            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8746            try {
8747                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8748
8749                final int N = mRecentTasks.size();
8750                for (int i = 0; i < N; i++) {
8751                    TaskRecord tr = mRecentTasks.get(i);
8752                    // Skip tasks that do not match the caller.  We don't need to verify
8753                    // callingPackage, because we are also limiting to callingUid and know
8754                    // that will limit to the correct security sandbox.
8755                    if (tr.effectiveUid != callingUid) {
8756                        continue;
8757                    }
8758                    Intent intent = tr.getBaseIntent();
8759                    if (intent == null ||
8760                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8761                        continue;
8762                    }
8763                    ActivityManager.RecentTaskInfo taskInfo =
8764                            createRecentTaskInfoFromTaskRecord(tr);
8765                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8766                    list.add(taskImpl);
8767                }
8768            } finally {
8769                Binder.restoreCallingIdentity(ident);
8770            }
8771            return list;
8772        }
8773    }
8774
8775    @Override
8776    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8777        final int callingUid = Binder.getCallingUid();
8778        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8779
8780        synchronized(this) {
8781            if (DEBUG_ALL) Slog.v(
8782                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8783
8784            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8785                    callingUid);
8786
8787            // TODO: Improve with MRU list from all ActivityStacks.
8788            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8789        }
8790
8791        return list;
8792    }
8793
8794    /**
8795     * Creates a new RecentTaskInfo from a TaskRecord.
8796     */
8797    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8798        // Update the task description to reflect any changes in the task stack
8799        tr.updateTaskDescription();
8800
8801        // Compose the recent task info
8802        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8803        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8804        rti.persistentId = tr.taskId;
8805        rti.baseIntent = new Intent(tr.getBaseIntent());
8806        rti.origActivity = tr.origActivity;
8807        rti.realActivity = tr.realActivity;
8808        rti.description = tr.lastDescription;
8809        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8810        rti.userId = tr.userId;
8811        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8812        rti.firstActiveTime = tr.firstActiveTime;
8813        rti.lastActiveTime = tr.lastActiveTime;
8814        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8815        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8816        rti.numActivities = 0;
8817        if (tr.mBounds != null) {
8818            rti.bounds = new Rect(tr.mBounds);
8819        }
8820        rti.isDockable = tr.canGoInDockedStack();
8821        rti.resizeMode = tr.mResizeMode;
8822
8823        ActivityRecord base = null;
8824        ActivityRecord top = null;
8825        ActivityRecord tmp;
8826
8827        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8828            tmp = tr.mActivities.get(i);
8829            if (tmp.finishing) {
8830                continue;
8831            }
8832            base = tmp;
8833            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8834                top = base;
8835            }
8836            rti.numActivities++;
8837        }
8838
8839        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8840        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8841
8842        return rti;
8843    }
8844
8845    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8846        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8847                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8848        if (!allowed) {
8849            if (checkPermission(android.Manifest.permission.GET_TASKS,
8850                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8851                // Temporary compatibility: some existing apps on the system image may
8852                // still be requesting the old permission and not switched to the new
8853                // one; if so, we'll still allow them full access.  This means we need
8854                // to see if they are holding the old permission and are a system app.
8855                try {
8856                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8857                        allowed = true;
8858                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8859                                + " is using old GET_TASKS but privileged; allowing");
8860                    }
8861                } catch (RemoteException e) {
8862                }
8863            }
8864        }
8865        if (!allowed) {
8866            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8867                    + " does not hold REAL_GET_TASKS; limiting output");
8868        }
8869        return allowed;
8870    }
8871
8872    @Override
8873    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8874        final int callingUid = Binder.getCallingUid();
8875        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8876                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8877
8878        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8879        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8880        synchronized (this) {
8881            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8882                    callingUid);
8883            final boolean detailed = checkCallingPermission(
8884                    android.Manifest.permission.GET_DETAILED_TASKS)
8885                    == PackageManager.PERMISSION_GRANTED;
8886
8887            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8888                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8889                return Collections.emptyList();
8890            }
8891            mRecentTasks.loadUserRecentsLocked(userId);
8892
8893            final int recentsCount = mRecentTasks.size();
8894            ArrayList<ActivityManager.RecentTaskInfo> res =
8895                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8896
8897            final Set<Integer> includedUsers;
8898            if (includeProfiles) {
8899                includedUsers = mUserController.getProfileIds(userId);
8900            } else {
8901                includedUsers = new HashSet<>();
8902            }
8903            includedUsers.add(Integer.valueOf(userId));
8904
8905            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8906                TaskRecord tr = mRecentTasks.get(i);
8907                // Only add calling user or related users recent tasks
8908                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8909                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8910                    continue;
8911                }
8912
8913                if (tr.realActivitySuspended) {
8914                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8915                    continue;
8916                }
8917
8918                // Return the entry if desired by the caller.  We always return
8919                // the first entry, because callers always expect this to be the
8920                // foreground app.  We may filter others if the caller has
8921                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8922                // we should exclude the entry.
8923
8924                if (i == 0
8925                        || withExcluded
8926                        || (tr.intent == null)
8927                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8928                                == 0)) {
8929                    if (!allowed) {
8930                        // If the caller doesn't have the GET_TASKS permission, then only
8931                        // allow them to see a small subset of tasks -- their own and home.
8932                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8933                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8934                            continue;
8935                        }
8936                    }
8937                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8938                        if (tr.stack != null && tr.stack.isHomeStack()) {
8939                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8940                                    "Skipping, home stack task: " + tr);
8941                            continue;
8942                        }
8943                    }
8944                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8945                        final ActivityStack stack = tr.stack;
8946                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8947                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8948                                    "Skipping, top task in docked stack: " + tr);
8949                            continue;
8950                        }
8951                    }
8952                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8953                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8954                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8955                                    "Skipping, pinned stack task: " + tr);
8956                            continue;
8957                        }
8958                    }
8959                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8960                        // Don't include auto remove tasks that are finished or finishing.
8961                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8962                                "Skipping, auto-remove without activity: " + tr);
8963                        continue;
8964                    }
8965                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8966                            && !tr.isAvailable) {
8967                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8968                                "Skipping, unavail real act: " + tr);
8969                        continue;
8970                    }
8971
8972                    if (!tr.mUserSetupComplete) {
8973                        // Don't include task launched while user is not done setting-up.
8974                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8975                                "Skipping, user setup not complete: " + tr);
8976                        continue;
8977                    }
8978
8979                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8980                    if (!detailed) {
8981                        rti.baseIntent.replaceExtras((Bundle)null);
8982                    }
8983
8984                    res.add(rti);
8985                    maxNum--;
8986                }
8987            }
8988            return res;
8989        }
8990    }
8991
8992    @Override
8993    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8994        synchronized (this) {
8995            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8996                    "getTaskThumbnail()");
8997            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8998                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8999            if (tr != null) {
9000                return tr.getTaskThumbnailLocked();
9001            }
9002        }
9003        return null;
9004    }
9005
9006    @Override
9007    public int addAppTask(IBinder activityToken, Intent intent,
9008            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9009        final int callingUid = Binder.getCallingUid();
9010        final long callingIdent = Binder.clearCallingIdentity();
9011
9012        try {
9013            synchronized (this) {
9014                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9015                if (r == null) {
9016                    throw new IllegalArgumentException("Activity does not exist; token="
9017                            + activityToken);
9018                }
9019                ComponentName comp = intent.getComponent();
9020                if (comp == null) {
9021                    throw new IllegalArgumentException("Intent " + intent
9022                            + " must specify explicit component");
9023                }
9024                if (thumbnail.getWidth() != mThumbnailWidth
9025                        || thumbnail.getHeight() != mThumbnailHeight) {
9026                    throw new IllegalArgumentException("Bad thumbnail size: got "
9027                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9028                            + mThumbnailWidth + "x" + mThumbnailHeight);
9029                }
9030                if (intent.getSelector() != null) {
9031                    intent.setSelector(null);
9032                }
9033                if (intent.getSourceBounds() != null) {
9034                    intent.setSourceBounds(null);
9035                }
9036                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9037                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9038                        // The caller has added this as an auto-remove task...  that makes no
9039                        // sense, so turn off auto-remove.
9040                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9041                    }
9042                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9043                    // Must be a new task.
9044                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9045                }
9046                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9047                    mLastAddedTaskActivity = null;
9048                }
9049                ActivityInfo ainfo = mLastAddedTaskActivity;
9050                if (ainfo == null) {
9051                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9052                            comp, 0, UserHandle.getUserId(callingUid));
9053                    if (ainfo.applicationInfo.uid != callingUid) {
9054                        throw new SecurityException(
9055                                "Can't add task for another application: target uid="
9056                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9057                    }
9058                }
9059
9060                // Use the full screen as the context for the task thumbnail
9061                final Point displaySize = new Point();
9062                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9063                r.task.stack.getDisplaySize(displaySize);
9064                thumbnailInfo.taskWidth = displaySize.x;
9065                thumbnailInfo.taskHeight = displaySize.y;
9066                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9067
9068                TaskRecord task = new TaskRecord(this,
9069                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9070                        ainfo, intent, description, thumbnailInfo);
9071
9072                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9073                if (trimIdx >= 0) {
9074                    // If this would have caused a trim, then we'll abort because that
9075                    // means it would be added at the end of the list but then just removed.
9076                    return INVALID_TASK_ID;
9077                }
9078
9079                final int N = mRecentTasks.size();
9080                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9081                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9082                    tr.removedFromRecents();
9083                }
9084
9085                task.inRecents = true;
9086                mRecentTasks.add(task);
9087                r.task.stack.addTask(task, false, "addAppTask");
9088
9089                task.setLastThumbnailLocked(thumbnail);
9090                task.freeLastThumbnail();
9091
9092                return task.taskId;
9093            }
9094        } finally {
9095            Binder.restoreCallingIdentity(callingIdent);
9096        }
9097    }
9098
9099    @Override
9100    public Point getAppTaskThumbnailSize() {
9101        synchronized (this) {
9102            return new Point(mThumbnailWidth,  mThumbnailHeight);
9103        }
9104    }
9105
9106    @Override
9107    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9108        synchronized (this) {
9109            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9110            if (r != null) {
9111                r.setTaskDescription(td);
9112                r.task.updateTaskDescription();
9113            }
9114        }
9115    }
9116
9117    @Override
9118    public void setTaskResizeable(int taskId, int resizeableMode) {
9119        synchronized (this) {
9120            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9121                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9122            if (task == null) {
9123                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9124                return;
9125            }
9126            if (task.mResizeMode != resizeableMode) {
9127                task.mResizeMode = resizeableMode;
9128                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9129                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9130                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9131            }
9132        }
9133    }
9134
9135    @Override
9136    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9137        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9138        long ident = Binder.clearCallingIdentity();
9139        try {
9140            synchronized (this) {
9141                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9142                if (task == null) {
9143                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9144                    return;
9145                }
9146                int stackId = task.stack.mStackId;
9147                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9148                // in crop windows resize mode or if the task size is affected by the docked stack
9149                // changing size. No need to update configuration.
9150                if (bounds != null && task.inCropWindowsResizeMode()
9151                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9152                    mWindowManager.scrollTask(task.taskId, bounds);
9153                    return;
9154                }
9155
9156                // Place the task in the right stack if it isn't there already based on
9157                // the requested bounds.
9158                // The stack transition logic is:
9159                // - a null bounds on a freeform task moves that task to fullscreen
9160                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9161                //   that task to freeform
9162                // - otherwise the task is not moved
9163                if (!StackId.isTaskResizeAllowed(stackId)) {
9164                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9165                }
9166                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9167                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9168                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9169                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9170                }
9171                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9172                if (stackId != task.stack.mStackId) {
9173                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9174                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9175                    preserveWindow = false;
9176                }
9177
9178                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9179                        false /* deferResume */);
9180            }
9181        } finally {
9182            Binder.restoreCallingIdentity(ident);
9183        }
9184    }
9185
9186    @Override
9187    public Rect getTaskBounds(int taskId) {
9188        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9189        long ident = Binder.clearCallingIdentity();
9190        Rect rect = new Rect();
9191        try {
9192            synchronized (this) {
9193                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9194                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9195                if (task == null) {
9196                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9197                    return rect;
9198                }
9199                if (task.stack != null) {
9200                    // Return the bounds from window manager since it will be adjusted for various
9201                    // things like the presense of a docked stack for tasks that aren't resizeable.
9202                    mWindowManager.getTaskBounds(task.taskId, rect);
9203                } else {
9204                    // Task isn't in window manager yet since it isn't associated with a stack.
9205                    // Return the persist value from activity manager
9206                    if (task.mBounds != null) {
9207                        rect.set(task.mBounds);
9208                    } else if (task.mLastNonFullscreenBounds != null) {
9209                        rect.set(task.mLastNonFullscreenBounds);
9210                    }
9211                }
9212            }
9213        } finally {
9214            Binder.restoreCallingIdentity(ident);
9215        }
9216        return rect;
9217    }
9218
9219    @Override
9220    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9221        if (userId != UserHandle.getCallingUserId()) {
9222            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9223                    "getTaskDescriptionIcon");
9224        }
9225        final File passedIconFile = new File(filePath);
9226        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9227                passedIconFile.getName());
9228        if (!legitIconFile.getPath().equals(filePath)
9229                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9230            throw new IllegalArgumentException("Bad file path: " + filePath
9231                    + " passed for userId " + userId);
9232        }
9233        return mRecentTasks.getTaskDescriptionIcon(filePath);
9234    }
9235
9236    @Override
9237    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9238            throws RemoteException {
9239        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9240                opts.getCustomInPlaceResId() == 0) {
9241            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9242                    "with valid animation");
9243        }
9244        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9245        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9246                opts.getCustomInPlaceResId());
9247        mWindowManager.executeAppTransition();
9248    }
9249
9250    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9251            boolean removeFromRecents) {
9252        if (removeFromRecents) {
9253            mRecentTasks.remove(tr);
9254            tr.removedFromRecents();
9255        }
9256        ComponentName component = tr.getBaseIntent().getComponent();
9257        if (component == null) {
9258            Slog.w(TAG, "No component for base intent of task: " + tr);
9259            return;
9260        }
9261
9262        // Find any running services associated with this app and stop if needed.
9263        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9264
9265        if (!killProcess) {
9266            return;
9267        }
9268
9269        // Determine if the process(es) for this task should be killed.
9270        final String pkg = component.getPackageName();
9271        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9272        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9273        for (int i = 0; i < pmap.size(); i++) {
9274
9275            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9276            for (int j = 0; j < uids.size(); j++) {
9277                ProcessRecord proc = uids.valueAt(j);
9278                if (proc.userId != tr.userId) {
9279                    // Don't kill process for a different user.
9280                    continue;
9281                }
9282                if (proc == mHomeProcess) {
9283                    // Don't kill the home process along with tasks from the same package.
9284                    continue;
9285                }
9286                if (!proc.pkgList.containsKey(pkg)) {
9287                    // Don't kill process that is not associated with this task.
9288                    continue;
9289                }
9290
9291                for (int k = 0; k < proc.activities.size(); k++) {
9292                    TaskRecord otherTask = proc.activities.get(k).task;
9293                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9294                        // Don't kill process(es) that has an activity in a different task that is
9295                        // also in recents.
9296                        return;
9297                    }
9298                }
9299
9300                if (proc.foregroundServices) {
9301                    // Don't kill process(es) with foreground service.
9302                    return;
9303                }
9304
9305                // Add process to kill list.
9306                procsToKill.add(proc);
9307            }
9308        }
9309
9310        // Kill the running processes.
9311        for (int i = 0; i < procsToKill.size(); i++) {
9312            ProcessRecord pr = procsToKill.get(i);
9313            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9314                    && pr.curReceiver == null) {
9315                pr.kill("remove task", true);
9316            } else {
9317                // We delay killing processes that are not in the background or running a receiver.
9318                pr.waitingToKill = "remove task";
9319            }
9320        }
9321    }
9322
9323    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9324        // Remove all tasks with activities in the specified package from the list of recent tasks
9325        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9326            TaskRecord tr = mRecentTasks.get(i);
9327            if (tr.userId != userId) continue;
9328
9329            ComponentName cn = tr.intent.getComponent();
9330            if (cn != null && cn.getPackageName().equals(packageName)) {
9331                // If the package name matches, remove the task.
9332                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9333            }
9334        }
9335    }
9336
9337    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9338            int userId) {
9339
9340        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9341            TaskRecord tr = mRecentTasks.get(i);
9342            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9343                continue;
9344            }
9345
9346            ComponentName cn = tr.intent.getComponent();
9347            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9348                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9349            if (sameComponent) {
9350                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9351            }
9352        }
9353    }
9354
9355    /**
9356     * Removes the task with the specified task id.
9357     *
9358     * @param taskId Identifier of the task to be removed.
9359     * @param killProcess Kill any process associated with the task if possible.
9360     * @param removeFromRecents Whether to also remove the task from recents.
9361     * @return Returns true if the given task was found and removed.
9362     */
9363    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9364            boolean removeFromRecents) {
9365        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9366                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9367        if (tr != null) {
9368            tr.removeTaskActivitiesLocked();
9369            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9370            if (tr.isPersistable) {
9371                notifyTaskPersisterLocked(null, true);
9372            }
9373            return true;
9374        }
9375        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9376        return false;
9377    }
9378
9379    @Override
9380    public void removeStack(int stackId) {
9381        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9382        if (stackId == HOME_STACK_ID) {
9383            throw new IllegalArgumentException("Removing home stack is not allowed.");
9384        }
9385
9386        synchronized (this) {
9387            final long ident = Binder.clearCallingIdentity();
9388            try {
9389                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9390                if (stack == null) {
9391                    return;
9392                }
9393                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9394                for (int i = tasks.size() - 1; i >= 0; i--) {
9395                    removeTaskByIdLocked(
9396                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9397                }
9398            } finally {
9399                Binder.restoreCallingIdentity(ident);
9400            }
9401        }
9402    }
9403
9404    @Override
9405    public boolean removeTask(int taskId) {
9406        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9407        synchronized (this) {
9408            final long ident = Binder.clearCallingIdentity();
9409            try {
9410                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9411            } finally {
9412                Binder.restoreCallingIdentity(ident);
9413            }
9414        }
9415    }
9416
9417    /**
9418     * TODO: Add mController hook
9419     */
9420    @Override
9421    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9422        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9423
9424        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9425        synchronized(this) {
9426            moveTaskToFrontLocked(taskId, flags, bOptions);
9427        }
9428    }
9429
9430    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9431        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9432
9433        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9434                Binder.getCallingUid(), -1, -1, "Task to front")) {
9435            ActivityOptions.abort(options);
9436            return;
9437        }
9438        final long origId = Binder.clearCallingIdentity();
9439        try {
9440            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9441            if (task == null) {
9442                Slog.d(TAG, "Could not find task for id: "+ taskId);
9443                return;
9444            }
9445            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9446                mStackSupervisor.showLockTaskToast();
9447                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9448                return;
9449            }
9450            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9451            if (prev != null && prev.isRecentsActivity()) {
9452                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9453            }
9454            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9455                    false /* forceNonResizable */);
9456        } finally {
9457            Binder.restoreCallingIdentity(origId);
9458        }
9459        ActivityOptions.abort(options);
9460    }
9461
9462    /**
9463     * Moves an activity, and all of the other activities within the same task, to the bottom
9464     * of the history stack.  The activity's order within the task is unchanged.
9465     *
9466     * @param token A reference to the activity we wish to move
9467     * @param nonRoot If false then this only works if the activity is the root
9468     *                of a task; if true it will work for any activity in a task.
9469     * @return Returns true if the move completed, false if not.
9470     */
9471    @Override
9472    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9473        enforceNotIsolatedCaller("moveActivityTaskToBack");
9474        synchronized(this) {
9475            final long origId = Binder.clearCallingIdentity();
9476            try {
9477                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9478                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9479                if (task != null) {
9480                    if (mStackSupervisor.isLockedTask(task)) {
9481                        mStackSupervisor.showLockTaskToast();
9482                        return false;
9483                    }
9484                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9485                }
9486            } finally {
9487                Binder.restoreCallingIdentity(origId);
9488            }
9489        }
9490        return false;
9491    }
9492
9493    @Override
9494    public void moveTaskBackwards(int task) {
9495        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9496                "moveTaskBackwards()");
9497
9498        synchronized(this) {
9499            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9500                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9501                return;
9502            }
9503            final long origId = Binder.clearCallingIdentity();
9504            moveTaskBackwardsLocked(task);
9505            Binder.restoreCallingIdentity(origId);
9506        }
9507    }
9508
9509    private final void moveTaskBackwardsLocked(int task) {
9510        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9511    }
9512
9513    @Override
9514    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9515            IActivityContainerCallback callback) throws RemoteException {
9516        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9517        synchronized (this) {
9518            if (parentActivityToken == null) {
9519                throw new IllegalArgumentException("parent token must not be null");
9520            }
9521            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9522            if (r == null) {
9523                return null;
9524            }
9525            if (callback == null) {
9526                throw new IllegalArgumentException("callback must not be null");
9527            }
9528            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9529        }
9530    }
9531
9532    @Override
9533    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9534        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9535        synchronized (this) {
9536            mStackSupervisor.deleteActivityContainer(container);
9537        }
9538    }
9539
9540    @Override
9541    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9542        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9543        synchronized (this) {
9544            final int stackId = mStackSupervisor.getNextStackId();
9545            final ActivityStack stack =
9546                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9547            if (stack == null) {
9548                return null;
9549            }
9550            return stack.mActivityContainer;
9551        }
9552    }
9553
9554    @Override
9555    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9556        synchronized (this) {
9557            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9558            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9559                return stack.mActivityContainer.getDisplayId();
9560            }
9561            return Display.DEFAULT_DISPLAY;
9562        }
9563    }
9564
9565    @Override
9566    public int getActivityStackId(IBinder token) throws RemoteException {
9567        synchronized (this) {
9568            ActivityStack stack = ActivityRecord.getStackLocked(token);
9569            if (stack == null) {
9570                return INVALID_STACK_ID;
9571            }
9572            return stack.mStackId;
9573        }
9574    }
9575
9576    @Override
9577    public void exitFreeformMode(IBinder token) throws RemoteException {
9578        synchronized (this) {
9579            long ident = Binder.clearCallingIdentity();
9580            try {
9581                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9582                if (r == null) {
9583                    throw new IllegalArgumentException(
9584                            "exitFreeformMode: No activity record matching token=" + token);
9585                }
9586                final ActivityStack stack = r.getStackLocked(token);
9587                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9588                    throw new IllegalStateException(
9589                            "exitFreeformMode: You can only go fullscreen from freeform.");
9590                }
9591                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9592                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9593                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9594            } finally {
9595                Binder.restoreCallingIdentity(ident);
9596            }
9597        }
9598    }
9599
9600    @Override
9601    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9602        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9603        if (stackId == HOME_STACK_ID) {
9604            throw new IllegalArgumentException(
9605                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9606        }
9607        synchronized (this) {
9608            long ident = Binder.clearCallingIdentity();
9609            try {
9610                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9611                        + " to stackId=" + stackId + " toTop=" + toTop);
9612                if (stackId == DOCKED_STACK_ID) {
9613                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9614                            null /* initialBounds */);
9615                }
9616                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9617                        "moveTaskToStack", ANIMATE);
9618            } finally {
9619                Binder.restoreCallingIdentity(ident);
9620            }
9621        }
9622    }
9623
9624    @Override
9625    public void swapDockedAndFullscreenStack() throws RemoteException {
9626        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9627        synchronized (this) {
9628            long ident = Binder.clearCallingIdentity();
9629            try {
9630                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9631                        FULLSCREEN_WORKSPACE_STACK_ID);
9632                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9633                        : null;
9634                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9635                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9636                        : null;
9637                if (topTask == null || tasks == null || tasks.size() == 0) {
9638                    Slog.w(TAG,
9639                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9640                    return;
9641                }
9642
9643                // TODO: App transition
9644                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9645
9646                // Defer the resume so resume/pausing while moving stacks is dangerous.
9647                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9648                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9649                        ANIMATE, true /* deferResume */);
9650                final int size = tasks.size();
9651                for (int i = 0; i < size; i++) {
9652                    final int id = tasks.get(i).taskId;
9653                    if (id == topTask.taskId) {
9654                        continue;
9655                    }
9656                    mStackSupervisor.moveTaskToStackLocked(id,
9657                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9658                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9659                }
9660
9661                // Because we deferred the resume, to avoid conflicts with stack switches while
9662                // resuming, we need to do it after all the tasks are moved.
9663                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9664                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9665
9666                mWindowManager.executeAppTransition();
9667            } finally {
9668                Binder.restoreCallingIdentity(ident);
9669            }
9670        }
9671    }
9672
9673    /**
9674     * Moves the input task to the docked stack.
9675     *
9676     * @param taskId Id of task to move.
9677     * @param createMode The mode the docked stack should be created in if it doesn't exist
9678     *                   already. See
9679     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9680     *                   and
9681     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9682     * @param toTop If the task and stack should be moved to the top.
9683     * @param animate Whether we should play an animation for the moving the task
9684     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9685     *                      docked stack. Pass {@code null} to use default bounds.
9686     */
9687    @Override
9688    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9689            Rect initialBounds) {
9690        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9691        synchronized (this) {
9692            long ident = Binder.clearCallingIdentity();
9693            try {
9694                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9695                        + " to createMode=" + createMode + " toTop=" + toTop);
9696                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9697                return mStackSupervisor.moveTaskToStackLocked(
9698                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9699                        "moveTaskToDockedStack", animate);
9700            } finally {
9701                Binder.restoreCallingIdentity(ident);
9702            }
9703        }
9704    }
9705
9706    /**
9707     * Moves the top activity in the input stackId to the pinned stack.
9708     *
9709     * @param stackId Id of stack to move the top activity to pinned stack.
9710     * @param bounds Bounds to use for pinned stack.
9711     *
9712     * @return True if the top activity of the input stack was successfully moved to the pinned
9713     *          stack.
9714     */
9715    @Override
9716    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9717        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9718        synchronized (this) {
9719            if (!mSupportsPictureInPicture) {
9720                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9721                        + "Device doesn't support picture-in-pciture mode");
9722            }
9723
9724            long ident = Binder.clearCallingIdentity();
9725            try {
9726                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9727            } finally {
9728                Binder.restoreCallingIdentity(ident);
9729            }
9730        }
9731    }
9732
9733    @Override
9734    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9735            boolean preserveWindows, boolean animate, int animationDuration) {
9736        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9737        long ident = Binder.clearCallingIdentity();
9738        try {
9739            synchronized (this) {
9740                if (animate) {
9741                    if (stackId == PINNED_STACK_ID) {
9742                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9743                    } else {
9744                        throw new IllegalArgumentException("Stack: " + stackId
9745                                + " doesn't support animated resize.");
9746                    }
9747                } else {
9748                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9749                            null /* tempTaskInsetBounds */, preserveWindows,
9750                            allowResizeInDockedMode, !DEFER_RESUME);
9751                }
9752            }
9753        } finally {
9754            Binder.restoreCallingIdentity(ident);
9755        }
9756    }
9757
9758    @Override
9759    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9760            Rect tempDockedTaskInsetBounds,
9761            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9762        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9763                "resizeDockedStack()");
9764        long ident = Binder.clearCallingIdentity();
9765        try {
9766            synchronized (this) {
9767                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9768                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9769                        PRESERVE_WINDOWS);
9770            }
9771        } finally {
9772            Binder.restoreCallingIdentity(ident);
9773        }
9774    }
9775
9776    @Override
9777    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9778        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9779                "resizePinnedStack()");
9780        final long ident = Binder.clearCallingIdentity();
9781        try {
9782            synchronized (this) {
9783                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9784            }
9785        } finally {
9786            Binder.restoreCallingIdentity(ident);
9787        }
9788    }
9789
9790    @Override
9791    public void positionTaskInStack(int taskId, int stackId, int position) {
9792        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9793        if (stackId == HOME_STACK_ID) {
9794            throw new IllegalArgumentException(
9795                    "positionTaskInStack: Attempt to change the position of task "
9796                    + taskId + " in/to home stack");
9797        }
9798        synchronized (this) {
9799            long ident = Binder.clearCallingIdentity();
9800            try {
9801                if (DEBUG_STACK) Slog.d(TAG_STACK,
9802                        "positionTaskInStack: positioning task=" + taskId
9803                        + " in stackId=" + stackId + " at position=" + position);
9804                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9805            } finally {
9806                Binder.restoreCallingIdentity(ident);
9807            }
9808        }
9809    }
9810
9811    @Override
9812    public List<StackInfo> getAllStackInfos() {
9813        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9814        long ident = Binder.clearCallingIdentity();
9815        try {
9816            synchronized (this) {
9817                return mStackSupervisor.getAllStackInfosLocked();
9818            }
9819        } finally {
9820            Binder.restoreCallingIdentity(ident);
9821        }
9822    }
9823
9824    @Override
9825    public StackInfo getStackInfo(int stackId) {
9826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9827        long ident = Binder.clearCallingIdentity();
9828        try {
9829            synchronized (this) {
9830                return mStackSupervisor.getStackInfoLocked(stackId);
9831            }
9832        } finally {
9833            Binder.restoreCallingIdentity(ident);
9834        }
9835    }
9836
9837    @Override
9838    public boolean isInHomeStack(int taskId) {
9839        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9840        long ident = Binder.clearCallingIdentity();
9841        try {
9842            synchronized (this) {
9843                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9844                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9845                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9846            }
9847        } finally {
9848            Binder.restoreCallingIdentity(ident);
9849        }
9850    }
9851
9852    @Override
9853    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9854        synchronized(this) {
9855            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9856        }
9857    }
9858
9859    @Override
9860    public void updateDeviceOwner(String packageName) {
9861        final int callingUid = Binder.getCallingUid();
9862        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9863            throw new SecurityException("updateDeviceOwner called from non-system process");
9864        }
9865        synchronized (this) {
9866            mDeviceOwnerName = packageName;
9867        }
9868    }
9869
9870    @Override
9871    public void updateLockTaskPackages(int userId, String[] packages) {
9872        final int callingUid = Binder.getCallingUid();
9873        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9874            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9875                    "updateLockTaskPackages()");
9876        }
9877        synchronized (this) {
9878            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9879                    Arrays.toString(packages));
9880            mLockTaskPackages.put(userId, packages);
9881            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9882        }
9883    }
9884
9885
9886    void startLockTaskModeLocked(TaskRecord task) {
9887        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9888        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9889            return;
9890        }
9891
9892        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9893        // is initiated by system after the pinning request was shown and locked mode is initiated
9894        // by an authorized app directly
9895        final int callingUid = Binder.getCallingUid();
9896        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9897        long ident = Binder.clearCallingIdentity();
9898        try {
9899            if (!isSystemInitiated) {
9900                task.mLockTaskUid = callingUid;
9901                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9902                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9903                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9904                    StatusBarManagerInternal statusBarManager =
9905                            LocalServices.getService(StatusBarManagerInternal.class);
9906                    if (statusBarManager != null) {
9907                        statusBarManager.showScreenPinningRequest(task.taskId);
9908                    }
9909                    return;
9910                }
9911
9912                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9913                if (stack == null || task != stack.topTask()) {
9914                    throw new IllegalArgumentException("Invalid task, not in foreground");
9915                }
9916            }
9917            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9918                    "Locking fully");
9919            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9920                    ActivityManager.LOCK_TASK_MODE_PINNED :
9921                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9922                    "startLockTask", true);
9923        } finally {
9924            Binder.restoreCallingIdentity(ident);
9925        }
9926    }
9927
9928    @Override
9929    public void startLockTaskMode(int taskId) {
9930        synchronized (this) {
9931            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9932            if (task != null) {
9933                startLockTaskModeLocked(task);
9934            }
9935        }
9936    }
9937
9938    @Override
9939    public void startLockTaskMode(IBinder token) {
9940        synchronized (this) {
9941            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9942            if (r == null) {
9943                return;
9944            }
9945            final TaskRecord task = r.task;
9946            if (task != null) {
9947                startLockTaskModeLocked(task);
9948            }
9949        }
9950    }
9951
9952    @Override
9953    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9954        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9955        // This makes inner call to look as if it was initiated by system.
9956        long ident = Binder.clearCallingIdentity();
9957        try {
9958            synchronized (this) {
9959                startLockTaskMode(taskId);
9960            }
9961        } finally {
9962            Binder.restoreCallingIdentity(ident);
9963        }
9964    }
9965
9966    @Override
9967    public void stopLockTaskMode() {
9968        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9969        if (lockTask == null) {
9970            // Our work here is done.
9971            return;
9972        }
9973
9974        final int callingUid = Binder.getCallingUid();
9975        final int lockTaskUid = lockTask.mLockTaskUid;
9976        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9977        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9978            // Done.
9979            return;
9980        } else {
9981            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9982            // It is possible lockTaskMode was started by the system process because
9983            // android:lockTaskMode is set to a locking value in the application manifest
9984            // instead of the app calling startLockTaskMode. In this case
9985            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9986            // {@link TaskRecord.effectiveUid} instead. Also caller with
9987            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9988            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9989                    && callingUid != lockTaskUid
9990                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9991                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9992                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9993            }
9994        }
9995        long ident = Binder.clearCallingIdentity();
9996        try {
9997            Log.d(TAG, "stopLockTaskMode");
9998            // Stop lock task
9999            synchronized (this) {
10000                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10001                        "stopLockTask", true);
10002            }
10003        } finally {
10004            Binder.restoreCallingIdentity(ident);
10005        }
10006    }
10007
10008    /**
10009     * This API should be called by SystemUI only when user perform certain action to dismiss
10010     * lock task mode. We should only dismiss pinned lock task mode in this case.
10011     */
10012    @Override
10013    public void stopSystemLockTaskMode() throws RemoteException {
10014        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10015            stopLockTaskMode();
10016        } else {
10017            mStackSupervisor.showLockTaskToast();
10018        }
10019    }
10020
10021    @Override
10022    public boolean isInLockTaskMode() {
10023        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10024    }
10025
10026    @Override
10027    public int getLockTaskModeState() {
10028        synchronized (this) {
10029            return mStackSupervisor.getLockTaskModeState();
10030        }
10031    }
10032
10033    @Override
10034    public void showLockTaskEscapeMessage(IBinder token) {
10035        synchronized (this) {
10036            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10037            if (r == null) {
10038                return;
10039            }
10040            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10041        }
10042    }
10043
10044    // =========================================================
10045    // CONTENT PROVIDERS
10046    // =========================================================
10047
10048    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10049        List<ProviderInfo> providers = null;
10050        try {
10051            providers = AppGlobals.getPackageManager()
10052                    .queryContentProviders(app.processName, app.uid,
10053                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10054                                    | MATCH_DEBUG_TRIAGED_MISSING)
10055                    .getList();
10056        } catch (RemoteException ex) {
10057        }
10058        if (DEBUG_MU) Slog.v(TAG_MU,
10059                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10060        int userId = app.userId;
10061        if (providers != null) {
10062            int N = providers.size();
10063            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10064            for (int i=0; i<N; i++) {
10065                ProviderInfo cpi =
10066                    (ProviderInfo)providers.get(i);
10067                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10068                        cpi.name, cpi.flags);
10069                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10070                    // This is a singleton provider, but a user besides the
10071                    // default user is asking to initialize a process it runs
10072                    // in...  well, no, it doesn't actually run in this process,
10073                    // it runs in the process of the default user.  Get rid of it.
10074                    providers.remove(i);
10075                    N--;
10076                    i--;
10077                    continue;
10078                }
10079
10080                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10081                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10082                if (cpr == null) {
10083                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10084                    mProviderMap.putProviderByClass(comp, cpr);
10085                }
10086                if (DEBUG_MU) Slog.v(TAG_MU,
10087                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10088                app.pubProviders.put(cpi.name, cpr);
10089                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10090                    // Don't add this if it is a platform component that is marked
10091                    // to run in multiple processes, because this is actually
10092                    // part of the framework so doesn't make sense to track as a
10093                    // separate apk in the process.
10094                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10095                            mProcessStats);
10096                }
10097                notifyPackageUse(cpi.applicationInfo.packageName);
10098            }
10099        }
10100        return providers;
10101    }
10102
10103    /**
10104     * Check if {@link ProcessRecord} has a possible chance at accessing the
10105     * given {@link ProviderInfo}. Final permission checking is always done
10106     * in {@link ContentProvider}.
10107     */
10108    private final String checkContentProviderPermissionLocked(
10109            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10110        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10111        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10112        boolean checkedGrants = false;
10113        if (checkUser) {
10114            // Looking for cross-user grants before enforcing the typical cross-users permissions
10115            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10116            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10117                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10118                    return null;
10119                }
10120                checkedGrants = true;
10121            }
10122            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10123                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10124            if (userId != tmpTargetUserId) {
10125                // When we actually went to determine the final targer user ID, this ended
10126                // up different than our initial check for the authority.  This is because
10127                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10128                // SELF.  So we need to re-check the grants again.
10129                checkedGrants = false;
10130            }
10131        }
10132        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10133                cpi.applicationInfo.uid, cpi.exported)
10134                == PackageManager.PERMISSION_GRANTED) {
10135            return null;
10136        }
10137        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10138                cpi.applicationInfo.uid, cpi.exported)
10139                == PackageManager.PERMISSION_GRANTED) {
10140            return null;
10141        }
10142
10143        PathPermission[] pps = cpi.pathPermissions;
10144        if (pps != null) {
10145            int i = pps.length;
10146            while (i > 0) {
10147                i--;
10148                PathPermission pp = pps[i];
10149                String pprperm = pp.getReadPermission();
10150                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10151                        cpi.applicationInfo.uid, cpi.exported)
10152                        == PackageManager.PERMISSION_GRANTED) {
10153                    return null;
10154                }
10155                String ppwperm = pp.getWritePermission();
10156                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10157                        cpi.applicationInfo.uid, cpi.exported)
10158                        == PackageManager.PERMISSION_GRANTED) {
10159                    return null;
10160                }
10161            }
10162        }
10163        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10164            return null;
10165        }
10166
10167        String msg;
10168        if (!cpi.exported) {
10169            msg = "Permission Denial: opening provider " + cpi.name
10170                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10171                    + ", uid=" + callingUid + ") that is not exported from uid "
10172                    + cpi.applicationInfo.uid;
10173        } else {
10174            msg = "Permission Denial: opening provider " + cpi.name
10175                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10176                    + ", uid=" + callingUid + ") requires "
10177                    + cpi.readPermission + " or " + cpi.writePermission;
10178        }
10179        Slog.w(TAG, msg);
10180        return msg;
10181    }
10182
10183    /**
10184     * Returns if the ContentProvider has granted a uri to callingUid
10185     */
10186    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10187        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10188        if (perms != null) {
10189            for (int i=perms.size()-1; i>=0; i--) {
10190                GrantUri grantUri = perms.keyAt(i);
10191                if (grantUri.sourceUserId == userId || !checkUser) {
10192                    if (matchesProvider(grantUri.uri, cpi)) {
10193                        return true;
10194                    }
10195                }
10196            }
10197        }
10198        return false;
10199    }
10200
10201    /**
10202     * Returns true if the uri authority is one of the authorities specified in the provider.
10203     */
10204    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10205        String uriAuth = uri.getAuthority();
10206        String cpiAuth = cpi.authority;
10207        if (cpiAuth.indexOf(';') == -1) {
10208            return cpiAuth.equals(uriAuth);
10209        }
10210        String[] cpiAuths = cpiAuth.split(";");
10211        int length = cpiAuths.length;
10212        for (int i = 0; i < length; i++) {
10213            if (cpiAuths[i].equals(uriAuth)) return true;
10214        }
10215        return false;
10216    }
10217
10218    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10219            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10220        if (r != null) {
10221            for (int i=0; i<r.conProviders.size(); i++) {
10222                ContentProviderConnection conn = r.conProviders.get(i);
10223                if (conn.provider == cpr) {
10224                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10225                            "Adding provider requested by "
10226                            + r.processName + " from process "
10227                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10228                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10229                    if (stable) {
10230                        conn.stableCount++;
10231                        conn.numStableIncs++;
10232                    } else {
10233                        conn.unstableCount++;
10234                        conn.numUnstableIncs++;
10235                    }
10236                    return conn;
10237                }
10238            }
10239            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10240            if (stable) {
10241                conn.stableCount = 1;
10242                conn.numStableIncs = 1;
10243            } else {
10244                conn.unstableCount = 1;
10245                conn.numUnstableIncs = 1;
10246            }
10247            cpr.connections.add(conn);
10248            r.conProviders.add(conn);
10249            startAssociationLocked(r.uid, r.processName, r.curProcState,
10250                    cpr.uid, cpr.name, cpr.info.processName);
10251            return conn;
10252        }
10253        cpr.addExternalProcessHandleLocked(externalProcessToken);
10254        return null;
10255    }
10256
10257    boolean decProviderCountLocked(ContentProviderConnection conn,
10258            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10259        if (conn != null) {
10260            cpr = conn.provider;
10261            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10262                    "Removing provider requested by "
10263                    + conn.client.processName + " from process "
10264                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10265                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10266            if (stable) {
10267                conn.stableCount--;
10268            } else {
10269                conn.unstableCount--;
10270            }
10271            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10272                cpr.connections.remove(conn);
10273                conn.client.conProviders.remove(conn);
10274                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10275                    // The client is more important than last activity -- note the time this
10276                    // is happening, so we keep the old provider process around a bit as last
10277                    // activity to avoid thrashing it.
10278                    if (cpr.proc != null) {
10279                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10280                    }
10281                }
10282                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10283                return true;
10284            }
10285            return false;
10286        }
10287        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10288        return false;
10289    }
10290
10291    private void checkTime(long startTime, String where) {
10292        long now = SystemClock.elapsedRealtime();
10293        if ((now-startTime) > 1000) {
10294            // If we are taking more than a second, log about it.
10295            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10296        }
10297    }
10298
10299    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10300            String name, IBinder token, boolean stable, int userId) {
10301        ContentProviderRecord cpr;
10302        ContentProviderConnection conn = null;
10303        ProviderInfo cpi = null;
10304
10305        synchronized(this) {
10306            long startTime = SystemClock.elapsedRealtime();
10307
10308            ProcessRecord r = null;
10309            if (caller != null) {
10310                r = getRecordForAppLocked(caller);
10311                if (r == null) {
10312                    throw new SecurityException(
10313                            "Unable to find app for caller " + caller
10314                          + " (pid=" + Binder.getCallingPid()
10315                          + ") when getting content provider " + name);
10316                }
10317            }
10318
10319            boolean checkCrossUser = true;
10320
10321            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10322
10323            // First check if this content provider has been published...
10324            cpr = mProviderMap.getProviderByName(name, userId);
10325            // If that didn't work, check if it exists for user 0 and then
10326            // verify that it's a singleton provider before using it.
10327            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10328                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10329                if (cpr != null) {
10330                    cpi = cpr.info;
10331                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10332                            cpi.name, cpi.flags)
10333                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10334                        userId = UserHandle.USER_SYSTEM;
10335                        checkCrossUser = false;
10336                    } else {
10337                        cpr = null;
10338                        cpi = null;
10339                    }
10340                }
10341            }
10342
10343            boolean providerRunning = cpr != null;
10344            if (providerRunning) {
10345                cpi = cpr.info;
10346                String msg;
10347                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10348                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10349                        != null) {
10350                    throw new SecurityException(msg);
10351                }
10352                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10353
10354                if (r != null && cpr.canRunHere(r)) {
10355                    // This provider has been published or is in the process
10356                    // of being published...  but it is also allowed to run
10357                    // in the caller's process, so don't make a connection
10358                    // and just let the caller instantiate its own instance.
10359                    ContentProviderHolder holder = cpr.newHolder(null);
10360                    // don't give caller the provider object, it needs
10361                    // to make its own.
10362                    holder.provider = null;
10363                    return holder;
10364                }
10365
10366                final long origId = Binder.clearCallingIdentity();
10367
10368                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10369
10370                // In this case the provider instance already exists, so we can
10371                // return it right away.
10372                conn = incProviderCountLocked(r, cpr, token, stable);
10373                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10374                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10375                        // If this is a perceptible app accessing the provider,
10376                        // make sure to count it as being accessed and thus
10377                        // back up on the LRU list.  This is good because
10378                        // content providers are often expensive to start.
10379                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10380                        updateLruProcessLocked(cpr.proc, false, null);
10381                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10382                    }
10383                }
10384
10385                if (cpr.proc != null) {
10386                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10387                    boolean success = updateOomAdjLocked(cpr.proc);
10388                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10389                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10390                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10391                    // NOTE: there is still a race here where a signal could be
10392                    // pending on the process even though we managed to update its
10393                    // adj level.  Not sure what to do about this, but at least
10394                    // the race is now smaller.
10395                    if (!success) {
10396                        // Uh oh...  it looks like the provider's process
10397                        // has been killed on us.  We need to wait for a new
10398                        // process to be started, and make sure its death
10399                        // doesn't kill our process.
10400                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10401                                + " is crashing; detaching " + r);
10402                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10403                        checkTime(startTime, "getContentProviderImpl: before appDied");
10404                        appDiedLocked(cpr.proc);
10405                        checkTime(startTime, "getContentProviderImpl: after appDied");
10406                        if (!lastRef) {
10407                            // This wasn't the last ref our process had on
10408                            // the provider...  we have now been killed, bail.
10409                            return null;
10410                        }
10411                        providerRunning = false;
10412                        conn = null;
10413                    }
10414                }
10415
10416                Binder.restoreCallingIdentity(origId);
10417            }
10418
10419            if (!providerRunning) {
10420                try {
10421                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10422                    cpi = AppGlobals.getPackageManager().
10423                        resolveContentProvider(name,
10424                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10425                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10426                } catch (RemoteException ex) {
10427                }
10428                if (cpi == null) {
10429                    return null;
10430                }
10431                // If the provider is a singleton AND
10432                // (it's a call within the same user || the provider is a
10433                // privileged app)
10434                // Then allow connecting to the singleton provider
10435                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10436                        cpi.name, cpi.flags)
10437                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10438                if (singleton) {
10439                    userId = UserHandle.USER_SYSTEM;
10440                }
10441                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10442                checkTime(startTime, "getContentProviderImpl: got app info for user");
10443
10444                String msg;
10445                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10446                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10447                        != null) {
10448                    throw new SecurityException(msg);
10449                }
10450                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10451
10452                if (!mProcessesReady
10453                        && !cpi.processName.equals("system")) {
10454                    // If this content provider does not run in the system
10455                    // process, and the system is not yet ready to run other
10456                    // processes, then fail fast instead of hanging.
10457                    throw new IllegalArgumentException(
10458                            "Attempt to launch content provider before system ready");
10459                }
10460
10461                // Make sure that the user who owns this provider is running.  If not,
10462                // we don't want to allow it to run.
10463                if (!mUserController.isUserRunningLocked(userId, 0)) {
10464                    Slog.w(TAG, "Unable to launch app "
10465                            + cpi.applicationInfo.packageName + "/"
10466                            + cpi.applicationInfo.uid + " for provider "
10467                            + name + ": user " + userId + " is stopped");
10468                    return null;
10469                }
10470
10471                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10472                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10473                cpr = mProviderMap.getProviderByClass(comp, userId);
10474                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10475                final boolean firstClass = cpr == null;
10476                if (firstClass) {
10477                    final long ident = Binder.clearCallingIdentity();
10478
10479                    // If permissions need a review before any of the app components can run,
10480                    // we return no provider and launch a review activity if the calling app
10481                    // is in the foreground.
10482                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10483                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10484                            return null;
10485                        }
10486                    }
10487
10488                    try {
10489                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10490                        ApplicationInfo ai =
10491                            AppGlobals.getPackageManager().
10492                                getApplicationInfo(
10493                                        cpi.applicationInfo.packageName,
10494                                        STOCK_PM_FLAGS, userId);
10495                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10496                        if (ai == null) {
10497                            Slog.w(TAG, "No package info for content provider "
10498                                    + cpi.name);
10499                            return null;
10500                        }
10501                        ai = getAppInfoForUser(ai, userId);
10502                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10503                    } catch (RemoteException ex) {
10504                        // pm is in same process, this will never happen.
10505                    } finally {
10506                        Binder.restoreCallingIdentity(ident);
10507                    }
10508                }
10509
10510                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10511
10512                if (r != null && cpr.canRunHere(r)) {
10513                    // If this is a multiprocess provider, then just return its
10514                    // info and allow the caller to instantiate it.  Only do
10515                    // this if the provider is the same user as the caller's
10516                    // process, or can run as root (so can be in any process).
10517                    return cpr.newHolder(null);
10518                }
10519
10520                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10521                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10522                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10523
10524                // This is single process, and our app is now connecting to it.
10525                // See if we are already in the process of launching this
10526                // provider.
10527                final int N = mLaunchingProviders.size();
10528                int i;
10529                for (i = 0; i < N; i++) {
10530                    if (mLaunchingProviders.get(i) == cpr) {
10531                        break;
10532                    }
10533                }
10534
10535                // If the provider is not already being launched, then get it
10536                // started.
10537                if (i >= N) {
10538                    final long origId = Binder.clearCallingIdentity();
10539
10540                    try {
10541                        // Content provider is now in use, its package can't be stopped.
10542                        try {
10543                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10544                            AppGlobals.getPackageManager().setPackageStoppedState(
10545                                    cpr.appInfo.packageName, false, userId);
10546                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10547                        } catch (RemoteException e) {
10548                        } catch (IllegalArgumentException e) {
10549                            Slog.w(TAG, "Failed trying to unstop package "
10550                                    + cpr.appInfo.packageName + ": " + e);
10551                        }
10552
10553                        // Use existing process if already started
10554                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10555                        ProcessRecord proc = getProcessRecordLocked(
10556                                cpi.processName, cpr.appInfo.uid, false);
10557                        if (proc != null && proc.thread != null) {
10558                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10559                                    "Installing in existing process " + proc);
10560                            if (!proc.pubProviders.containsKey(cpi.name)) {
10561                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10562                                proc.pubProviders.put(cpi.name, cpr);
10563                                try {
10564                                    proc.thread.scheduleInstallProvider(cpi);
10565                                } catch (RemoteException e) {
10566                                }
10567                            }
10568                        } else {
10569                            checkTime(startTime, "getContentProviderImpl: before start process");
10570                            proc = startProcessLocked(cpi.processName,
10571                                    cpr.appInfo, false, 0, "content provider",
10572                                    new ComponentName(cpi.applicationInfo.packageName,
10573                                            cpi.name), false, false, false);
10574                            checkTime(startTime, "getContentProviderImpl: after start process");
10575                            if (proc == null) {
10576                                Slog.w(TAG, "Unable to launch app "
10577                                        + cpi.applicationInfo.packageName + "/"
10578                                        + cpi.applicationInfo.uid + " for provider "
10579                                        + name + ": process is bad");
10580                                return null;
10581                            }
10582                        }
10583                        cpr.launchingApp = proc;
10584                        mLaunchingProviders.add(cpr);
10585                    } finally {
10586                        Binder.restoreCallingIdentity(origId);
10587                    }
10588                }
10589
10590                checkTime(startTime, "getContentProviderImpl: updating data structures");
10591
10592                // Make sure the provider is published (the same provider class
10593                // may be published under multiple names).
10594                if (firstClass) {
10595                    mProviderMap.putProviderByClass(comp, cpr);
10596                }
10597
10598                mProviderMap.putProviderByName(name, cpr);
10599                conn = incProviderCountLocked(r, cpr, token, stable);
10600                if (conn != null) {
10601                    conn.waiting = true;
10602                }
10603            }
10604            checkTime(startTime, "getContentProviderImpl: done!");
10605        }
10606
10607        // Wait for the provider to be published...
10608        synchronized (cpr) {
10609            while (cpr.provider == null) {
10610                if (cpr.launchingApp == null) {
10611                    Slog.w(TAG, "Unable to launch app "
10612                            + cpi.applicationInfo.packageName + "/"
10613                            + cpi.applicationInfo.uid + " for provider "
10614                            + name + ": launching app became null");
10615                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10616                            UserHandle.getUserId(cpi.applicationInfo.uid),
10617                            cpi.applicationInfo.packageName,
10618                            cpi.applicationInfo.uid, name);
10619                    return null;
10620                }
10621                try {
10622                    if (DEBUG_MU) Slog.v(TAG_MU,
10623                            "Waiting to start provider " + cpr
10624                            + " launchingApp=" + cpr.launchingApp);
10625                    if (conn != null) {
10626                        conn.waiting = true;
10627                    }
10628                    cpr.wait();
10629                } catch (InterruptedException ex) {
10630                } finally {
10631                    if (conn != null) {
10632                        conn.waiting = false;
10633                    }
10634                }
10635            }
10636        }
10637        return cpr != null ? cpr.newHolder(conn) : null;
10638    }
10639
10640    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10641            ProcessRecord r, final int userId) {
10642        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10643                cpi.packageName, userId)) {
10644
10645            final boolean callerForeground = r == null || r.setSchedGroup
10646                    != ProcessList.SCHED_GROUP_BACKGROUND;
10647
10648            // Show a permission review UI only for starting from a foreground app
10649            if (!callerForeground) {
10650                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10651                        + cpi.packageName + " requires a permissions review");
10652                return false;
10653            }
10654
10655            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10656            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10657                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10658            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10659
10660            if (DEBUG_PERMISSIONS_REVIEW) {
10661                Slog.i(TAG, "u" + userId + " Launching permission review "
10662                        + "for package " + cpi.packageName);
10663            }
10664
10665            final UserHandle userHandle = new UserHandle(userId);
10666            mHandler.post(new Runnable() {
10667                @Override
10668                public void run() {
10669                    mContext.startActivityAsUser(intent, userHandle);
10670                }
10671            });
10672
10673            return false;
10674        }
10675
10676        return true;
10677    }
10678
10679    PackageManagerInternal getPackageManagerInternalLocked() {
10680        if (mPackageManagerInt == null) {
10681            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10682        }
10683        return mPackageManagerInt;
10684    }
10685
10686    @Override
10687    public final ContentProviderHolder getContentProvider(
10688            IApplicationThread caller, String name, int userId, boolean stable) {
10689        enforceNotIsolatedCaller("getContentProvider");
10690        if (caller == null) {
10691            String msg = "null IApplicationThread when getting content provider "
10692                    + name;
10693            Slog.w(TAG, msg);
10694            throw new SecurityException(msg);
10695        }
10696        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10697        // with cross-user grant.
10698        return getContentProviderImpl(caller, name, null, stable, userId);
10699    }
10700
10701    public ContentProviderHolder getContentProviderExternal(
10702            String name, int userId, IBinder token) {
10703        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10704            "Do not have permission in call getContentProviderExternal()");
10705        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10706                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10707        return getContentProviderExternalUnchecked(name, token, userId);
10708    }
10709
10710    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10711            IBinder token, int userId) {
10712        return getContentProviderImpl(null, name, token, true, userId);
10713    }
10714
10715    /**
10716     * Drop a content provider from a ProcessRecord's bookkeeping
10717     */
10718    public void removeContentProvider(IBinder connection, boolean stable) {
10719        enforceNotIsolatedCaller("removeContentProvider");
10720        long ident = Binder.clearCallingIdentity();
10721        try {
10722            synchronized (this) {
10723                ContentProviderConnection conn;
10724                try {
10725                    conn = (ContentProviderConnection)connection;
10726                } catch (ClassCastException e) {
10727                    String msg ="removeContentProvider: " + connection
10728                            + " not a ContentProviderConnection";
10729                    Slog.w(TAG, msg);
10730                    throw new IllegalArgumentException(msg);
10731                }
10732                if (conn == null) {
10733                    throw new NullPointerException("connection is null");
10734                }
10735                if (decProviderCountLocked(conn, null, null, stable)) {
10736                    updateOomAdjLocked();
10737                }
10738            }
10739        } finally {
10740            Binder.restoreCallingIdentity(ident);
10741        }
10742    }
10743
10744    public void removeContentProviderExternal(String name, IBinder token) {
10745        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10746            "Do not have permission in call removeContentProviderExternal()");
10747        int userId = UserHandle.getCallingUserId();
10748        long ident = Binder.clearCallingIdentity();
10749        try {
10750            removeContentProviderExternalUnchecked(name, token, userId);
10751        } finally {
10752            Binder.restoreCallingIdentity(ident);
10753        }
10754    }
10755
10756    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10757        synchronized (this) {
10758            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10759            if(cpr == null) {
10760                //remove from mProvidersByClass
10761                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10762                return;
10763            }
10764
10765            //update content provider record entry info
10766            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10767            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10768            if (localCpr.hasExternalProcessHandles()) {
10769                if (localCpr.removeExternalProcessHandleLocked(token)) {
10770                    updateOomAdjLocked();
10771                } else {
10772                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10773                            + " with no external reference for token: "
10774                            + token + ".");
10775                }
10776            } else {
10777                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10778                        + " with no external references.");
10779            }
10780        }
10781    }
10782
10783    public final void publishContentProviders(IApplicationThread caller,
10784            List<ContentProviderHolder> providers) {
10785        if (providers == null) {
10786            return;
10787        }
10788
10789        enforceNotIsolatedCaller("publishContentProviders");
10790        synchronized (this) {
10791            final ProcessRecord r = getRecordForAppLocked(caller);
10792            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10793            if (r == null) {
10794                throw new SecurityException(
10795                        "Unable to find app for caller " + caller
10796                      + " (pid=" + Binder.getCallingPid()
10797                      + ") when publishing content providers");
10798            }
10799
10800            final long origId = Binder.clearCallingIdentity();
10801
10802            final int N = providers.size();
10803            for (int i = 0; i < N; i++) {
10804                ContentProviderHolder src = providers.get(i);
10805                if (src == null || src.info == null || src.provider == null) {
10806                    continue;
10807                }
10808                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10809                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10810                if (dst != null) {
10811                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10812                    mProviderMap.putProviderByClass(comp, dst);
10813                    String names[] = dst.info.authority.split(";");
10814                    for (int j = 0; j < names.length; j++) {
10815                        mProviderMap.putProviderByName(names[j], dst);
10816                    }
10817
10818                    int launchingCount = mLaunchingProviders.size();
10819                    int j;
10820                    boolean wasInLaunchingProviders = false;
10821                    for (j = 0; j < launchingCount; j++) {
10822                        if (mLaunchingProviders.get(j) == dst) {
10823                            mLaunchingProviders.remove(j);
10824                            wasInLaunchingProviders = true;
10825                            j--;
10826                            launchingCount--;
10827                        }
10828                    }
10829                    if (wasInLaunchingProviders) {
10830                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10831                    }
10832                    synchronized (dst) {
10833                        dst.provider = src.provider;
10834                        dst.proc = r;
10835                        dst.notifyAll();
10836                    }
10837                    updateOomAdjLocked(r);
10838                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10839                            src.info.authority);
10840                }
10841            }
10842
10843            Binder.restoreCallingIdentity(origId);
10844        }
10845    }
10846
10847    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10848        ContentProviderConnection conn;
10849        try {
10850            conn = (ContentProviderConnection)connection;
10851        } catch (ClassCastException e) {
10852            String msg ="refContentProvider: " + connection
10853                    + " not a ContentProviderConnection";
10854            Slog.w(TAG, msg);
10855            throw new IllegalArgumentException(msg);
10856        }
10857        if (conn == null) {
10858            throw new NullPointerException("connection is null");
10859        }
10860
10861        synchronized (this) {
10862            if (stable > 0) {
10863                conn.numStableIncs += stable;
10864            }
10865            stable = conn.stableCount + stable;
10866            if (stable < 0) {
10867                throw new IllegalStateException("stableCount < 0: " + stable);
10868            }
10869
10870            if (unstable > 0) {
10871                conn.numUnstableIncs += unstable;
10872            }
10873            unstable = conn.unstableCount + unstable;
10874            if (unstable < 0) {
10875                throw new IllegalStateException("unstableCount < 0: " + unstable);
10876            }
10877
10878            if ((stable+unstable) <= 0) {
10879                throw new IllegalStateException("ref counts can't go to zero here: stable="
10880                        + stable + " unstable=" + unstable);
10881            }
10882            conn.stableCount = stable;
10883            conn.unstableCount = unstable;
10884            return !conn.dead;
10885        }
10886    }
10887
10888    public void unstableProviderDied(IBinder connection) {
10889        ContentProviderConnection conn;
10890        try {
10891            conn = (ContentProviderConnection)connection;
10892        } catch (ClassCastException e) {
10893            String msg ="refContentProvider: " + connection
10894                    + " not a ContentProviderConnection";
10895            Slog.w(TAG, msg);
10896            throw new IllegalArgumentException(msg);
10897        }
10898        if (conn == null) {
10899            throw new NullPointerException("connection is null");
10900        }
10901
10902        // Safely retrieve the content provider associated with the connection.
10903        IContentProvider provider;
10904        synchronized (this) {
10905            provider = conn.provider.provider;
10906        }
10907
10908        if (provider == null) {
10909            // Um, yeah, we're way ahead of you.
10910            return;
10911        }
10912
10913        // Make sure the caller is being honest with us.
10914        if (provider.asBinder().pingBinder()) {
10915            // Er, no, still looks good to us.
10916            synchronized (this) {
10917                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10918                        + " says " + conn + " died, but we don't agree");
10919                return;
10920            }
10921        }
10922
10923        // Well look at that!  It's dead!
10924        synchronized (this) {
10925            if (conn.provider.provider != provider) {
10926                // But something changed...  good enough.
10927                return;
10928            }
10929
10930            ProcessRecord proc = conn.provider.proc;
10931            if (proc == null || proc.thread == null) {
10932                // Seems like the process is already cleaned up.
10933                return;
10934            }
10935
10936            // As far as we're concerned, this is just like receiving a
10937            // death notification...  just a bit prematurely.
10938            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10939                    + ") early provider death");
10940            final long ident = Binder.clearCallingIdentity();
10941            try {
10942                appDiedLocked(proc);
10943            } finally {
10944                Binder.restoreCallingIdentity(ident);
10945            }
10946        }
10947    }
10948
10949    @Override
10950    public void appNotRespondingViaProvider(IBinder connection) {
10951        enforceCallingPermission(
10952                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10953
10954        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10955        if (conn == null) {
10956            Slog.w(TAG, "ContentProviderConnection is null");
10957            return;
10958        }
10959
10960        final ProcessRecord host = conn.provider.proc;
10961        if (host == null) {
10962            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10963            return;
10964        }
10965
10966        mHandler.post(new Runnable() {
10967            @Override
10968            public void run() {
10969                mAppErrors.appNotResponding(host, null, null, false,
10970                        "ContentProvider not responding");
10971            }
10972        });
10973    }
10974
10975    public final void installSystemProviders() {
10976        List<ProviderInfo> providers;
10977        synchronized (this) {
10978            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10979            providers = generateApplicationProvidersLocked(app);
10980            if (providers != null) {
10981                for (int i=providers.size()-1; i>=0; i--) {
10982                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10983                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10984                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10985                                + ": not system .apk");
10986                        providers.remove(i);
10987                    }
10988                }
10989            }
10990        }
10991        if (providers != null) {
10992            mSystemThread.installSystemProviders(providers);
10993        }
10994
10995        mCoreSettingsObserver = new CoreSettingsObserver(this);
10996        mFontScaleSettingObserver = new FontScaleSettingObserver();
10997
10998        //mUsageStatsService.monitorPackages();
10999    }
11000
11001    private void startPersistentApps(int matchFlags) {
11002        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11003
11004        synchronized (this) {
11005            try {
11006                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11007                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11008                for (ApplicationInfo app : apps) {
11009                    if (!"android".equals(app.packageName)) {
11010                        addAppLocked(app, false, null /* ABI override */);
11011                    }
11012                }
11013            } catch (RemoteException ex) {
11014            }
11015        }
11016    }
11017
11018    /**
11019     * When a user is unlocked, we need to install encryption-unaware providers
11020     * belonging to any running apps.
11021     */
11022    private void installEncryptionUnawareProviders(int userId) {
11023        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11024            // TODO: eventually pivot this back to look at current user state,
11025            // similar to the comment in UserManager.isUserUnlocked(), but for
11026            // now, if we started apps when "unlocked" then unaware providers
11027            // have already been spun up.
11028            return;
11029        }
11030
11031        // We're only interested in providers that are encryption unaware, and
11032        // we don't care about uninstalled apps, since there's no way they're
11033        // running at this point.
11034        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11035
11036        synchronized (this) {
11037            final int NP = mProcessNames.getMap().size();
11038            for (int ip = 0; ip < NP; ip++) {
11039                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11040                final int NA = apps.size();
11041                for (int ia = 0; ia < NA; ia++) {
11042                    final ProcessRecord app = apps.valueAt(ia);
11043                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11044
11045                    final int NG = app.pkgList.size();
11046                    for (int ig = 0; ig < NG; ig++) {
11047                        try {
11048                            final String pkgName = app.pkgList.keyAt(ig);
11049                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11050                                    .getPackageInfo(pkgName, matchFlags, userId);
11051                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11052                                for (ProviderInfo provInfo : pkgInfo.providers) {
11053                                    Log.v(TAG, "Installing " + provInfo);
11054                                    app.thread.scheduleInstallProvider(provInfo);
11055                                }
11056                            }
11057                        } catch (RemoteException ignored) {
11058                        }
11059                    }
11060                }
11061            }
11062        }
11063    }
11064
11065    /**
11066     * Allows apps to retrieve the MIME type of a URI.
11067     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11068     * users, then it does not need permission to access the ContentProvider.
11069     * Either, it needs cross-user uri grants.
11070     *
11071     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11072     *
11073     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11074     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11075     */
11076    public String getProviderMimeType(Uri uri, int userId) {
11077        enforceNotIsolatedCaller("getProviderMimeType");
11078        final String name = uri.getAuthority();
11079        int callingUid = Binder.getCallingUid();
11080        int callingPid = Binder.getCallingPid();
11081        long ident = 0;
11082        boolean clearedIdentity = false;
11083        synchronized (this) {
11084            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11085        }
11086        if (canClearIdentity(callingPid, callingUid, userId)) {
11087            clearedIdentity = true;
11088            ident = Binder.clearCallingIdentity();
11089        }
11090        ContentProviderHolder holder = null;
11091        try {
11092            holder = getContentProviderExternalUnchecked(name, null, userId);
11093            if (holder != null) {
11094                return holder.provider.getType(uri);
11095            }
11096        } catch (RemoteException e) {
11097            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11098            return null;
11099        } finally {
11100            // We need to clear the identity to call removeContentProviderExternalUnchecked
11101            if (!clearedIdentity) {
11102                ident = Binder.clearCallingIdentity();
11103            }
11104            try {
11105                if (holder != null) {
11106                    removeContentProviderExternalUnchecked(name, null, userId);
11107                }
11108            } finally {
11109                Binder.restoreCallingIdentity(ident);
11110            }
11111        }
11112
11113        return null;
11114    }
11115
11116    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11117        if (UserHandle.getUserId(callingUid) == userId) {
11118            return true;
11119        }
11120        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11121                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11122                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11123                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11124                return true;
11125        }
11126        return false;
11127    }
11128
11129    // =========================================================
11130    // GLOBAL MANAGEMENT
11131    // =========================================================
11132
11133    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11134            boolean isolated, int isolatedUid) {
11135        String proc = customProcess != null ? customProcess : info.processName;
11136        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11137        final int userId = UserHandle.getUserId(info.uid);
11138        int uid = info.uid;
11139        if (isolated) {
11140            if (isolatedUid == 0) {
11141                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11142                while (true) {
11143                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11144                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11145                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11146                    }
11147                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11148                    mNextIsolatedProcessUid++;
11149                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11150                        // No process for this uid, use it.
11151                        break;
11152                    }
11153                    stepsLeft--;
11154                    if (stepsLeft <= 0) {
11155                        return null;
11156                    }
11157                }
11158            } else {
11159                // Special case for startIsolatedProcess (internal only), where
11160                // the uid of the isolated process is specified by the caller.
11161                uid = isolatedUid;
11162            }
11163        }
11164        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11165        if (!mBooted && !mBooting
11166                && userId == UserHandle.USER_SYSTEM
11167                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11168            r.persistent = true;
11169        }
11170        addProcessNameLocked(r);
11171        return r;
11172    }
11173
11174    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11175            String abiOverride) {
11176        ProcessRecord app;
11177        if (!isolated) {
11178            app = getProcessRecordLocked(info.processName, info.uid, true);
11179        } else {
11180            app = null;
11181        }
11182
11183        if (app == null) {
11184            app = newProcessRecordLocked(info, null, isolated, 0);
11185            updateLruProcessLocked(app, false, null);
11186            updateOomAdjLocked();
11187        }
11188
11189        // This package really, really can not be stopped.
11190        try {
11191            AppGlobals.getPackageManager().setPackageStoppedState(
11192                    info.packageName, false, UserHandle.getUserId(app.uid));
11193        } catch (RemoteException e) {
11194        } catch (IllegalArgumentException e) {
11195            Slog.w(TAG, "Failed trying to unstop package "
11196                    + info.packageName + ": " + e);
11197        }
11198
11199        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11200            app.persistent = true;
11201            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11202        }
11203        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11204            mPersistentStartingProcesses.add(app);
11205            startProcessLocked(app, "added application", app.processName, abiOverride,
11206                    null /* entryPoint */, null /* entryPointArgs */);
11207        }
11208
11209        return app;
11210    }
11211
11212    public void unhandledBack() {
11213        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11214                "unhandledBack()");
11215
11216        synchronized(this) {
11217            final long origId = Binder.clearCallingIdentity();
11218            try {
11219                getFocusedStack().unhandledBackLocked();
11220            } finally {
11221                Binder.restoreCallingIdentity(origId);
11222            }
11223        }
11224    }
11225
11226    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11227        enforceNotIsolatedCaller("openContentUri");
11228        final int userId = UserHandle.getCallingUserId();
11229        String name = uri.getAuthority();
11230        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11231        ParcelFileDescriptor pfd = null;
11232        if (cph != null) {
11233            // We record the binder invoker's uid in thread-local storage before
11234            // going to the content provider to open the file.  Later, in the code
11235            // that handles all permissions checks, we look for this uid and use
11236            // that rather than the Activity Manager's own uid.  The effect is that
11237            // we do the check against the caller's permissions even though it looks
11238            // to the content provider like the Activity Manager itself is making
11239            // the request.
11240            Binder token = new Binder();
11241            sCallerIdentity.set(new Identity(
11242                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11243            try {
11244                pfd = cph.provider.openFile(null, uri, "r", null, token);
11245            } catch (FileNotFoundException e) {
11246                // do nothing; pfd will be returned null
11247            } finally {
11248                // Ensure that whatever happens, we clean up the identity state
11249                sCallerIdentity.remove();
11250                // Ensure we're done with the provider.
11251                removeContentProviderExternalUnchecked(name, null, userId);
11252            }
11253        } else {
11254            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11255        }
11256        return pfd;
11257    }
11258
11259    // Actually is sleeping or shutting down or whatever else in the future
11260    // is an inactive state.
11261    public boolean isSleepingOrShuttingDown() {
11262        return isSleeping() || mShuttingDown;
11263    }
11264
11265    public boolean isSleeping() {
11266        return mSleeping;
11267    }
11268
11269    void onWakefulnessChanged(int wakefulness) {
11270        synchronized(this) {
11271            mWakefulness = wakefulness;
11272            updateSleepIfNeededLocked();
11273        }
11274    }
11275
11276    void finishRunningVoiceLocked() {
11277        if (mRunningVoice != null) {
11278            mRunningVoice = null;
11279            mVoiceWakeLock.release();
11280            updateSleepIfNeededLocked();
11281        }
11282    }
11283
11284    void startTimeTrackingFocusedActivityLocked() {
11285        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11286            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11287        }
11288    }
11289
11290    void updateSleepIfNeededLocked() {
11291        if (mSleeping && !shouldSleepLocked()) {
11292            mSleeping = false;
11293            startTimeTrackingFocusedActivityLocked();
11294            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11295            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11296            updateOomAdjLocked();
11297        } else if (!mSleeping && shouldSleepLocked()) {
11298            mSleeping = true;
11299            if (mCurAppTimeTracker != null) {
11300                mCurAppTimeTracker.stop();
11301            }
11302            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11303            mStackSupervisor.goingToSleepLocked();
11304            updateOomAdjLocked();
11305
11306            // Initialize the wake times of all processes.
11307            checkExcessivePowerUsageLocked(false);
11308            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11309            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11310            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11311        }
11312    }
11313
11314    private boolean shouldSleepLocked() {
11315        // Resume applications while running a voice interactor.
11316        if (mRunningVoice != null) {
11317            return false;
11318        }
11319
11320        // TODO: Transform the lock screen state into a sleep token instead.
11321        switch (mWakefulness) {
11322            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11323            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11324            case PowerManagerInternal.WAKEFULNESS_DOZING:
11325                // Pause applications whenever the lock screen is shown or any sleep
11326                // tokens have been acquired.
11327                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11328            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11329            default:
11330                // If we're asleep then pause applications unconditionally.
11331                return true;
11332        }
11333    }
11334
11335    /** Pokes the task persister. */
11336    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11337        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11338    }
11339
11340    /** Notifies all listeners when the task stack has changed. */
11341    void notifyTaskStackChangedLocked() {
11342        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11343        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11344        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11345        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11346    }
11347
11348    /** Notifies all listeners when an Activity is pinned. */
11349    void notifyActivityPinnedLocked() {
11350        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11351        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11352    }
11353
11354    /**
11355     * Notifies all listeners when an attempt was made to start an an activity that is already
11356     * running in the pinned stack and the activity was not actually started, but the task is
11357     * either brought to the front or a new Intent is delivered to it.
11358     */
11359    void notifyPinnedActivityRestartAttemptLocked() {
11360        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11361        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11362    }
11363
11364    /** Notifies all listeners when the pinned stack animation ends. */
11365    @Override
11366    public void notifyPinnedStackAnimationEnded() {
11367        synchronized (this) {
11368            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11369            mHandler.obtainMessage(
11370                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11371        }
11372    }
11373
11374    @Override
11375    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11376        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11377    }
11378
11379    @Override
11380    public boolean shutdown(int timeout) {
11381        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11382                != PackageManager.PERMISSION_GRANTED) {
11383            throw new SecurityException("Requires permission "
11384                    + android.Manifest.permission.SHUTDOWN);
11385        }
11386
11387        boolean timedout = false;
11388
11389        synchronized(this) {
11390            mShuttingDown = true;
11391            updateEventDispatchingLocked();
11392            timedout = mStackSupervisor.shutdownLocked(timeout);
11393        }
11394
11395        mAppOpsService.shutdown();
11396        if (mUsageStatsService != null) {
11397            mUsageStatsService.prepareShutdown();
11398        }
11399        mBatteryStatsService.shutdown();
11400        synchronized (this) {
11401            mProcessStats.shutdownLocked();
11402            notifyTaskPersisterLocked(null, true);
11403        }
11404
11405        return timedout;
11406    }
11407
11408    public final void activitySlept(IBinder token) {
11409        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11410
11411        final long origId = Binder.clearCallingIdentity();
11412
11413        synchronized (this) {
11414            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11415            if (r != null) {
11416                mStackSupervisor.activitySleptLocked(r);
11417            }
11418        }
11419
11420        Binder.restoreCallingIdentity(origId);
11421    }
11422
11423    private String lockScreenShownToString() {
11424        switch (mLockScreenShown) {
11425            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11426            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11427            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11428            default: return "Unknown=" + mLockScreenShown;
11429        }
11430    }
11431
11432    void logLockScreen(String msg) {
11433        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11434                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11435                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11436                + " mSleeping=" + mSleeping);
11437    }
11438
11439    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11440        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11441        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11442        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11443            boolean wasRunningVoice = mRunningVoice != null;
11444            mRunningVoice = session;
11445            if (!wasRunningVoice) {
11446                mVoiceWakeLock.acquire();
11447                updateSleepIfNeededLocked();
11448            }
11449        }
11450    }
11451
11452    private void updateEventDispatchingLocked() {
11453        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11454    }
11455
11456    public void setLockScreenShown(boolean shown) {
11457        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11458                != PackageManager.PERMISSION_GRANTED) {
11459            throw new SecurityException("Requires permission "
11460                    + android.Manifest.permission.DEVICE_POWER);
11461        }
11462
11463        synchronized(this) {
11464            long ident = Binder.clearCallingIdentity();
11465            try {
11466                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11467                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11468                updateSleepIfNeededLocked();
11469            } finally {
11470                Binder.restoreCallingIdentity(ident);
11471            }
11472        }
11473    }
11474
11475    @Override
11476    public void notifyLockedProfile(@UserIdInt int userId) {
11477        try {
11478            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11479                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11480            }
11481        } catch (RemoteException ex) {
11482            throw new SecurityException("Fail to check is caller a privileged app", ex);
11483        }
11484
11485        synchronized (this) {
11486            if (mStackSupervisor.isUserLockedProfile(userId)) {
11487                final long ident = Binder.clearCallingIdentity();
11488                try {
11489                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11490                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11491                        // If there is no device lock, we will show the profile's credential page.
11492                        mActivityStarter.showConfirmDeviceCredential(userId);
11493                    } else {
11494                        // Showing launcher to avoid user entering credential twice.
11495                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11496                    }
11497                } finally {
11498                    Binder.restoreCallingIdentity(ident);
11499                }
11500            }
11501        }
11502    }
11503
11504    @Override
11505    public void stopAppSwitches() {
11506        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11507                != PackageManager.PERMISSION_GRANTED) {
11508            throw new SecurityException("viewquires permission "
11509                    + android.Manifest.permission.STOP_APP_SWITCHES);
11510        }
11511
11512        synchronized(this) {
11513            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11514                    + APP_SWITCH_DELAY_TIME;
11515            mDidAppSwitch = false;
11516            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11517            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11518            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11519        }
11520    }
11521
11522    public void resumeAppSwitches() {
11523        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11524                != PackageManager.PERMISSION_GRANTED) {
11525            throw new SecurityException("Requires permission "
11526                    + android.Manifest.permission.STOP_APP_SWITCHES);
11527        }
11528
11529        synchronized(this) {
11530            // Note that we don't execute any pending app switches... we will
11531            // let those wait until either the timeout, or the next start
11532            // activity request.
11533            mAppSwitchesAllowedTime = 0;
11534        }
11535    }
11536
11537    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11538            int callingPid, int callingUid, String name) {
11539        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11540            return true;
11541        }
11542
11543        int perm = checkComponentPermission(
11544                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11545                sourceUid, -1, true);
11546        if (perm == PackageManager.PERMISSION_GRANTED) {
11547            return true;
11548        }
11549
11550        // If the actual IPC caller is different from the logical source, then
11551        // also see if they are allowed to control app switches.
11552        if (callingUid != -1 && callingUid != sourceUid) {
11553            perm = checkComponentPermission(
11554                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11555                    callingUid, -1, true);
11556            if (perm == PackageManager.PERMISSION_GRANTED) {
11557                return true;
11558            }
11559        }
11560
11561        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11562        return false;
11563    }
11564
11565    public void setDebugApp(String packageName, boolean waitForDebugger,
11566            boolean persistent) {
11567        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11568                "setDebugApp()");
11569
11570        long ident = Binder.clearCallingIdentity();
11571        try {
11572            // Note that this is not really thread safe if there are multiple
11573            // callers into it at the same time, but that's not a situation we
11574            // care about.
11575            if (persistent) {
11576                final ContentResolver resolver = mContext.getContentResolver();
11577                Settings.Global.putString(
11578                    resolver, Settings.Global.DEBUG_APP,
11579                    packageName);
11580                Settings.Global.putInt(
11581                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11582                    waitForDebugger ? 1 : 0);
11583            }
11584
11585            synchronized (this) {
11586                if (!persistent) {
11587                    mOrigDebugApp = mDebugApp;
11588                    mOrigWaitForDebugger = mWaitForDebugger;
11589                }
11590                mDebugApp = packageName;
11591                mWaitForDebugger = waitForDebugger;
11592                mDebugTransient = !persistent;
11593                if (packageName != null) {
11594                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11595                            false, UserHandle.USER_ALL, "set debug app");
11596                }
11597            }
11598        } finally {
11599            Binder.restoreCallingIdentity(ident);
11600        }
11601    }
11602
11603    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11604        synchronized (this) {
11605            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11606            if (!isDebuggable) {
11607                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11608                    throw new SecurityException("Process not debuggable: " + app.packageName);
11609                }
11610            }
11611
11612            mTrackAllocationApp = processName;
11613        }
11614    }
11615
11616    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11617        synchronized (this) {
11618            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11619            if (!isDebuggable) {
11620                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11621                    throw new SecurityException("Process not debuggable: " + app.packageName);
11622                }
11623            }
11624            mProfileApp = processName;
11625            mProfileFile = profilerInfo.profileFile;
11626            if (mProfileFd != null) {
11627                try {
11628                    mProfileFd.close();
11629                } catch (IOException e) {
11630                }
11631                mProfileFd = null;
11632            }
11633            mProfileFd = profilerInfo.profileFd;
11634            mSamplingInterval = profilerInfo.samplingInterval;
11635            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11636            mProfileType = 0;
11637        }
11638    }
11639
11640    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11641        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11642        if (!isDebuggable) {
11643            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11644                throw new SecurityException("Process not debuggable: " + app.packageName);
11645            }
11646        }
11647        mNativeDebuggingApp = processName;
11648    }
11649
11650    @Override
11651    public void setAlwaysFinish(boolean enabled) {
11652        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11653                "setAlwaysFinish()");
11654
11655        long ident = Binder.clearCallingIdentity();
11656        try {
11657            Settings.Global.putInt(
11658                    mContext.getContentResolver(),
11659                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11660
11661            synchronized (this) {
11662                mAlwaysFinishActivities = enabled;
11663            }
11664        } finally {
11665            Binder.restoreCallingIdentity(ident);
11666        }
11667    }
11668
11669    @Override
11670    public void setLenientBackgroundCheck(boolean enabled) {
11671        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11672                "setLenientBackgroundCheck()");
11673
11674        long ident = Binder.clearCallingIdentity();
11675        try {
11676            Settings.Global.putInt(
11677                    mContext.getContentResolver(),
11678                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11679
11680            synchronized (this) {
11681                mLenientBackgroundCheck = enabled;
11682            }
11683        } finally {
11684            Binder.restoreCallingIdentity(ident);
11685        }
11686    }
11687
11688    @Override
11689    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11690        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11691                "setActivityController()");
11692        synchronized (this) {
11693            mController = controller;
11694            mControllerIsAMonkey = imAMonkey;
11695            Watchdog.getInstance().setActivityController(controller);
11696        }
11697    }
11698
11699    @Override
11700    public void setUserIsMonkey(boolean userIsMonkey) {
11701        synchronized (this) {
11702            synchronized (mPidsSelfLocked) {
11703                final int callingPid = Binder.getCallingPid();
11704                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11705                if (precessRecord == null) {
11706                    throw new SecurityException("Unknown process: " + callingPid);
11707                }
11708                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11709                    throw new SecurityException("Only an instrumentation process "
11710                            + "with a UiAutomation can call setUserIsMonkey");
11711                }
11712            }
11713            mUserIsMonkey = userIsMonkey;
11714        }
11715    }
11716
11717    @Override
11718    public boolean isUserAMonkey() {
11719        synchronized (this) {
11720            // If there is a controller also implies the user is a monkey.
11721            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11722        }
11723    }
11724
11725    public void requestBugReport(int bugreportType) {
11726        String service = null;
11727        switch (bugreportType) {
11728            case ActivityManager.BUGREPORT_OPTION_FULL:
11729                service = "bugreport";
11730                break;
11731            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11732                service = "bugreportplus";
11733                break;
11734            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11735                service = "bugreportremote";
11736                break;
11737        }
11738        if (service == null) {
11739            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11740                    + bugreportType);
11741        }
11742        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11743        SystemProperties.set("ctl.start", service);
11744    }
11745
11746    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11747        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11748    }
11749
11750    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11751        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11752            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11753        }
11754        return KEY_DISPATCHING_TIMEOUT;
11755    }
11756
11757    @Override
11758    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11759        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11760                != PackageManager.PERMISSION_GRANTED) {
11761            throw new SecurityException("Requires permission "
11762                    + android.Manifest.permission.FILTER_EVENTS);
11763        }
11764        ProcessRecord proc;
11765        long timeout;
11766        synchronized (this) {
11767            synchronized (mPidsSelfLocked) {
11768                proc = mPidsSelfLocked.get(pid);
11769            }
11770            timeout = getInputDispatchingTimeoutLocked(proc);
11771        }
11772
11773        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11774            return -1;
11775        }
11776
11777        return timeout;
11778    }
11779
11780    /**
11781     * Handle input dispatching timeouts.
11782     * Returns whether input dispatching should be aborted or not.
11783     */
11784    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11785            final ActivityRecord activity, final ActivityRecord parent,
11786            final boolean aboveSystem, String reason) {
11787        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11788                != PackageManager.PERMISSION_GRANTED) {
11789            throw new SecurityException("Requires permission "
11790                    + android.Manifest.permission.FILTER_EVENTS);
11791        }
11792
11793        final String annotation;
11794        if (reason == null) {
11795            annotation = "Input dispatching timed out";
11796        } else {
11797            annotation = "Input dispatching timed out (" + reason + ")";
11798        }
11799
11800        if (proc != null) {
11801            synchronized (this) {
11802                if (proc.debugging) {
11803                    return false;
11804                }
11805
11806                if (mDidDexOpt) {
11807                    // Give more time since we were dexopting.
11808                    mDidDexOpt = false;
11809                    return false;
11810                }
11811
11812                if (proc.instrumentationClass != null) {
11813                    Bundle info = new Bundle();
11814                    info.putString("shortMsg", "keyDispatchingTimedOut");
11815                    info.putString("longMsg", annotation);
11816                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11817                    return true;
11818                }
11819            }
11820            mHandler.post(new Runnable() {
11821                @Override
11822                public void run() {
11823                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11824                }
11825            });
11826        }
11827
11828        return true;
11829    }
11830
11831    @Override
11832    public Bundle getAssistContextExtras(int requestType) {
11833        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11834                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11835        if (pae == null) {
11836            return null;
11837        }
11838        synchronized (pae) {
11839            while (!pae.haveResult) {
11840                try {
11841                    pae.wait();
11842                } catch (InterruptedException e) {
11843                }
11844            }
11845        }
11846        synchronized (this) {
11847            buildAssistBundleLocked(pae, pae.result);
11848            mPendingAssistExtras.remove(pae);
11849            mUiHandler.removeCallbacks(pae);
11850        }
11851        return pae.extras;
11852    }
11853
11854    @Override
11855    public boolean isAssistDataAllowedOnCurrentActivity() {
11856        int userId;
11857        synchronized (this) {
11858            userId = mUserController.getCurrentUserIdLocked();
11859            ActivityRecord activity = getFocusedStack().topActivity();
11860            if (activity == null) {
11861                return false;
11862            }
11863            userId = activity.userId;
11864        }
11865        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11866                Context.DEVICE_POLICY_SERVICE);
11867        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11868    }
11869
11870    @Override
11871    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11872        long ident = Binder.clearCallingIdentity();
11873        try {
11874            synchronized (this) {
11875                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11876                ActivityRecord top = getFocusedStack().topActivity();
11877                if (top != caller) {
11878                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11879                            + " is not current top " + top);
11880                    return false;
11881                }
11882                if (!top.nowVisible) {
11883                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11884                            + " is not visible");
11885                    return false;
11886                }
11887            }
11888            AssistUtils utils = new AssistUtils(mContext);
11889            return utils.showSessionForActiveService(args,
11890                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11891        } finally {
11892            Binder.restoreCallingIdentity(ident);
11893        }
11894    }
11895
11896    @Override
11897    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11898            Bundle receiverExtras,
11899            IBinder activityToken, boolean focused) {
11900        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11901                activityToken, focused,
11902                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11903                != null;
11904    }
11905
11906    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11907            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11908            int userHandle, Bundle args, long timeout) {
11909        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11910                "enqueueAssistContext()");
11911        synchronized (this) {
11912            ActivityRecord activity = getFocusedStack().topActivity();
11913            if (activity == null) {
11914                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11915                return null;
11916            }
11917            if (activity.app == null || activity.app.thread == null) {
11918                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11919                return null;
11920            }
11921            if (focused) {
11922                if (activityToken != null) {
11923                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11924                    if (activity != caller) {
11925                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11926                                + " is not current top " + activity);
11927                        return null;
11928                    }
11929                }
11930            } else {
11931                activity = ActivityRecord.forTokenLocked(activityToken);
11932                if (activity == null) {
11933                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11934                            + " couldn't be found");
11935                    return null;
11936                }
11937            }
11938
11939            PendingAssistExtras pae;
11940            Bundle extras = new Bundle();
11941            if (args != null) {
11942                extras.putAll(args);
11943            }
11944            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11945            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11946            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11947                    userHandle);
11948            try {
11949                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11950                        requestType);
11951                mPendingAssistExtras.add(pae);
11952                mUiHandler.postDelayed(pae, timeout);
11953            } catch (RemoteException e) {
11954                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11955                return null;
11956            }
11957            return pae;
11958        }
11959    }
11960
11961    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11962        IResultReceiver receiver;
11963        synchronized (this) {
11964            mPendingAssistExtras.remove(pae);
11965            receiver = pae.receiver;
11966        }
11967        if (receiver != null) {
11968            // Caller wants result sent back to them.
11969            try {
11970                pae.receiver.send(0, null);
11971            } catch (RemoteException e) {
11972            }
11973        }
11974    }
11975
11976    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11977        if (result != null) {
11978            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11979        }
11980        if (pae.hint != null) {
11981            pae.extras.putBoolean(pae.hint, true);
11982        }
11983    }
11984
11985    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11986            AssistContent content, Uri referrer) {
11987        PendingAssistExtras pae = (PendingAssistExtras)token;
11988        synchronized (pae) {
11989            pae.result = extras;
11990            pae.structure = structure;
11991            pae.content = content;
11992            if (referrer != null) {
11993                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11994            }
11995            pae.haveResult = true;
11996            pae.notifyAll();
11997            if (pae.intent == null && pae.receiver == null) {
11998                // Caller is just waiting for the result.
11999                return;
12000            }
12001        }
12002
12003        // We are now ready to launch the assist activity.
12004        IResultReceiver sendReceiver = null;
12005        Bundle sendBundle = null;
12006        synchronized (this) {
12007            buildAssistBundleLocked(pae, extras);
12008            boolean exists = mPendingAssistExtras.remove(pae);
12009            mUiHandler.removeCallbacks(pae);
12010            if (!exists) {
12011                // Timed out.
12012                return;
12013            }
12014            if ((sendReceiver=pae.receiver) != null) {
12015                // Caller wants result sent back to them.
12016                sendBundle = new Bundle();
12017                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12018                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12019                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12020                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12021                        pae.receiverExtras);
12022            }
12023        }
12024        if (sendReceiver != null) {
12025            try {
12026                sendReceiver.send(0, sendBundle);
12027            } catch (RemoteException e) {
12028            }
12029            return;
12030        }
12031
12032        long ident = Binder.clearCallingIdentity();
12033        try {
12034            pae.intent.replaceExtras(pae.extras);
12035            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12036                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12037                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12038            closeSystemDialogs("assist");
12039            try {
12040                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12041            } catch (ActivityNotFoundException e) {
12042                Slog.w(TAG, "No activity to handle assist action.", e);
12043            }
12044        } finally {
12045            Binder.restoreCallingIdentity(ident);
12046        }
12047    }
12048
12049    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12050            Bundle args) {
12051        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12052                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12053    }
12054
12055    public void registerProcessObserver(IProcessObserver observer) {
12056        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12057                "registerProcessObserver()");
12058        synchronized (this) {
12059            mProcessObservers.register(observer);
12060        }
12061    }
12062
12063    @Override
12064    public void unregisterProcessObserver(IProcessObserver observer) {
12065        synchronized (this) {
12066            mProcessObservers.unregister(observer);
12067        }
12068    }
12069
12070    @Override
12071    public void registerUidObserver(IUidObserver observer, int which) {
12072        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12073                "registerUidObserver()");
12074        synchronized (this) {
12075            mUidObservers.register(observer, which);
12076        }
12077    }
12078
12079    @Override
12080    public void unregisterUidObserver(IUidObserver observer) {
12081        synchronized (this) {
12082            mUidObservers.unregister(observer);
12083        }
12084    }
12085
12086    @Override
12087    public boolean convertFromTranslucent(IBinder token) {
12088        final long origId = Binder.clearCallingIdentity();
12089        try {
12090            synchronized (this) {
12091                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12092                if (r == null) {
12093                    return false;
12094                }
12095                final boolean translucentChanged = r.changeWindowTranslucency(true);
12096                if (translucentChanged) {
12097                    r.task.stack.releaseBackgroundResources(r);
12098                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12099                }
12100                mWindowManager.setAppFullscreen(token, true);
12101                return translucentChanged;
12102            }
12103        } finally {
12104            Binder.restoreCallingIdentity(origId);
12105        }
12106    }
12107
12108    @Override
12109    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12110        final long origId = Binder.clearCallingIdentity();
12111        try {
12112            synchronized (this) {
12113                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12114                if (r == null) {
12115                    return false;
12116                }
12117                int index = r.task.mActivities.lastIndexOf(r);
12118                if (index > 0) {
12119                    ActivityRecord under = r.task.mActivities.get(index - 1);
12120                    under.returningOptions = options;
12121                }
12122                final boolean translucentChanged = r.changeWindowTranslucency(false);
12123                if (translucentChanged) {
12124                    r.task.stack.convertActivityToTranslucent(r);
12125                }
12126                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12127                mWindowManager.setAppFullscreen(token, false);
12128                return translucentChanged;
12129            }
12130        } finally {
12131            Binder.restoreCallingIdentity(origId);
12132        }
12133    }
12134
12135    @Override
12136    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12137        final long origId = Binder.clearCallingIdentity();
12138        try {
12139            synchronized (this) {
12140                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12141                if (r != null) {
12142                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12143                }
12144            }
12145            return false;
12146        } finally {
12147            Binder.restoreCallingIdentity(origId);
12148        }
12149    }
12150
12151    @Override
12152    public boolean isBackgroundVisibleBehind(IBinder token) {
12153        final long origId = Binder.clearCallingIdentity();
12154        try {
12155            synchronized (this) {
12156                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12157                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12158                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12159                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12160                return visible;
12161            }
12162        } finally {
12163            Binder.restoreCallingIdentity(origId);
12164        }
12165    }
12166
12167    @Override
12168    public ActivityOptions getActivityOptions(IBinder token) {
12169        final long origId = Binder.clearCallingIdentity();
12170        try {
12171            synchronized (this) {
12172                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12173                if (r != null) {
12174                    final ActivityOptions activityOptions = r.pendingOptions;
12175                    r.pendingOptions = null;
12176                    return activityOptions;
12177                }
12178                return null;
12179            }
12180        } finally {
12181            Binder.restoreCallingIdentity(origId);
12182        }
12183    }
12184
12185    @Override
12186    public void setImmersive(IBinder token, boolean immersive) {
12187        synchronized(this) {
12188            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12189            if (r == null) {
12190                throw new IllegalArgumentException();
12191            }
12192            r.immersive = immersive;
12193
12194            // update associated state if we're frontmost
12195            if (r == mFocusedActivity) {
12196                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12197                applyUpdateLockStateLocked(r);
12198            }
12199        }
12200    }
12201
12202    @Override
12203    public boolean isImmersive(IBinder token) {
12204        synchronized (this) {
12205            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12206            if (r == null) {
12207                throw new IllegalArgumentException();
12208            }
12209            return r.immersive;
12210        }
12211    }
12212
12213    @Override
12214    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12215        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12216            throw new UnsupportedOperationException("VR mode not supported on this device!");
12217        }
12218
12219        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12220
12221        ActivityRecord r;
12222        synchronized (this) {
12223            r = ActivityRecord.isInStackLocked(token);
12224        }
12225
12226        if (r == null) {
12227            throw new IllegalArgumentException();
12228        }
12229
12230        int err;
12231        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12232                VrManagerInternal.NO_ERROR) {
12233            return err;
12234        }
12235
12236        synchronized(this) {
12237            r.requestedVrComponent = (enabled) ? packageName : null;
12238
12239            // Update associated state if this activity is currently focused
12240            if (r == mFocusedActivity) {
12241                applyUpdateVrModeLocked(r);
12242            }
12243            return 0;
12244        }
12245    }
12246
12247    @Override
12248    public boolean isVrModePackageEnabled(ComponentName packageName) {
12249        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12250            throw new UnsupportedOperationException("VR mode not supported on this device!");
12251        }
12252
12253        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12254
12255        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12256                VrManagerInternal.NO_ERROR;
12257    }
12258
12259    public boolean isTopActivityImmersive() {
12260        enforceNotIsolatedCaller("startActivity");
12261        synchronized (this) {
12262            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12263            return (r != null) ? r.immersive : false;
12264        }
12265    }
12266
12267    @Override
12268    public boolean isTopOfTask(IBinder token) {
12269        synchronized (this) {
12270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12271            if (r == null) {
12272                throw new IllegalArgumentException();
12273            }
12274            return r.task.getTopActivity() == r;
12275        }
12276    }
12277
12278    public final void enterSafeMode() {
12279        synchronized(this) {
12280            // It only makes sense to do this before the system is ready
12281            // and started launching other packages.
12282            if (!mSystemReady) {
12283                try {
12284                    AppGlobals.getPackageManager().enterSafeMode();
12285                } catch (RemoteException e) {
12286                }
12287            }
12288
12289            mSafeMode = true;
12290        }
12291    }
12292
12293    public final void showSafeModeOverlay() {
12294        View v = LayoutInflater.from(mContext).inflate(
12295                com.android.internal.R.layout.safe_mode, null);
12296        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12297        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12298        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12299        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12300        lp.gravity = Gravity.BOTTOM | Gravity.START;
12301        lp.format = v.getBackground().getOpacity();
12302        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12303                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12304        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12305        ((WindowManager)mContext.getSystemService(
12306                Context.WINDOW_SERVICE)).addView(v, lp);
12307    }
12308
12309    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12310        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12311            return;
12312        }
12313        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12314        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12315        synchronized (stats) {
12316            if (mBatteryStatsService.isOnBattery()) {
12317                mBatteryStatsService.enforceCallingPermission();
12318                int MY_UID = Binder.getCallingUid();
12319                final int uid;
12320                if (sender == null) {
12321                    uid = sourceUid;
12322                } else {
12323                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12324                }
12325                BatteryStatsImpl.Uid.Pkg pkg =
12326                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12327                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12328                pkg.noteWakeupAlarmLocked(tag);
12329            }
12330        }
12331    }
12332
12333    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12334        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12335            return;
12336        }
12337        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12338        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12339        synchronized (stats) {
12340            mBatteryStatsService.enforceCallingPermission();
12341            int MY_UID = Binder.getCallingUid();
12342            final int uid;
12343            if (sender == null) {
12344                uid = sourceUid;
12345            } else {
12346                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12347            }
12348            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12349        }
12350    }
12351
12352    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12353        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12354            return;
12355        }
12356        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12357        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12358        synchronized (stats) {
12359            mBatteryStatsService.enforceCallingPermission();
12360            int MY_UID = Binder.getCallingUid();
12361            final int uid;
12362            if (sender == null) {
12363                uid = sourceUid;
12364            } else {
12365                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12366            }
12367            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12368        }
12369    }
12370
12371    public boolean killPids(int[] pids, String pReason, boolean secure) {
12372        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12373            throw new SecurityException("killPids only available to the system");
12374        }
12375        String reason = (pReason == null) ? "Unknown" : pReason;
12376        // XXX Note: don't acquire main activity lock here, because the window
12377        // manager calls in with its locks held.
12378
12379        boolean killed = false;
12380        synchronized (mPidsSelfLocked) {
12381            int worstType = 0;
12382            for (int i=0; i<pids.length; i++) {
12383                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12384                if (proc != null) {
12385                    int type = proc.setAdj;
12386                    if (type > worstType) {
12387                        worstType = type;
12388                    }
12389                }
12390            }
12391
12392            // If the worst oom_adj is somewhere in the cached proc LRU range,
12393            // then constrain it so we will kill all cached procs.
12394            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12395                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12396                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12397            }
12398
12399            // If this is not a secure call, don't let it kill processes that
12400            // are important.
12401            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12402                worstType = ProcessList.SERVICE_ADJ;
12403            }
12404
12405            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12406            for (int i=0; i<pids.length; i++) {
12407                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12408                if (proc == null) {
12409                    continue;
12410                }
12411                int adj = proc.setAdj;
12412                if (adj >= worstType && !proc.killedByAm) {
12413                    proc.kill(reason, true);
12414                    killed = true;
12415                }
12416            }
12417        }
12418        return killed;
12419    }
12420
12421    @Override
12422    public void killUid(int appId, int userId, String reason) {
12423        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12424        synchronized (this) {
12425            final long identity = Binder.clearCallingIdentity();
12426            try {
12427                killPackageProcessesLocked(null, appId, userId,
12428                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12429                        reason != null ? reason : "kill uid");
12430            } finally {
12431                Binder.restoreCallingIdentity(identity);
12432            }
12433        }
12434    }
12435
12436    @Override
12437    public boolean killProcessesBelowForeground(String reason) {
12438        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12439            throw new SecurityException("killProcessesBelowForeground() only available to system");
12440        }
12441
12442        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12443    }
12444
12445    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12446        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12447            throw new SecurityException("killProcessesBelowAdj() only available to system");
12448        }
12449
12450        boolean killed = false;
12451        synchronized (mPidsSelfLocked) {
12452            final int size = mPidsSelfLocked.size();
12453            for (int i = 0; i < size; i++) {
12454                final int pid = mPidsSelfLocked.keyAt(i);
12455                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12456                if (proc == null) continue;
12457
12458                final int adj = proc.setAdj;
12459                if (adj > belowAdj && !proc.killedByAm) {
12460                    proc.kill(reason, true);
12461                    killed = true;
12462                }
12463            }
12464        }
12465        return killed;
12466    }
12467
12468    @Override
12469    public void hang(final IBinder who, boolean allowRestart) {
12470        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12471                != PackageManager.PERMISSION_GRANTED) {
12472            throw new SecurityException("Requires permission "
12473                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12474        }
12475
12476        final IBinder.DeathRecipient death = new DeathRecipient() {
12477            @Override
12478            public void binderDied() {
12479                synchronized (this) {
12480                    notifyAll();
12481                }
12482            }
12483        };
12484
12485        try {
12486            who.linkToDeath(death, 0);
12487        } catch (RemoteException e) {
12488            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12489            return;
12490        }
12491
12492        synchronized (this) {
12493            Watchdog.getInstance().setAllowRestart(allowRestart);
12494            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12495            synchronized (death) {
12496                while (who.isBinderAlive()) {
12497                    try {
12498                        death.wait();
12499                    } catch (InterruptedException e) {
12500                    }
12501                }
12502            }
12503            Watchdog.getInstance().setAllowRestart(true);
12504        }
12505    }
12506
12507    @Override
12508    public void restart() {
12509        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12510                != PackageManager.PERMISSION_GRANTED) {
12511            throw new SecurityException("Requires permission "
12512                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12513        }
12514
12515        Log.i(TAG, "Sending shutdown broadcast...");
12516
12517        BroadcastReceiver br = new BroadcastReceiver() {
12518            @Override public void onReceive(Context context, Intent intent) {
12519                // Now the broadcast is done, finish up the low-level shutdown.
12520                Log.i(TAG, "Shutting down activity manager...");
12521                shutdown(10000);
12522                Log.i(TAG, "Shutdown complete, restarting!");
12523                Process.killProcess(Process.myPid());
12524                System.exit(10);
12525            }
12526        };
12527
12528        // First send the high-level shut down broadcast.
12529        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12530        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12531        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12532        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12533        mContext.sendOrderedBroadcastAsUser(intent,
12534                UserHandle.ALL, null, br, mHandler, 0, null, null);
12535        */
12536        br.onReceive(mContext, intent);
12537    }
12538
12539    private long getLowRamTimeSinceIdle(long now) {
12540        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12541    }
12542
12543    @Override
12544    public void performIdleMaintenance() {
12545        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12546                != PackageManager.PERMISSION_GRANTED) {
12547            throw new SecurityException("Requires permission "
12548                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12549        }
12550
12551        synchronized (this) {
12552            final long now = SystemClock.uptimeMillis();
12553            final long timeSinceLastIdle = now - mLastIdleTime;
12554            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12555            mLastIdleTime = now;
12556            mLowRamTimeSinceLastIdle = 0;
12557            if (mLowRamStartTime != 0) {
12558                mLowRamStartTime = now;
12559            }
12560
12561            StringBuilder sb = new StringBuilder(128);
12562            sb.append("Idle maintenance over ");
12563            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12564            sb.append(" low RAM for ");
12565            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12566            Slog.i(TAG, sb.toString());
12567
12568            // If at least 1/3 of our time since the last idle period has been spent
12569            // with RAM low, then we want to kill processes.
12570            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12571
12572            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12573                ProcessRecord proc = mLruProcesses.get(i);
12574                if (proc.notCachedSinceIdle) {
12575                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12576                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12577                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12578                        if (doKilling && proc.initialIdlePss != 0
12579                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12580                            sb = new StringBuilder(128);
12581                            sb.append("Kill");
12582                            sb.append(proc.processName);
12583                            sb.append(" in idle maint: pss=");
12584                            sb.append(proc.lastPss);
12585                            sb.append(", swapPss=");
12586                            sb.append(proc.lastSwapPss);
12587                            sb.append(", initialPss=");
12588                            sb.append(proc.initialIdlePss);
12589                            sb.append(", period=");
12590                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12591                            sb.append(", lowRamPeriod=");
12592                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12593                            Slog.wtfQuiet(TAG, sb.toString());
12594                            proc.kill("idle maint (pss " + proc.lastPss
12595                                    + " from " + proc.initialIdlePss + ")", true);
12596                        }
12597                    }
12598                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12599                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12600                    proc.notCachedSinceIdle = true;
12601                    proc.initialIdlePss = 0;
12602                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12603                            mTestPssMode, isSleeping(), now);
12604                }
12605            }
12606
12607            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12608            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12609        }
12610    }
12611
12612    private void retrieveSettings() {
12613        final ContentResolver resolver = mContext.getContentResolver();
12614        final boolean freeformWindowManagement =
12615                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12616                        || Settings.Global.getInt(
12617                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12618        final boolean supportsPictureInPicture =
12619                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12620
12621        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12622        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12623        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12624        final boolean alwaysFinishActivities =
12625                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12626        final boolean lenientBackgroundCheck =
12627                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12628        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12629        final boolean forceResizable = Settings.Global.getInt(
12630                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12631        // Transfer any global setting for forcing RTL layout, into a System Property
12632        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12633
12634        final Configuration configuration = new Configuration();
12635        Settings.System.getConfiguration(resolver, configuration);
12636        if (forceRtl) {
12637            // This will take care of setting the correct layout direction flags
12638            configuration.setLayoutDirection(configuration.locale);
12639        }
12640
12641        synchronized (this) {
12642            mDebugApp = mOrigDebugApp = debugApp;
12643            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12644            mAlwaysFinishActivities = alwaysFinishActivities;
12645            mLenientBackgroundCheck = lenientBackgroundCheck;
12646            mForceResizableActivities = forceResizable;
12647            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12648            if (supportsMultiWindow || forceResizable) {
12649                mSupportsMultiWindow = true;
12650                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12651                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12652            } else {
12653                mSupportsMultiWindow = false;
12654                mSupportsFreeformWindowManagement = false;
12655                mSupportsPictureInPicture = false;
12656            }
12657            // This happens before any activities are started, so we can
12658            // change mConfiguration in-place.
12659            updateConfigurationLocked(configuration, null, true);
12660            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12661                    "Initial config: " + mConfiguration);
12662
12663            // Load resources only after the current configuration has been set.
12664            final Resources res = mContext.getResources();
12665            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12666            mThumbnailWidth = res.getDimensionPixelSize(
12667                    com.android.internal.R.dimen.thumbnail_width);
12668            mThumbnailHeight = res.getDimensionPixelSize(
12669                    com.android.internal.R.dimen.thumbnail_height);
12670            mFullscreenThumbnailScale = res.getFraction(
12671                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12672            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12673                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12674            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12675                    com.android.internal.R.string.config_appsNotReportingCrashes));
12676        }
12677    }
12678
12679    public boolean testIsSystemReady() {
12680        // no need to synchronize(this) just to read & return the value
12681        return mSystemReady;
12682    }
12683
12684    public void systemReady(final Runnable goingCallback) {
12685        synchronized(this) {
12686            if (mSystemReady) {
12687                // If we're done calling all the receivers, run the next "boot phase" passed in
12688                // by the SystemServer
12689                if (goingCallback != null) {
12690                    goingCallback.run();
12691                }
12692                return;
12693            }
12694
12695            mLocalDeviceIdleController
12696                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12697
12698            // Make sure we have the current profile info, since it is needed for security checks.
12699            mUserController.onSystemReady();
12700            mRecentTasks.onSystemReadyLocked();
12701            mAppOpsService.systemReady();
12702            mSystemReady = true;
12703        }
12704
12705        ArrayList<ProcessRecord> procsToKill = null;
12706        synchronized(mPidsSelfLocked) {
12707            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12708                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12709                if (!isAllowedWhileBooting(proc.info)){
12710                    if (procsToKill == null) {
12711                        procsToKill = new ArrayList<ProcessRecord>();
12712                    }
12713                    procsToKill.add(proc);
12714                }
12715            }
12716        }
12717
12718        synchronized(this) {
12719            if (procsToKill != null) {
12720                for (int i=procsToKill.size()-1; i>=0; i--) {
12721                    ProcessRecord proc = procsToKill.get(i);
12722                    Slog.i(TAG, "Removing system update proc: " + proc);
12723                    removeProcessLocked(proc, true, false, "system update done");
12724                }
12725            }
12726
12727            // Now that we have cleaned up any update processes, we
12728            // are ready to start launching real processes and know that
12729            // we won't trample on them any more.
12730            mProcessesReady = true;
12731        }
12732
12733        Slog.i(TAG, "System now ready");
12734        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12735            SystemClock.uptimeMillis());
12736
12737        synchronized(this) {
12738            // Make sure we have no pre-ready processes sitting around.
12739
12740            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12741                ResolveInfo ri = mContext.getPackageManager()
12742                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12743                                STOCK_PM_FLAGS);
12744                CharSequence errorMsg = null;
12745                if (ri != null) {
12746                    ActivityInfo ai = ri.activityInfo;
12747                    ApplicationInfo app = ai.applicationInfo;
12748                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12749                        mTopAction = Intent.ACTION_FACTORY_TEST;
12750                        mTopData = null;
12751                        mTopComponent = new ComponentName(app.packageName,
12752                                ai.name);
12753                    } else {
12754                        errorMsg = mContext.getResources().getText(
12755                                com.android.internal.R.string.factorytest_not_system);
12756                    }
12757                } else {
12758                    errorMsg = mContext.getResources().getText(
12759                            com.android.internal.R.string.factorytest_no_action);
12760                }
12761                if (errorMsg != null) {
12762                    mTopAction = null;
12763                    mTopData = null;
12764                    mTopComponent = null;
12765                    Message msg = Message.obtain();
12766                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12767                    msg.getData().putCharSequence("msg", errorMsg);
12768                    mUiHandler.sendMessage(msg);
12769                }
12770            }
12771        }
12772
12773        retrieveSettings();
12774        final int currentUserId;
12775        synchronized (this) {
12776            currentUserId = mUserController.getCurrentUserIdLocked();
12777            readGrantedUriPermissionsLocked();
12778        }
12779
12780        if (goingCallback != null) goingCallback.run();
12781
12782        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12783                Integer.toString(currentUserId), currentUserId);
12784        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12785                Integer.toString(currentUserId), currentUserId);
12786        mSystemServiceManager.startUser(currentUserId);
12787
12788        synchronized (this) {
12789            // Only start up encryption-aware persistent apps; once user is
12790            // unlocked we'll come back around and start unaware apps
12791            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12792
12793            // Start up initial activity.
12794            mBooting = true;
12795            // Enable home activity for system user, so that the system can always boot
12796            if (UserManager.isSplitSystemUser()) {
12797                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12798                try {
12799                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12800                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12801                            UserHandle.USER_SYSTEM);
12802                } catch (RemoteException e) {
12803                    throw e.rethrowAsRuntimeException();
12804                }
12805            }
12806            startHomeActivityLocked(currentUserId, "systemReady");
12807
12808            try {
12809                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12810                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12811                            + " data partition or your device will be unstable.");
12812                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12813                }
12814            } catch (RemoteException e) {
12815            }
12816
12817            if (!Build.isBuildConsistent()) {
12818                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12819                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12820            }
12821
12822            long ident = Binder.clearCallingIdentity();
12823            try {
12824                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12825                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12826                        | Intent.FLAG_RECEIVER_FOREGROUND);
12827                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12828                broadcastIntentLocked(null, null, intent,
12829                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12830                        null, false, false, MY_PID, Process.SYSTEM_UID,
12831                        currentUserId);
12832                intent = new Intent(Intent.ACTION_USER_STARTING);
12833                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12834                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12835                broadcastIntentLocked(null, null, intent,
12836                        null, new IIntentReceiver.Stub() {
12837                            @Override
12838                            public void performReceive(Intent intent, int resultCode, String data,
12839                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12840                                    throws RemoteException {
12841                            }
12842                        }, 0, null, null,
12843                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12844                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12845            } catch (Throwable t) {
12846                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12847            } finally {
12848                Binder.restoreCallingIdentity(ident);
12849            }
12850            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12851            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12852        }
12853    }
12854
12855    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12856        synchronized (this) {
12857            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12858        }
12859    }
12860
12861    void skipCurrentReceiverLocked(ProcessRecord app) {
12862        for (BroadcastQueue queue : mBroadcastQueues) {
12863            queue.skipCurrentReceiverLocked(app);
12864        }
12865    }
12866
12867    /**
12868     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12869     * The application process will exit immediately after this call returns.
12870     * @param app object of the crashing app, null for the system server
12871     * @param crashInfo describing the exception
12872     */
12873    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12874        ProcessRecord r = findAppProcess(app, "Crash");
12875        final String processName = app == null ? "system_server"
12876                : (r == null ? "unknown" : r.processName);
12877
12878        handleApplicationCrashInner("crash", r, processName, crashInfo);
12879    }
12880
12881    /* Native crash reporting uses this inner version because it needs to be somewhat
12882     * decoupled from the AM-managed cleanup lifecycle
12883     */
12884    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12885            ApplicationErrorReport.CrashInfo crashInfo) {
12886        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12887                UserHandle.getUserId(Binder.getCallingUid()), processName,
12888                r == null ? -1 : r.info.flags,
12889                crashInfo.exceptionClassName,
12890                crashInfo.exceptionMessage,
12891                crashInfo.throwFileName,
12892                crashInfo.throwLineNumber);
12893
12894        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12895
12896        mAppErrors.crashApplication(r, crashInfo);
12897    }
12898
12899    public void handleApplicationStrictModeViolation(
12900            IBinder app,
12901            int violationMask,
12902            StrictMode.ViolationInfo info) {
12903        ProcessRecord r = findAppProcess(app, "StrictMode");
12904        if (r == null) {
12905            return;
12906        }
12907
12908        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12909            Integer stackFingerprint = info.hashCode();
12910            boolean logIt = true;
12911            synchronized (mAlreadyLoggedViolatedStacks) {
12912                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12913                    logIt = false;
12914                    // TODO: sub-sample into EventLog for these, with
12915                    // the info.durationMillis?  Then we'd get
12916                    // the relative pain numbers, without logging all
12917                    // the stack traces repeatedly.  We'd want to do
12918                    // likewise in the client code, which also does
12919                    // dup suppression, before the Binder call.
12920                } else {
12921                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12922                        mAlreadyLoggedViolatedStacks.clear();
12923                    }
12924                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12925                }
12926            }
12927            if (logIt) {
12928                logStrictModeViolationToDropBox(r, info);
12929            }
12930        }
12931
12932        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12933            AppErrorResult result = new AppErrorResult();
12934            synchronized (this) {
12935                final long origId = Binder.clearCallingIdentity();
12936
12937                Message msg = Message.obtain();
12938                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12939                HashMap<String, Object> data = new HashMap<String, Object>();
12940                data.put("result", result);
12941                data.put("app", r);
12942                data.put("violationMask", violationMask);
12943                data.put("info", info);
12944                msg.obj = data;
12945                mUiHandler.sendMessage(msg);
12946
12947                Binder.restoreCallingIdentity(origId);
12948            }
12949            int res = result.get();
12950            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12951        }
12952    }
12953
12954    // Depending on the policy in effect, there could be a bunch of
12955    // these in quick succession so we try to batch these together to
12956    // minimize disk writes, number of dropbox entries, and maximize
12957    // compression, by having more fewer, larger records.
12958    private void logStrictModeViolationToDropBox(
12959            ProcessRecord process,
12960            StrictMode.ViolationInfo info) {
12961        if (info == null) {
12962            return;
12963        }
12964        final boolean isSystemApp = process == null ||
12965                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12966                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12967        final String processName = process == null ? "unknown" : process.processName;
12968        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12969        final DropBoxManager dbox = (DropBoxManager)
12970                mContext.getSystemService(Context.DROPBOX_SERVICE);
12971
12972        // Exit early if the dropbox isn't configured to accept this report type.
12973        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12974
12975        boolean bufferWasEmpty;
12976        boolean needsFlush;
12977        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12978        synchronized (sb) {
12979            bufferWasEmpty = sb.length() == 0;
12980            appendDropBoxProcessHeaders(process, processName, sb);
12981            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12982            sb.append("System-App: ").append(isSystemApp).append("\n");
12983            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12984            if (info.violationNumThisLoop != 0) {
12985                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12986            }
12987            if (info.numAnimationsRunning != 0) {
12988                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12989            }
12990            if (info.broadcastIntentAction != null) {
12991                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12992            }
12993            if (info.durationMillis != -1) {
12994                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12995            }
12996            if (info.numInstances != -1) {
12997                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12998            }
12999            if (info.tags != null) {
13000                for (String tag : info.tags) {
13001                    sb.append("Span-Tag: ").append(tag).append("\n");
13002                }
13003            }
13004            sb.append("\n");
13005            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13006                sb.append(info.crashInfo.stackTrace);
13007                sb.append("\n");
13008            }
13009            if (info.message != null) {
13010                sb.append(info.message);
13011                sb.append("\n");
13012            }
13013
13014            // Only buffer up to ~64k.  Various logging bits truncate
13015            // things at 128k.
13016            needsFlush = (sb.length() > 64 * 1024);
13017        }
13018
13019        // Flush immediately if the buffer's grown too large, or this
13020        // is a non-system app.  Non-system apps are isolated with a
13021        // different tag & policy and not batched.
13022        //
13023        // Batching is useful during internal testing with
13024        // StrictMode settings turned up high.  Without batching,
13025        // thousands of separate files could be created on boot.
13026        if (!isSystemApp || needsFlush) {
13027            new Thread("Error dump: " + dropboxTag) {
13028                @Override
13029                public void run() {
13030                    String report;
13031                    synchronized (sb) {
13032                        report = sb.toString();
13033                        sb.delete(0, sb.length());
13034                        sb.trimToSize();
13035                    }
13036                    if (report.length() != 0) {
13037                        dbox.addText(dropboxTag, report);
13038                    }
13039                }
13040            }.start();
13041            return;
13042        }
13043
13044        // System app batching:
13045        if (!bufferWasEmpty) {
13046            // An existing dropbox-writing thread is outstanding, so
13047            // we don't need to start it up.  The existing thread will
13048            // catch the buffer appends we just did.
13049            return;
13050        }
13051
13052        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13053        // (After this point, we shouldn't access AMS internal data structures.)
13054        new Thread("Error dump: " + dropboxTag) {
13055            @Override
13056            public void run() {
13057                // 5 second sleep to let stacks arrive and be batched together
13058                try {
13059                    Thread.sleep(5000);  // 5 seconds
13060                } catch (InterruptedException e) {}
13061
13062                String errorReport;
13063                synchronized (mStrictModeBuffer) {
13064                    errorReport = mStrictModeBuffer.toString();
13065                    if (errorReport.length() == 0) {
13066                        return;
13067                    }
13068                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13069                    mStrictModeBuffer.trimToSize();
13070                }
13071                dbox.addText(dropboxTag, errorReport);
13072            }
13073        }.start();
13074    }
13075
13076    /**
13077     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13078     * @param app object of the crashing app, null for the system server
13079     * @param tag reported by the caller
13080     * @param system whether this wtf is coming from the system
13081     * @param crashInfo describing the context of the error
13082     * @return true if the process should exit immediately (WTF is fatal)
13083     */
13084    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13085            final ApplicationErrorReport.CrashInfo crashInfo) {
13086        final int callingUid = Binder.getCallingUid();
13087        final int callingPid = Binder.getCallingPid();
13088
13089        if (system) {
13090            // If this is coming from the system, we could very well have low-level
13091            // system locks held, so we want to do this all asynchronously.  And we
13092            // never want this to become fatal, so there is that too.
13093            mHandler.post(new Runnable() {
13094                @Override public void run() {
13095                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13096                }
13097            });
13098            return false;
13099        }
13100
13101        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13102                crashInfo);
13103
13104        if (r != null && r.pid != Process.myPid() &&
13105                Settings.Global.getInt(mContext.getContentResolver(),
13106                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13107            mAppErrors.crashApplication(r, crashInfo);
13108            return true;
13109        } else {
13110            return false;
13111        }
13112    }
13113
13114    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13115            final ApplicationErrorReport.CrashInfo crashInfo) {
13116        final ProcessRecord r = findAppProcess(app, "WTF");
13117        final String processName = app == null ? "system_server"
13118                : (r == null ? "unknown" : r.processName);
13119
13120        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13121                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13122
13123        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13124
13125        return r;
13126    }
13127
13128    /**
13129     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13130     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13131     */
13132    private ProcessRecord findAppProcess(IBinder app, String reason) {
13133        if (app == null) {
13134            return null;
13135        }
13136
13137        synchronized (this) {
13138            final int NP = mProcessNames.getMap().size();
13139            for (int ip=0; ip<NP; ip++) {
13140                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13141                final int NA = apps.size();
13142                for (int ia=0; ia<NA; ia++) {
13143                    ProcessRecord p = apps.valueAt(ia);
13144                    if (p.thread != null && p.thread.asBinder() == app) {
13145                        return p;
13146                    }
13147                }
13148            }
13149
13150            Slog.w(TAG, "Can't find mystery application for " + reason
13151                    + " from pid=" + Binder.getCallingPid()
13152                    + " uid=" + Binder.getCallingUid() + ": " + app);
13153            return null;
13154        }
13155    }
13156
13157    /**
13158     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13159     * to append various headers to the dropbox log text.
13160     */
13161    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13162            StringBuilder sb) {
13163        // Watchdog thread ends up invoking this function (with
13164        // a null ProcessRecord) to add the stack file to dropbox.
13165        // Do not acquire a lock on this (am) in such cases, as it
13166        // could cause a potential deadlock, if and when watchdog
13167        // is invoked due to unavailability of lock on am and it
13168        // would prevent watchdog from killing system_server.
13169        if (process == null) {
13170            sb.append("Process: ").append(processName).append("\n");
13171            return;
13172        }
13173        // Note: ProcessRecord 'process' is guarded by the service
13174        // instance.  (notably process.pkgList, which could otherwise change
13175        // concurrently during execution of this method)
13176        synchronized (this) {
13177            sb.append("Process: ").append(processName).append("\n");
13178            int flags = process.info.flags;
13179            IPackageManager pm = AppGlobals.getPackageManager();
13180            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13181            for (int ip=0; ip<process.pkgList.size(); ip++) {
13182                String pkg = process.pkgList.keyAt(ip);
13183                sb.append("Package: ").append(pkg);
13184                try {
13185                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13186                    if (pi != null) {
13187                        sb.append(" v").append(pi.versionCode);
13188                        if (pi.versionName != null) {
13189                            sb.append(" (").append(pi.versionName).append(")");
13190                        }
13191                    }
13192                } catch (RemoteException e) {
13193                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13194                }
13195                sb.append("\n");
13196            }
13197        }
13198    }
13199
13200    private static String processClass(ProcessRecord process) {
13201        if (process == null || process.pid == MY_PID) {
13202            return "system_server";
13203        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13204            return "system_app";
13205        } else {
13206            return "data_app";
13207        }
13208    }
13209
13210    private volatile long mWtfClusterStart;
13211    private volatile int mWtfClusterCount;
13212
13213    /**
13214     * Write a description of an error (crash, WTF, ANR) to the drop box.
13215     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13216     * @param process which caused the error, null means the system server
13217     * @param activity which triggered the error, null if unknown
13218     * @param parent activity related to the error, null if unknown
13219     * @param subject line related to the error, null if absent
13220     * @param report in long form describing the error, null if absent
13221     * @param logFile to include in the report, null if none
13222     * @param crashInfo giving an application stack trace, null if absent
13223     */
13224    public void addErrorToDropBox(String eventType,
13225            ProcessRecord process, String processName, ActivityRecord activity,
13226            ActivityRecord parent, String subject,
13227            final String report, final File logFile,
13228            final ApplicationErrorReport.CrashInfo crashInfo) {
13229        // NOTE -- this must never acquire the ActivityManagerService lock,
13230        // otherwise the watchdog may be prevented from resetting the system.
13231
13232        final String dropboxTag = processClass(process) + "_" + eventType;
13233        final DropBoxManager dbox = (DropBoxManager)
13234                mContext.getSystemService(Context.DROPBOX_SERVICE);
13235
13236        // Exit early if the dropbox isn't configured to accept this report type.
13237        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13238
13239        // Rate-limit how often we're willing to do the heavy lifting below to
13240        // collect and record logs; currently 5 logs per 10 second period.
13241        final long now = SystemClock.elapsedRealtime();
13242        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13243            mWtfClusterStart = now;
13244            mWtfClusterCount = 1;
13245        } else {
13246            if (mWtfClusterCount++ >= 5) return;
13247        }
13248
13249        final StringBuilder sb = new StringBuilder(1024);
13250        appendDropBoxProcessHeaders(process, processName, sb);
13251        if (process != null) {
13252            sb.append("Foreground: ")
13253                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13254                    .append("\n");
13255        }
13256        if (activity != null) {
13257            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13258        }
13259        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13260            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13261        }
13262        if (parent != null && parent != activity) {
13263            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13264        }
13265        if (subject != null) {
13266            sb.append("Subject: ").append(subject).append("\n");
13267        }
13268        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13269        if (Debug.isDebuggerConnected()) {
13270            sb.append("Debugger: Connected\n");
13271        }
13272        sb.append("\n");
13273
13274        // Do the rest in a worker thread to avoid blocking the caller on I/O
13275        // (After this point, we shouldn't access AMS internal data structures.)
13276        Thread worker = new Thread("Error dump: " + dropboxTag) {
13277            @Override
13278            public void run() {
13279                if (report != null) {
13280                    sb.append(report);
13281                }
13282                if (logFile != null) {
13283                    try {
13284                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13285                                    "\n\n[[TRUNCATED]]"));
13286                    } catch (IOException e) {
13287                        Slog.e(TAG, "Error reading " + logFile, e);
13288                    }
13289                }
13290                if (crashInfo != null && crashInfo.stackTrace != null) {
13291                    sb.append(crashInfo.stackTrace);
13292                }
13293
13294                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13295                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13296                if (lines > 0) {
13297                    sb.append("\n");
13298
13299                    // Merge several logcat streams, and take the last N lines
13300                    InputStreamReader input = null;
13301                    try {
13302                        java.lang.Process logcat = new ProcessBuilder(
13303                                "/system/bin/timeout", "-k", "15s", "10s",
13304                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13305                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13306                                        .redirectErrorStream(true).start();
13307
13308                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13309                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13310                        input = new InputStreamReader(logcat.getInputStream());
13311
13312                        int num;
13313                        char[] buf = new char[8192];
13314                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13315                    } catch (IOException e) {
13316                        Slog.e(TAG, "Error running logcat", e);
13317                    } finally {
13318                        if (input != null) try { input.close(); } catch (IOException e) {}
13319                    }
13320                }
13321
13322                dbox.addText(dropboxTag, sb.toString());
13323            }
13324        };
13325
13326        if (process == null) {
13327            // If process is null, we are being called from some internal code
13328            // and may be about to die -- run this synchronously.
13329            worker.run();
13330        } else {
13331            worker.start();
13332        }
13333    }
13334
13335    @Override
13336    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13337        enforceNotIsolatedCaller("getProcessesInErrorState");
13338        // assume our apps are happy - lazy create the list
13339        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13340
13341        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13342                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13343        int userId = UserHandle.getUserId(Binder.getCallingUid());
13344
13345        synchronized (this) {
13346
13347            // iterate across all processes
13348            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13349                ProcessRecord app = mLruProcesses.get(i);
13350                if (!allUsers && app.userId != userId) {
13351                    continue;
13352                }
13353                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13354                    // This one's in trouble, so we'll generate a report for it
13355                    // crashes are higher priority (in case there's a crash *and* an anr)
13356                    ActivityManager.ProcessErrorStateInfo report = null;
13357                    if (app.crashing) {
13358                        report = app.crashingReport;
13359                    } else if (app.notResponding) {
13360                        report = app.notRespondingReport;
13361                    }
13362
13363                    if (report != null) {
13364                        if (errList == null) {
13365                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13366                        }
13367                        errList.add(report);
13368                    } else {
13369                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13370                                " crashing = " + app.crashing +
13371                                " notResponding = " + app.notResponding);
13372                    }
13373                }
13374            }
13375        }
13376
13377        return errList;
13378    }
13379
13380    static int procStateToImportance(int procState, int memAdj,
13381            ActivityManager.RunningAppProcessInfo currApp) {
13382        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13383        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13384            currApp.lru = memAdj;
13385        } else {
13386            currApp.lru = 0;
13387        }
13388        return imp;
13389    }
13390
13391    private void fillInProcMemInfo(ProcessRecord app,
13392            ActivityManager.RunningAppProcessInfo outInfo) {
13393        outInfo.pid = app.pid;
13394        outInfo.uid = app.info.uid;
13395        if (mHeavyWeightProcess == app) {
13396            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13397        }
13398        if (app.persistent) {
13399            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13400        }
13401        if (app.activities.size() > 0) {
13402            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13403        }
13404        outInfo.lastTrimLevel = app.trimMemoryLevel;
13405        int adj = app.curAdj;
13406        int procState = app.curProcState;
13407        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13408        outInfo.importanceReasonCode = app.adjTypeCode;
13409        outInfo.processState = app.curProcState;
13410    }
13411
13412    @Override
13413    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13414        enforceNotIsolatedCaller("getRunningAppProcesses");
13415
13416        final int callingUid = Binder.getCallingUid();
13417
13418        // Lazy instantiation of list
13419        List<ActivityManager.RunningAppProcessInfo> runList = null;
13420        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13421                callingUid) == PackageManager.PERMISSION_GRANTED;
13422        final int userId = UserHandle.getUserId(callingUid);
13423        final boolean allUids = isGetTasksAllowed(
13424                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13425
13426        synchronized (this) {
13427            // Iterate across all processes
13428            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13429                ProcessRecord app = mLruProcesses.get(i);
13430                if ((!allUsers && app.userId != userId)
13431                        || (!allUids && app.uid != callingUid)) {
13432                    continue;
13433                }
13434                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13435                    // Generate process state info for running application
13436                    ActivityManager.RunningAppProcessInfo currApp =
13437                        new ActivityManager.RunningAppProcessInfo(app.processName,
13438                                app.pid, app.getPackageList());
13439                    fillInProcMemInfo(app, currApp);
13440                    if (app.adjSource instanceof ProcessRecord) {
13441                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13442                        currApp.importanceReasonImportance =
13443                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13444                                        app.adjSourceProcState);
13445                    } else if (app.adjSource instanceof ActivityRecord) {
13446                        ActivityRecord r = (ActivityRecord)app.adjSource;
13447                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13448                    }
13449                    if (app.adjTarget instanceof ComponentName) {
13450                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13451                    }
13452                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13453                    //        + " lru=" + currApp.lru);
13454                    if (runList == null) {
13455                        runList = new ArrayList<>();
13456                    }
13457                    runList.add(currApp);
13458                }
13459            }
13460        }
13461        return runList;
13462    }
13463
13464    @Override
13465    public List<ApplicationInfo> getRunningExternalApplications() {
13466        enforceNotIsolatedCaller("getRunningExternalApplications");
13467        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13468        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13469        if (runningApps != null && runningApps.size() > 0) {
13470            Set<String> extList = new HashSet<String>();
13471            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13472                if (app.pkgList != null) {
13473                    for (String pkg : app.pkgList) {
13474                        extList.add(pkg);
13475                    }
13476                }
13477            }
13478            IPackageManager pm = AppGlobals.getPackageManager();
13479            for (String pkg : extList) {
13480                try {
13481                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13482                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13483                        retList.add(info);
13484                    }
13485                } catch (RemoteException e) {
13486                }
13487            }
13488        }
13489        return retList;
13490    }
13491
13492    @Override
13493    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13494        enforceNotIsolatedCaller("getMyMemoryState");
13495        synchronized (this) {
13496            ProcessRecord proc;
13497            synchronized (mPidsSelfLocked) {
13498                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13499            }
13500            fillInProcMemInfo(proc, outInfo);
13501        }
13502    }
13503
13504    @Override
13505    public int getMemoryTrimLevel() {
13506        enforceNotIsolatedCaller("getMyMemoryState");
13507        synchronized (this) {
13508            return mLastMemoryLevel;
13509        }
13510    }
13511
13512    @Override
13513    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13514            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13515        (new ActivityManagerShellCommand(this, false)).exec(
13516                this, in, out, err, args, resultReceiver);
13517    }
13518
13519    @Override
13520    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13521        if (checkCallingPermission(android.Manifest.permission.DUMP)
13522                != PackageManager.PERMISSION_GRANTED) {
13523            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13524                    + Binder.getCallingPid()
13525                    + ", uid=" + Binder.getCallingUid()
13526                    + " without permission "
13527                    + android.Manifest.permission.DUMP);
13528            return;
13529        }
13530
13531        boolean dumpAll = false;
13532        boolean dumpClient = false;
13533        String dumpPackage = null;
13534
13535        int opti = 0;
13536        while (opti < args.length) {
13537            String opt = args[opti];
13538            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13539                break;
13540            }
13541            opti++;
13542            if ("-a".equals(opt)) {
13543                dumpAll = true;
13544            } else if ("-c".equals(opt)) {
13545                dumpClient = true;
13546            } else if ("-p".equals(opt)) {
13547                if (opti < args.length) {
13548                    dumpPackage = args[opti];
13549                    opti++;
13550                } else {
13551                    pw.println("Error: -p option requires package argument");
13552                    return;
13553                }
13554                dumpClient = true;
13555            } else if ("-h".equals(opt)) {
13556                ActivityManagerShellCommand.dumpHelp(pw, true);
13557                return;
13558            } else {
13559                pw.println("Unknown argument: " + opt + "; use -h for help");
13560            }
13561        }
13562
13563        long origId = Binder.clearCallingIdentity();
13564        boolean more = false;
13565        // Is the caller requesting to dump a particular piece of data?
13566        if (opti < args.length) {
13567            String cmd = args[opti];
13568            opti++;
13569            if ("activities".equals(cmd) || "a".equals(cmd)) {
13570                synchronized (this) {
13571                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13572                }
13573            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13574                synchronized (this) {
13575                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13576                }
13577            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13578                String[] newArgs;
13579                String name;
13580                if (opti >= args.length) {
13581                    name = null;
13582                    newArgs = EMPTY_STRING_ARRAY;
13583                } else {
13584                    dumpPackage = args[opti];
13585                    opti++;
13586                    newArgs = new String[args.length - opti];
13587                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13588                            args.length - opti);
13589                }
13590                synchronized (this) {
13591                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13592                }
13593            } else if ("intents".equals(cmd) || "i".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                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13608                }
13609            } else if ("processes".equals(cmd) || "p".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                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13624                }
13625            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13626                synchronized (this) {
13627                    dumpOomLocked(fd, pw, args, opti, true);
13628                }
13629            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13630                synchronized (this) {
13631                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13632                }
13633            } else if ("provider".equals(cmd)) {
13634                String[] newArgs;
13635                String name;
13636                if (opti >= args.length) {
13637                    name = null;
13638                    newArgs = EMPTY_STRING_ARRAY;
13639                } else {
13640                    name = args[opti];
13641                    opti++;
13642                    newArgs = new String[args.length - opti];
13643                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13644                }
13645                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13646                    pw.println("No providers match: " + name);
13647                    pw.println("Use -h for help.");
13648                }
13649            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13650                synchronized (this) {
13651                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13652                }
13653            } else if ("service".equals(cmd)) {
13654                String[] newArgs;
13655                String name;
13656                if (opti >= args.length) {
13657                    name = null;
13658                    newArgs = EMPTY_STRING_ARRAY;
13659                } else {
13660                    name = args[opti];
13661                    opti++;
13662                    newArgs = new String[args.length - opti];
13663                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13664                            args.length - opti);
13665                }
13666                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13667                    pw.println("No services match: " + name);
13668                    pw.println("Use -h for help.");
13669                }
13670            } else if ("package".equals(cmd)) {
13671                String[] newArgs;
13672                if (opti >= args.length) {
13673                    pw.println("package: no package name specified");
13674                    pw.println("Use -h for help.");
13675                } else {
13676                    dumpPackage = 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                    args = newArgs;
13682                    opti = 0;
13683                    more = true;
13684                }
13685            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13686                synchronized (this) {
13687                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13688                }
13689            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13690                synchronized (this) {
13691                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13692                }
13693            } else if ("locks".equals(cmd)) {
13694                LockGuard.dump(fd, pw, args);
13695            } else {
13696                // Dumping a single activity?
13697                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13698                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13699                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13700                    if (res < 0) {
13701                        pw.println("Bad activity command, or no activities match: " + cmd);
13702                        pw.println("Use -h for help.");
13703                    }
13704                }
13705            }
13706            if (!more) {
13707                Binder.restoreCallingIdentity(origId);
13708                return;
13709            }
13710        }
13711
13712        // No piece of data specified, dump everything.
13713        synchronized (this) {
13714            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13715            pw.println();
13716            if (dumpAll) {
13717                pw.println("-------------------------------------------------------------------------------");
13718            }
13719            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13720            pw.println();
13721            if (dumpAll) {
13722                pw.println("-------------------------------------------------------------------------------");
13723            }
13724            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13725            pw.println();
13726            if (dumpAll) {
13727                pw.println("-------------------------------------------------------------------------------");
13728            }
13729            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13730            pw.println();
13731            if (dumpAll) {
13732                pw.println("-------------------------------------------------------------------------------");
13733            }
13734            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13735            pw.println();
13736            if (dumpAll) {
13737                pw.println("-------------------------------------------------------------------------------");
13738            }
13739            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13740            pw.println();
13741            if (dumpAll) {
13742                pw.println("-------------------------------------------------------------------------------");
13743            }
13744            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13745            if (mAssociations.size() > 0) {
13746                pw.println();
13747                if (dumpAll) {
13748                    pw.println("-------------------------------------------------------------------------------");
13749                }
13750                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13751            }
13752            pw.println();
13753            if (dumpAll) {
13754                pw.println("-------------------------------------------------------------------------------");
13755            }
13756            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13757        }
13758        Binder.restoreCallingIdentity(origId);
13759    }
13760
13761    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13762            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13763        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13764
13765        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13766                dumpPackage);
13767        boolean needSep = printedAnything;
13768
13769        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13770                dumpPackage, needSep, "  mFocusedActivity: ");
13771        if (printed) {
13772            printedAnything = true;
13773            needSep = false;
13774        }
13775
13776        if (dumpPackage == null) {
13777            if (needSep) {
13778                pw.println();
13779            }
13780            needSep = true;
13781            printedAnything = true;
13782            mStackSupervisor.dump(pw, "  ");
13783        }
13784
13785        if (!printedAnything) {
13786            pw.println("  (nothing)");
13787        }
13788    }
13789
13790    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13791            int opti, boolean dumpAll, String dumpPackage) {
13792        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13793
13794        boolean printedAnything = false;
13795
13796        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13797            boolean printedHeader = false;
13798
13799            final int N = mRecentTasks.size();
13800            for (int i=0; i<N; i++) {
13801                TaskRecord tr = mRecentTasks.get(i);
13802                if (dumpPackage != null) {
13803                    if (tr.realActivity == null ||
13804                            !dumpPackage.equals(tr.realActivity)) {
13805                        continue;
13806                    }
13807                }
13808                if (!printedHeader) {
13809                    pw.println("  Recent tasks:");
13810                    printedHeader = true;
13811                    printedAnything = true;
13812                }
13813                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13814                        pw.println(tr);
13815                if (dumpAll) {
13816                    mRecentTasks.get(i).dump(pw, "    ");
13817                }
13818            }
13819        }
13820
13821        if (!printedAnything) {
13822            pw.println("  (nothing)");
13823        }
13824    }
13825
13826    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13827            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13828        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13829
13830        int dumpUid = 0;
13831        if (dumpPackage != null) {
13832            IPackageManager pm = AppGlobals.getPackageManager();
13833            try {
13834                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13835            } catch (RemoteException e) {
13836            }
13837        }
13838
13839        boolean printedAnything = false;
13840
13841        final long now = SystemClock.uptimeMillis();
13842
13843        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13844            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13845                    = mAssociations.valueAt(i1);
13846            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13847                SparseArray<ArrayMap<String, Association>> sourceUids
13848                        = targetComponents.valueAt(i2);
13849                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13850                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13851                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13852                        Association ass = sourceProcesses.valueAt(i4);
13853                        if (dumpPackage != null) {
13854                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13855                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13856                                continue;
13857                            }
13858                        }
13859                        printedAnything = true;
13860                        pw.print("  ");
13861                        pw.print(ass.mTargetProcess);
13862                        pw.print("/");
13863                        UserHandle.formatUid(pw, ass.mTargetUid);
13864                        pw.print(" <- ");
13865                        pw.print(ass.mSourceProcess);
13866                        pw.print("/");
13867                        UserHandle.formatUid(pw, ass.mSourceUid);
13868                        pw.println();
13869                        pw.print("    via ");
13870                        pw.print(ass.mTargetComponent.flattenToShortString());
13871                        pw.println();
13872                        pw.print("    ");
13873                        long dur = ass.mTime;
13874                        if (ass.mNesting > 0) {
13875                            dur += now - ass.mStartTime;
13876                        }
13877                        TimeUtils.formatDuration(dur, pw);
13878                        pw.print(" (");
13879                        pw.print(ass.mCount);
13880                        pw.print(" times)");
13881                        pw.print("  ");
13882                        for (int i=0; i<ass.mStateTimes.length; i++) {
13883                            long amt = ass.mStateTimes[i];
13884                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13885                                amt += now - ass.mLastStateUptime;
13886                            }
13887                            if (amt != 0) {
13888                                pw.print(" ");
13889                                pw.print(ProcessList.makeProcStateString(
13890                                            i + ActivityManager.MIN_PROCESS_STATE));
13891                                pw.print("=");
13892                                TimeUtils.formatDuration(amt, pw);
13893                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13894                                    pw.print("*");
13895                                }
13896                            }
13897                        }
13898                        pw.println();
13899                        if (ass.mNesting > 0) {
13900                            pw.print("    Currently active: ");
13901                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13902                            pw.println();
13903                        }
13904                    }
13905                }
13906            }
13907
13908        }
13909
13910        if (!printedAnything) {
13911            pw.println("  (nothing)");
13912        }
13913    }
13914
13915    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13916            String header, boolean needSep) {
13917        boolean printed = false;
13918        int whichAppId = -1;
13919        if (dumpPackage != null) {
13920            try {
13921                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13922                        dumpPackage, 0);
13923                whichAppId = UserHandle.getAppId(info.uid);
13924            } catch (NameNotFoundException e) {
13925                e.printStackTrace();
13926            }
13927        }
13928        for (int i=0; i<uids.size(); i++) {
13929            UidRecord uidRec = uids.valueAt(i);
13930            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13931                continue;
13932            }
13933            if (!printed) {
13934                printed = true;
13935                if (needSep) {
13936                    pw.println();
13937                }
13938                pw.print("  ");
13939                pw.println(header);
13940                needSep = true;
13941            }
13942            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13943            pw.print(": "); pw.println(uidRec);
13944        }
13945        return printed;
13946    }
13947
13948    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13949            int opti, boolean dumpAll, String dumpPackage) {
13950        boolean needSep = false;
13951        boolean printedAnything = false;
13952        int numPers = 0;
13953
13954        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13955
13956        if (dumpAll) {
13957            final int NP = mProcessNames.getMap().size();
13958            for (int ip=0; ip<NP; ip++) {
13959                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13960                final int NA = procs.size();
13961                for (int ia=0; ia<NA; ia++) {
13962                    ProcessRecord r = procs.valueAt(ia);
13963                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13964                        continue;
13965                    }
13966                    if (!needSep) {
13967                        pw.println("  All known processes:");
13968                        needSep = true;
13969                        printedAnything = true;
13970                    }
13971                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13972                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13973                        pw.print(" "); pw.println(r);
13974                    r.dump(pw, "    ");
13975                    if (r.persistent) {
13976                        numPers++;
13977                    }
13978                }
13979            }
13980        }
13981
13982        if (mIsolatedProcesses.size() > 0) {
13983            boolean printed = false;
13984            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13985                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13986                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13987                    continue;
13988                }
13989                if (!printed) {
13990                    if (needSep) {
13991                        pw.println();
13992                    }
13993                    pw.println("  Isolated process list (sorted by uid):");
13994                    printedAnything = true;
13995                    printed = true;
13996                    needSep = true;
13997                }
13998                pw.println(String.format("%sIsolated #%2d: %s",
13999                        "    ", i, r.toString()));
14000            }
14001        }
14002
14003        if (mActiveUids.size() > 0) {
14004            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14005                printedAnything = needSep = true;
14006            }
14007        }
14008        if (mValidateUids.size() > 0) {
14009            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14010                printedAnything = needSep = true;
14011            }
14012        }
14013
14014        if (mLruProcesses.size() > 0) {
14015            if (needSep) {
14016                pw.println();
14017            }
14018            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14019                    pw.print(" total, non-act at ");
14020                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14021                    pw.print(", non-svc at ");
14022                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14023                    pw.println("):");
14024            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14025            needSep = true;
14026            printedAnything = true;
14027        }
14028
14029        if (dumpAll || dumpPackage != null) {
14030            synchronized (mPidsSelfLocked) {
14031                boolean printed = false;
14032                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14033                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14034                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14035                        continue;
14036                    }
14037                    if (!printed) {
14038                        if (needSep) pw.println();
14039                        needSep = true;
14040                        pw.println("  PID mappings:");
14041                        printed = true;
14042                        printedAnything = true;
14043                    }
14044                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14045                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14046                }
14047            }
14048        }
14049
14050        if (mForegroundProcesses.size() > 0) {
14051            synchronized (mPidsSelfLocked) {
14052                boolean printed = false;
14053                for (int i=0; i<mForegroundProcesses.size(); i++) {
14054                    ProcessRecord r = mPidsSelfLocked.get(
14055                            mForegroundProcesses.valueAt(i).pid);
14056                    if (dumpPackage != null && (r == null
14057                            || !r.pkgList.containsKey(dumpPackage))) {
14058                        continue;
14059                    }
14060                    if (!printed) {
14061                        if (needSep) pw.println();
14062                        needSep = true;
14063                        pw.println("  Foreground Processes:");
14064                        printed = true;
14065                        printedAnything = true;
14066                    }
14067                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14068                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14069                }
14070            }
14071        }
14072
14073        if (mPersistentStartingProcesses.size() > 0) {
14074            if (needSep) pw.println();
14075            needSep = true;
14076            printedAnything = true;
14077            pw.println("  Persisent processes that are starting:");
14078            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14079                    "Starting Norm", "Restarting PERS", dumpPackage);
14080        }
14081
14082        if (mRemovedProcesses.size() > 0) {
14083            if (needSep) pw.println();
14084            needSep = true;
14085            printedAnything = true;
14086            pw.println("  Processes that are being removed:");
14087            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14088                    "Removed Norm", "Removed PERS", dumpPackage);
14089        }
14090
14091        if (mProcessesOnHold.size() > 0) {
14092            if (needSep) pw.println();
14093            needSep = true;
14094            printedAnything = true;
14095            pw.println("  Processes that are on old until the system is ready:");
14096            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14097                    "OnHold Norm", "OnHold PERS", dumpPackage);
14098        }
14099
14100        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14101
14102        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14103        if (needSep) {
14104            printedAnything = true;
14105        }
14106
14107        if (dumpPackage == null) {
14108            pw.println();
14109            needSep = false;
14110            mUserController.dump(pw, dumpAll);
14111        }
14112        if (mHomeProcess != null && (dumpPackage == null
14113                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14114            if (needSep) {
14115                pw.println();
14116                needSep = false;
14117            }
14118            pw.println("  mHomeProcess: " + mHomeProcess);
14119        }
14120        if (mPreviousProcess != null && (dumpPackage == null
14121                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14122            if (needSep) {
14123                pw.println();
14124                needSep = false;
14125            }
14126            pw.println("  mPreviousProcess: " + mPreviousProcess);
14127        }
14128        if (dumpAll) {
14129            StringBuilder sb = new StringBuilder(128);
14130            sb.append("  mPreviousProcessVisibleTime: ");
14131            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14132            pw.println(sb);
14133        }
14134        if (mHeavyWeightProcess != null && (dumpPackage == null
14135                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14136            if (needSep) {
14137                pw.println();
14138                needSep = false;
14139            }
14140            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14141        }
14142        if (dumpPackage == null) {
14143            pw.println("  mConfiguration: " + mConfiguration);
14144        }
14145        if (dumpAll) {
14146            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14147            if (mCompatModePackages.getPackages().size() > 0) {
14148                boolean printed = false;
14149                for (Map.Entry<String, Integer> entry
14150                        : mCompatModePackages.getPackages().entrySet()) {
14151                    String pkg = entry.getKey();
14152                    int mode = entry.getValue();
14153                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14154                        continue;
14155                    }
14156                    if (!printed) {
14157                        pw.println("  mScreenCompatPackages:");
14158                        printed = true;
14159                    }
14160                    pw.print("    "); pw.print(pkg); pw.print(": ");
14161                            pw.print(mode); pw.println();
14162                }
14163            }
14164        }
14165        if (dumpPackage == null) {
14166            pw.println("  mWakefulness="
14167                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14168            pw.println("  mSleepTokens=" + mSleepTokens);
14169            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14170                    + lockScreenShownToString());
14171            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14172            if (mRunningVoice != null) {
14173                pw.println("  mRunningVoice=" + mRunningVoice);
14174                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14175            }
14176        }
14177        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14178                || mOrigWaitForDebugger) {
14179            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14180                    || dumpPackage.equals(mOrigDebugApp)) {
14181                if (needSep) {
14182                    pw.println();
14183                    needSep = false;
14184                }
14185                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14186                        + " mDebugTransient=" + mDebugTransient
14187                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14188            }
14189        }
14190        if (mCurAppTimeTracker != null) {
14191            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14192        }
14193        if (mMemWatchProcesses.getMap().size() > 0) {
14194            pw.println("  Mem watch processes:");
14195            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14196                    = mMemWatchProcesses.getMap();
14197            for (int i=0; i<procs.size(); i++) {
14198                final String proc = procs.keyAt(i);
14199                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14200                for (int j=0; j<uids.size(); j++) {
14201                    if (needSep) {
14202                        pw.println();
14203                        needSep = false;
14204                    }
14205                    StringBuilder sb = new StringBuilder();
14206                    sb.append("    ").append(proc).append('/');
14207                    UserHandle.formatUid(sb, uids.keyAt(j));
14208                    Pair<Long, String> val = uids.valueAt(j);
14209                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14210                    if (val.second != null) {
14211                        sb.append(", report to ").append(val.second);
14212                    }
14213                    pw.println(sb.toString());
14214                }
14215            }
14216            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14217            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14218            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14219                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14220        }
14221        if (mTrackAllocationApp != null) {
14222            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14223                if (needSep) {
14224                    pw.println();
14225                    needSep = false;
14226                }
14227                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14228            }
14229        }
14230        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14231                || mProfileFd != null) {
14232            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14233                if (needSep) {
14234                    pw.println();
14235                    needSep = false;
14236                }
14237                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14238                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14239                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14240                        + mAutoStopProfiler);
14241                pw.println("  mProfileType=" + mProfileType);
14242            }
14243        }
14244        if (mNativeDebuggingApp != null) {
14245            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14246                if (needSep) {
14247                    pw.println();
14248                    needSep = false;
14249                }
14250                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14251            }
14252        }
14253        if (dumpPackage == null) {
14254            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14255                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14256                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14257            }
14258            if (mController != null) {
14259                pw.println("  mController=" + mController
14260                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14261            }
14262            if (dumpAll) {
14263                pw.println("  Total persistent processes: " + numPers);
14264                pw.println("  mProcessesReady=" + mProcessesReady
14265                        + " mSystemReady=" + mSystemReady
14266                        + " mBooted=" + mBooted
14267                        + " mFactoryTest=" + mFactoryTest);
14268                pw.println("  mBooting=" + mBooting
14269                        + " mCallFinishBooting=" + mCallFinishBooting
14270                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14271                pw.print("  mLastPowerCheckRealtime=");
14272                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14273                        pw.println("");
14274                pw.print("  mLastPowerCheckUptime=");
14275                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14276                        pw.println("");
14277                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14278                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14279                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14280                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14281                        + " (" + mLruProcesses.size() + " total)"
14282                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14283                        + " mNumServiceProcs=" + mNumServiceProcs
14284                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14285                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14286                        + " mLastMemoryLevel=" + mLastMemoryLevel
14287                        + " mLastNumProcesses=" + mLastNumProcesses);
14288                long now = SystemClock.uptimeMillis();
14289                pw.print("  mLastIdleTime=");
14290                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14291                        pw.print(" mLowRamSinceLastIdle=");
14292                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14293                        pw.println();
14294            }
14295        }
14296
14297        if (!printedAnything) {
14298            pw.println("  (nothing)");
14299        }
14300    }
14301
14302    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14303            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14304        if (mProcessesToGc.size() > 0) {
14305            boolean printed = false;
14306            long now = SystemClock.uptimeMillis();
14307            for (int i=0; i<mProcessesToGc.size(); i++) {
14308                ProcessRecord proc = mProcessesToGc.get(i);
14309                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14310                    continue;
14311                }
14312                if (!printed) {
14313                    if (needSep) pw.println();
14314                    needSep = true;
14315                    pw.println("  Processes that are waiting to GC:");
14316                    printed = true;
14317                }
14318                pw.print("    Process "); pw.println(proc);
14319                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14320                        pw.print(", last gced=");
14321                        pw.print(now-proc.lastRequestedGc);
14322                        pw.print(" ms ago, last lowMem=");
14323                        pw.print(now-proc.lastLowMemory);
14324                        pw.println(" ms ago");
14325
14326            }
14327        }
14328        return needSep;
14329    }
14330
14331    void printOomLevel(PrintWriter pw, String name, int adj) {
14332        pw.print("    ");
14333        if (adj >= 0) {
14334            pw.print(' ');
14335            if (adj < 10) pw.print(' ');
14336        } else {
14337            if (adj > -10) pw.print(' ');
14338        }
14339        pw.print(adj);
14340        pw.print(": ");
14341        pw.print(name);
14342        pw.print(" (");
14343        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14344        pw.println(")");
14345    }
14346
14347    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14348            int opti, boolean dumpAll) {
14349        boolean needSep = false;
14350
14351        if (mLruProcesses.size() > 0) {
14352            if (needSep) pw.println();
14353            needSep = true;
14354            pw.println("  OOM levels:");
14355            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14356            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14357            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14358            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14359            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14360            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14361            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14362            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14363            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14364            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14365            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14366            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14367            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14368            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14369
14370            if (needSep) pw.println();
14371            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14372                    pw.print(" total, non-act at ");
14373                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14374                    pw.print(", non-svc at ");
14375                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14376                    pw.println("):");
14377            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14378            needSep = true;
14379        }
14380
14381        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14382
14383        pw.println();
14384        pw.println("  mHomeProcess: " + mHomeProcess);
14385        pw.println("  mPreviousProcess: " + mPreviousProcess);
14386        if (mHeavyWeightProcess != null) {
14387            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14388        }
14389
14390        return true;
14391    }
14392
14393    /**
14394     * There are three ways to call this:
14395     *  - no provider specified: dump all the providers
14396     *  - a flattened component name that matched an existing provider was specified as the
14397     *    first arg: dump that one provider
14398     *  - the first arg isn't the flattened component name of an existing provider:
14399     *    dump all providers whose component contains the first arg as a substring
14400     */
14401    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14402            int opti, boolean dumpAll) {
14403        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14404    }
14405
14406    static class ItemMatcher {
14407        ArrayList<ComponentName> components;
14408        ArrayList<String> strings;
14409        ArrayList<Integer> objects;
14410        boolean all;
14411
14412        ItemMatcher() {
14413            all = true;
14414        }
14415
14416        void build(String name) {
14417            ComponentName componentName = ComponentName.unflattenFromString(name);
14418            if (componentName != null) {
14419                if (components == null) {
14420                    components = new ArrayList<ComponentName>();
14421                }
14422                components.add(componentName);
14423                all = false;
14424            } else {
14425                int objectId = 0;
14426                // Not a '/' separated full component name; maybe an object ID?
14427                try {
14428                    objectId = Integer.parseInt(name, 16);
14429                    if (objects == null) {
14430                        objects = new ArrayList<Integer>();
14431                    }
14432                    objects.add(objectId);
14433                    all = false;
14434                } catch (RuntimeException e) {
14435                    // Not an integer; just do string match.
14436                    if (strings == null) {
14437                        strings = new ArrayList<String>();
14438                    }
14439                    strings.add(name);
14440                    all = false;
14441                }
14442            }
14443        }
14444
14445        int build(String[] args, int opti) {
14446            for (; opti<args.length; opti++) {
14447                String name = args[opti];
14448                if ("--".equals(name)) {
14449                    return opti+1;
14450                }
14451                build(name);
14452            }
14453            return opti;
14454        }
14455
14456        boolean match(Object object, ComponentName comp) {
14457            if (all) {
14458                return true;
14459            }
14460            if (components != null) {
14461                for (int i=0; i<components.size(); i++) {
14462                    if (components.get(i).equals(comp)) {
14463                        return true;
14464                    }
14465                }
14466            }
14467            if (objects != null) {
14468                for (int i=0; i<objects.size(); i++) {
14469                    if (System.identityHashCode(object) == objects.get(i)) {
14470                        return true;
14471                    }
14472                }
14473            }
14474            if (strings != null) {
14475                String flat = comp.flattenToString();
14476                for (int i=0; i<strings.size(); i++) {
14477                    if (flat.contains(strings.get(i))) {
14478                        return true;
14479                    }
14480                }
14481            }
14482            return false;
14483        }
14484    }
14485
14486    /**
14487     * There are three things that cmd can be:
14488     *  - a flattened component name that matches an existing activity
14489     *  - the cmd arg isn't the flattened component name of an existing activity:
14490     *    dump all activity whose component contains the cmd as a substring
14491     *  - A hex number of the ActivityRecord object instance.
14492     */
14493    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14494            int opti, boolean dumpAll) {
14495        ArrayList<ActivityRecord> activities;
14496
14497        synchronized (this) {
14498            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14499        }
14500
14501        if (activities.size() <= 0) {
14502            return false;
14503        }
14504
14505        String[] newArgs = new String[args.length - opti];
14506        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14507
14508        TaskRecord lastTask = null;
14509        boolean needSep = false;
14510        for (int i=activities.size()-1; i>=0; i--) {
14511            ActivityRecord r = activities.get(i);
14512            if (needSep) {
14513                pw.println();
14514            }
14515            needSep = true;
14516            synchronized (this) {
14517                if (lastTask != r.task) {
14518                    lastTask = r.task;
14519                    pw.print("TASK "); pw.print(lastTask.affinity);
14520                            pw.print(" id="); pw.println(lastTask.taskId);
14521                    if (dumpAll) {
14522                        lastTask.dump(pw, "  ");
14523                    }
14524                }
14525            }
14526            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14527        }
14528        return true;
14529    }
14530
14531    /**
14532     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14533     * there is a thread associated with the activity.
14534     */
14535    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14536            final ActivityRecord r, String[] args, boolean dumpAll) {
14537        String innerPrefix = prefix + "  ";
14538        synchronized (this) {
14539            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14540                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14541                    pw.print(" pid=");
14542                    if (r.app != null) pw.println(r.app.pid);
14543                    else pw.println("(not running)");
14544            if (dumpAll) {
14545                r.dump(pw, innerPrefix);
14546            }
14547        }
14548        if (r.app != null && r.app.thread != null) {
14549            // flush anything that is already in the PrintWriter since the thread is going
14550            // to write to the file descriptor directly
14551            pw.flush();
14552            try {
14553                TransferPipe tp = new TransferPipe();
14554                try {
14555                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14556                            r.appToken, innerPrefix, args);
14557                    tp.go(fd);
14558                } finally {
14559                    tp.kill();
14560                }
14561            } catch (IOException e) {
14562                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14563            } catch (RemoteException e) {
14564                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14565            }
14566        }
14567    }
14568
14569    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14570            int opti, boolean dumpAll, String dumpPackage) {
14571        boolean needSep = false;
14572        boolean onlyHistory = false;
14573        boolean printedAnything = false;
14574
14575        if ("history".equals(dumpPackage)) {
14576            if (opti < args.length && "-s".equals(args[opti])) {
14577                dumpAll = false;
14578            }
14579            onlyHistory = true;
14580            dumpPackage = null;
14581        }
14582
14583        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14584        if (!onlyHistory && dumpAll) {
14585            if (mRegisteredReceivers.size() > 0) {
14586                boolean printed = false;
14587                Iterator it = mRegisteredReceivers.values().iterator();
14588                while (it.hasNext()) {
14589                    ReceiverList r = (ReceiverList)it.next();
14590                    if (dumpPackage != null && (r.app == null ||
14591                            !dumpPackage.equals(r.app.info.packageName))) {
14592                        continue;
14593                    }
14594                    if (!printed) {
14595                        pw.println("  Registered Receivers:");
14596                        needSep = true;
14597                        printed = true;
14598                        printedAnything = true;
14599                    }
14600                    pw.print("  * "); pw.println(r);
14601                    r.dump(pw, "    ");
14602                }
14603            }
14604
14605            if (mReceiverResolver.dump(pw, needSep ?
14606                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14607                    "    ", dumpPackage, false, false)) {
14608                needSep = true;
14609                printedAnything = true;
14610            }
14611        }
14612
14613        for (BroadcastQueue q : mBroadcastQueues) {
14614            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14615            printedAnything |= needSep;
14616        }
14617
14618        needSep = true;
14619
14620        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14621            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14622                if (needSep) {
14623                    pw.println();
14624                }
14625                needSep = true;
14626                printedAnything = true;
14627                pw.print("  Sticky broadcasts for user ");
14628                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14629                StringBuilder sb = new StringBuilder(128);
14630                for (Map.Entry<String, ArrayList<Intent>> ent
14631                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14632                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14633                    if (dumpAll) {
14634                        pw.println(":");
14635                        ArrayList<Intent> intents = ent.getValue();
14636                        final int N = intents.size();
14637                        for (int i=0; i<N; i++) {
14638                            sb.setLength(0);
14639                            sb.append("    Intent: ");
14640                            intents.get(i).toShortString(sb, false, true, false, false);
14641                            pw.println(sb.toString());
14642                            Bundle bundle = intents.get(i).getExtras();
14643                            if (bundle != null) {
14644                                pw.print("      ");
14645                                pw.println(bundle.toString());
14646                            }
14647                        }
14648                    } else {
14649                        pw.println("");
14650                    }
14651                }
14652            }
14653        }
14654
14655        if (!onlyHistory && dumpAll) {
14656            pw.println();
14657            for (BroadcastQueue queue : mBroadcastQueues) {
14658                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14659                        + queue.mBroadcastsScheduled);
14660            }
14661            pw.println("  mHandler:");
14662            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14663            needSep = true;
14664            printedAnything = true;
14665        }
14666
14667        if (!printedAnything) {
14668            pw.println("  (nothing)");
14669        }
14670    }
14671
14672    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14673            int opti, boolean dumpAll, String dumpPackage) {
14674        boolean needSep;
14675        boolean printedAnything = false;
14676
14677        ItemMatcher matcher = new ItemMatcher();
14678        matcher.build(args, opti);
14679
14680        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14681
14682        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14683        printedAnything |= needSep;
14684
14685        if (mLaunchingProviders.size() > 0) {
14686            boolean printed = false;
14687            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14688                ContentProviderRecord r = mLaunchingProviders.get(i);
14689                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14690                    continue;
14691                }
14692                if (!printed) {
14693                    if (needSep) pw.println();
14694                    needSep = true;
14695                    pw.println("  Launching content providers:");
14696                    printed = true;
14697                    printedAnything = true;
14698                }
14699                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14700                        pw.println(r);
14701            }
14702        }
14703
14704        if (!printedAnything) {
14705            pw.println("  (nothing)");
14706        }
14707    }
14708
14709    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14710            int opti, boolean dumpAll, String dumpPackage) {
14711        boolean needSep = false;
14712        boolean printedAnything = false;
14713
14714        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14715
14716        if (mGrantedUriPermissions.size() > 0) {
14717            boolean printed = false;
14718            int dumpUid = -2;
14719            if (dumpPackage != null) {
14720                try {
14721                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14722                            MATCH_UNINSTALLED_PACKAGES, 0);
14723                } catch (NameNotFoundException e) {
14724                    dumpUid = -1;
14725                }
14726            }
14727            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14728                int uid = mGrantedUriPermissions.keyAt(i);
14729                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14730                    continue;
14731                }
14732                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14733                if (!printed) {
14734                    if (needSep) pw.println();
14735                    needSep = true;
14736                    pw.println("  Granted Uri Permissions:");
14737                    printed = true;
14738                    printedAnything = true;
14739                }
14740                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14741                for (UriPermission perm : perms.values()) {
14742                    pw.print("    "); pw.println(perm);
14743                    if (dumpAll) {
14744                        perm.dump(pw, "      ");
14745                    }
14746                }
14747            }
14748        }
14749
14750        if (!printedAnything) {
14751            pw.println("  (nothing)");
14752        }
14753    }
14754
14755    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14756            int opti, boolean dumpAll, String dumpPackage) {
14757        boolean printed = false;
14758
14759        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14760
14761        if (mIntentSenderRecords.size() > 0) {
14762            Iterator<WeakReference<PendingIntentRecord>> it
14763                    = mIntentSenderRecords.values().iterator();
14764            while (it.hasNext()) {
14765                WeakReference<PendingIntentRecord> ref = it.next();
14766                PendingIntentRecord rec = ref != null ? ref.get(): null;
14767                if (dumpPackage != null && (rec == null
14768                        || !dumpPackage.equals(rec.key.packageName))) {
14769                    continue;
14770                }
14771                printed = true;
14772                if (rec != null) {
14773                    pw.print("  * "); pw.println(rec);
14774                    if (dumpAll) {
14775                        rec.dump(pw, "    ");
14776                    }
14777                } else {
14778                    pw.print("  * "); pw.println(ref);
14779                }
14780            }
14781        }
14782
14783        if (!printed) {
14784            pw.println("  (nothing)");
14785        }
14786    }
14787
14788    private static final int dumpProcessList(PrintWriter pw,
14789            ActivityManagerService service, List list,
14790            String prefix, String normalLabel, String persistentLabel,
14791            String dumpPackage) {
14792        int numPers = 0;
14793        final int N = list.size()-1;
14794        for (int i=N; i>=0; i--) {
14795            ProcessRecord r = (ProcessRecord)list.get(i);
14796            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14797                continue;
14798            }
14799            pw.println(String.format("%s%s #%2d: %s",
14800                    prefix, (r.persistent ? persistentLabel : normalLabel),
14801                    i, r.toString()));
14802            if (r.persistent) {
14803                numPers++;
14804            }
14805        }
14806        return numPers;
14807    }
14808
14809    private static final boolean dumpProcessOomList(PrintWriter pw,
14810            ActivityManagerService service, List<ProcessRecord> origList,
14811            String prefix, String normalLabel, String persistentLabel,
14812            boolean inclDetails, String dumpPackage) {
14813
14814        ArrayList<Pair<ProcessRecord, Integer>> list
14815                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14816        for (int i=0; i<origList.size(); i++) {
14817            ProcessRecord r = origList.get(i);
14818            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14819                continue;
14820            }
14821            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14822        }
14823
14824        if (list.size() <= 0) {
14825            return false;
14826        }
14827
14828        Comparator<Pair<ProcessRecord, Integer>> comparator
14829                = new Comparator<Pair<ProcessRecord, Integer>>() {
14830            @Override
14831            public int compare(Pair<ProcessRecord, Integer> object1,
14832                    Pair<ProcessRecord, Integer> object2) {
14833                if (object1.first.setAdj != object2.first.setAdj) {
14834                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14835                }
14836                if (object1.first.setProcState != object2.first.setProcState) {
14837                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14838                }
14839                if (object1.second.intValue() != object2.second.intValue()) {
14840                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14841                }
14842                return 0;
14843            }
14844        };
14845
14846        Collections.sort(list, comparator);
14847
14848        final long curRealtime = SystemClock.elapsedRealtime();
14849        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14850        final long curUptime = SystemClock.uptimeMillis();
14851        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14852
14853        for (int i=list.size()-1; i>=0; i--) {
14854            ProcessRecord r = list.get(i).first;
14855            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14856            char schedGroup;
14857            switch (r.setSchedGroup) {
14858                case ProcessList.SCHED_GROUP_BACKGROUND:
14859                    schedGroup = 'B';
14860                    break;
14861                case ProcessList.SCHED_GROUP_DEFAULT:
14862                    schedGroup = 'F';
14863                    break;
14864                case ProcessList.SCHED_GROUP_TOP_APP:
14865                    schedGroup = 'T';
14866                    break;
14867                default:
14868                    schedGroup = '?';
14869                    break;
14870            }
14871            char foreground;
14872            if (r.foregroundActivities) {
14873                foreground = 'A';
14874            } else if (r.foregroundServices) {
14875                foreground = 'S';
14876            } else {
14877                foreground = ' ';
14878            }
14879            String procState = ProcessList.makeProcStateString(r.curProcState);
14880            pw.print(prefix);
14881            pw.print(r.persistent ? persistentLabel : normalLabel);
14882            pw.print(" #");
14883            int num = (origList.size()-1)-list.get(i).second;
14884            if (num < 10) pw.print(' ');
14885            pw.print(num);
14886            pw.print(": ");
14887            pw.print(oomAdj);
14888            pw.print(' ');
14889            pw.print(schedGroup);
14890            pw.print('/');
14891            pw.print(foreground);
14892            pw.print('/');
14893            pw.print(procState);
14894            pw.print(" trm:");
14895            if (r.trimMemoryLevel < 10) pw.print(' ');
14896            pw.print(r.trimMemoryLevel);
14897            pw.print(' ');
14898            pw.print(r.toShortString());
14899            pw.print(" (");
14900            pw.print(r.adjType);
14901            pw.println(')');
14902            if (r.adjSource != null || r.adjTarget != null) {
14903                pw.print(prefix);
14904                pw.print("    ");
14905                if (r.adjTarget instanceof ComponentName) {
14906                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14907                } else if (r.adjTarget != null) {
14908                    pw.print(r.adjTarget.toString());
14909                } else {
14910                    pw.print("{null}");
14911                }
14912                pw.print("<=");
14913                if (r.adjSource instanceof ProcessRecord) {
14914                    pw.print("Proc{");
14915                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14916                    pw.println("}");
14917                } else if (r.adjSource != null) {
14918                    pw.println(r.adjSource.toString());
14919                } else {
14920                    pw.println("{null}");
14921                }
14922            }
14923            if (inclDetails) {
14924                pw.print(prefix);
14925                pw.print("    ");
14926                pw.print("oom: max="); pw.print(r.maxAdj);
14927                pw.print(" curRaw="); pw.print(r.curRawAdj);
14928                pw.print(" setRaw="); pw.print(r.setRawAdj);
14929                pw.print(" cur="); pw.print(r.curAdj);
14930                pw.print(" set="); pw.println(r.setAdj);
14931                pw.print(prefix);
14932                pw.print("    ");
14933                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14934                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14935                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14936                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14937                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14938                pw.println();
14939                pw.print(prefix);
14940                pw.print("    ");
14941                pw.print("cached="); pw.print(r.cached);
14942                pw.print(" empty="); pw.print(r.empty);
14943                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14944
14945                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14946                    if (r.lastWakeTime != 0) {
14947                        long wtime;
14948                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14949                        synchronized (stats) {
14950                            wtime = stats.getProcessWakeTime(r.info.uid,
14951                                    r.pid, curRealtime);
14952                        }
14953                        long timeUsed = wtime - r.lastWakeTime;
14954                        pw.print(prefix);
14955                        pw.print("    ");
14956                        pw.print("keep awake over ");
14957                        TimeUtils.formatDuration(realtimeSince, pw);
14958                        pw.print(" used ");
14959                        TimeUtils.formatDuration(timeUsed, pw);
14960                        pw.print(" (");
14961                        pw.print((timeUsed*100)/realtimeSince);
14962                        pw.println("%)");
14963                    }
14964                    if (r.lastCpuTime != 0) {
14965                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14966                        pw.print(prefix);
14967                        pw.print("    ");
14968                        pw.print("run cpu over ");
14969                        TimeUtils.formatDuration(uptimeSince, pw);
14970                        pw.print(" used ");
14971                        TimeUtils.formatDuration(timeUsed, pw);
14972                        pw.print(" (");
14973                        pw.print((timeUsed*100)/uptimeSince);
14974                        pw.println("%)");
14975                    }
14976                }
14977            }
14978        }
14979        return true;
14980    }
14981
14982    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14983            String[] args) {
14984        ArrayList<ProcessRecord> procs;
14985        synchronized (this) {
14986            if (args != null && args.length > start
14987                    && args[start].charAt(0) != '-') {
14988                procs = new ArrayList<ProcessRecord>();
14989                int pid = -1;
14990                try {
14991                    pid = Integer.parseInt(args[start]);
14992                } catch (NumberFormatException e) {
14993                }
14994                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14995                    ProcessRecord proc = mLruProcesses.get(i);
14996                    if (proc.pid == pid) {
14997                        procs.add(proc);
14998                    } else if (allPkgs && proc.pkgList != null
14999                            && proc.pkgList.containsKey(args[start])) {
15000                        procs.add(proc);
15001                    } else if (proc.processName.equals(args[start])) {
15002                        procs.add(proc);
15003                    }
15004                }
15005                if (procs.size() <= 0) {
15006                    return null;
15007                }
15008            } else {
15009                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15010            }
15011        }
15012        return procs;
15013    }
15014
15015    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15016            PrintWriter pw, String[] args) {
15017        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15018        if (procs == null) {
15019            pw.println("No process found for: " + args[0]);
15020            return;
15021        }
15022
15023        long uptime = SystemClock.uptimeMillis();
15024        long realtime = SystemClock.elapsedRealtime();
15025        pw.println("Applications Graphics Acceleration Info:");
15026        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15027
15028        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15029            ProcessRecord r = procs.get(i);
15030            if (r.thread != null) {
15031                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15032                pw.flush();
15033                try {
15034                    TransferPipe tp = new TransferPipe();
15035                    try {
15036                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15037                        tp.go(fd);
15038                    } finally {
15039                        tp.kill();
15040                    }
15041                } catch (IOException e) {
15042                    pw.println("Failure while dumping the app: " + r);
15043                    pw.flush();
15044                } catch (RemoteException e) {
15045                    pw.println("Got a RemoteException while dumping the app " + r);
15046                    pw.flush();
15047                }
15048            }
15049        }
15050    }
15051
15052    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15053        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15054        if (procs == null) {
15055            pw.println("No process found for: " + args[0]);
15056            return;
15057        }
15058
15059        pw.println("Applications Database Info:");
15060
15061        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15062            ProcessRecord r = procs.get(i);
15063            if (r.thread != null) {
15064                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15065                pw.flush();
15066                try {
15067                    TransferPipe tp = new TransferPipe();
15068                    try {
15069                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15070                        tp.go(fd);
15071                    } finally {
15072                        tp.kill();
15073                    }
15074                } catch (IOException e) {
15075                    pw.println("Failure while dumping the app: " + r);
15076                    pw.flush();
15077                } catch (RemoteException e) {
15078                    pw.println("Got a RemoteException while dumping the app " + r);
15079                    pw.flush();
15080                }
15081            }
15082        }
15083    }
15084
15085    final static class MemItem {
15086        final boolean isProc;
15087        final String label;
15088        final String shortLabel;
15089        final long pss;
15090        final long swapPss;
15091        final int id;
15092        final boolean hasActivities;
15093        ArrayList<MemItem> subitems;
15094
15095        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15096                boolean _hasActivities) {
15097            isProc = true;
15098            label = _label;
15099            shortLabel = _shortLabel;
15100            pss = _pss;
15101            swapPss = _swapPss;
15102            id = _id;
15103            hasActivities = _hasActivities;
15104        }
15105
15106        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15107            isProc = false;
15108            label = _label;
15109            shortLabel = _shortLabel;
15110            pss = _pss;
15111            swapPss = _swapPss;
15112            id = _id;
15113            hasActivities = false;
15114        }
15115    }
15116
15117    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15118            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15119        if (sort && !isCompact) {
15120            Collections.sort(items, new Comparator<MemItem>() {
15121                @Override
15122                public int compare(MemItem lhs, MemItem rhs) {
15123                    if (lhs.pss < rhs.pss) {
15124                        return 1;
15125                    } else if (lhs.pss > rhs.pss) {
15126                        return -1;
15127                    }
15128                    return 0;
15129                }
15130            });
15131        }
15132
15133        for (int i=0; i<items.size(); i++) {
15134            MemItem mi = items.get(i);
15135            if (!isCompact) {
15136                if (dumpSwapPss) {
15137                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15138                            mi.label, stringifyKBSize(mi.swapPss));
15139                } else {
15140                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15141                }
15142            } else if (mi.isProc) {
15143                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15144                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15145                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15146                pw.println(mi.hasActivities ? ",a" : ",e");
15147            } else {
15148                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15149                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15150            }
15151            if (mi.subitems != null) {
15152                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15153                        true, isCompact, dumpSwapPss);
15154            }
15155        }
15156    }
15157
15158    // These are in KB.
15159    static final long[] DUMP_MEM_BUCKETS = new long[] {
15160        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15161        120*1024, 160*1024, 200*1024,
15162        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15163        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15164    };
15165
15166    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15167            boolean stackLike) {
15168        int start = label.lastIndexOf('.');
15169        if (start >= 0) start++;
15170        else start = 0;
15171        int end = label.length();
15172        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15173            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15174                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15175                out.append(bucket);
15176                out.append(stackLike ? "MB." : "MB ");
15177                out.append(label, start, end);
15178                return;
15179            }
15180        }
15181        out.append(memKB/1024);
15182        out.append(stackLike ? "MB." : "MB ");
15183        out.append(label, start, end);
15184    }
15185
15186    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15187            ProcessList.NATIVE_ADJ,
15188            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15189            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15190            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15191            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15192            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15193            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15194    };
15195    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15196            "Native",
15197            "System", "Persistent", "Persistent Service", "Foreground",
15198            "Visible", "Perceptible",
15199            "Heavy Weight", "Backup",
15200            "A Services", "Home",
15201            "Previous", "B Services", "Cached"
15202    };
15203    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15204            "native",
15205            "sys", "pers", "persvc", "fore",
15206            "vis", "percept",
15207            "heavy", "backup",
15208            "servicea", "home",
15209            "prev", "serviceb", "cached"
15210    };
15211
15212    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15213            long realtime, boolean isCheckinRequest, boolean isCompact) {
15214        if (isCompact) {
15215            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15216        }
15217        if (isCheckinRequest || isCompact) {
15218            // short checkin version
15219            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15220        } else {
15221            pw.println("Applications Memory Usage (in Kilobytes):");
15222            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15223        }
15224    }
15225
15226    private static final int KSM_SHARED = 0;
15227    private static final int KSM_SHARING = 1;
15228    private static final int KSM_UNSHARED = 2;
15229    private static final int KSM_VOLATILE = 3;
15230
15231    private final long[] getKsmInfo() {
15232        long[] longOut = new long[4];
15233        final int[] SINGLE_LONG_FORMAT = new int[] {
15234            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15235        };
15236        long[] longTmp = new long[1];
15237        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15238                SINGLE_LONG_FORMAT, null, longTmp, null);
15239        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15240        longTmp[0] = 0;
15241        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15242                SINGLE_LONG_FORMAT, null, longTmp, null);
15243        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15244        longTmp[0] = 0;
15245        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15246                SINGLE_LONG_FORMAT, null, longTmp, null);
15247        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15248        longTmp[0] = 0;
15249        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15250                SINGLE_LONG_FORMAT, null, longTmp, null);
15251        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15252        return longOut;
15253    }
15254
15255    private static String stringifySize(long size, int order) {
15256        Locale locale = Locale.US;
15257        switch (order) {
15258            case 1:
15259                return String.format(locale, "%,13d", size);
15260            case 1024:
15261                return String.format(locale, "%,9dK", size / 1024);
15262            case 1024 * 1024:
15263                return String.format(locale, "%,5dM", size / 1024 / 1024);
15264            case 1024 * 1024 * 1024:
15265                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15266            default:
15267                throw new IllegalArgumentException("Invalid size order");
15268        }
15269    }
15270
15271    private static String stringifyKBSize(long size) {
15272        return stringifySize(size * 1024, 1024);
15273    }
15274
15275    // Update this version number in case you change the 'compact' format
15276    private static final int MEMINFO_COMPACT_VERSION = 1;
15277
15278    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15279            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15280        boolean dumpDetails = false;
15281        boolean dumpFullDetails = false;
15282        boolean dumpDalvik = false;
15283        boolean dumpSummaryOnly = false;
15284        boolean dumpUnreachable = false;
15285        boolean oomOnly = false;
15286        boolean isCompact = false;
15287        boolean localOnly = false;
15288        boolean packages = false;
15289        boolean isCheckinRequest = false;
15290        boolean dumpSwapPss = false;
15291
15292        int opti = 0;
15293        while (opti < args.length) {
15294            String opt = args[opti];
15295            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15296                break;
15297            }
15298            opti++;
15299            if ("-a".equals(opt)) {
15300                dumpDetails = true;
15301                dumpFullDetails = true;
15302                dumpDalvik = true;
15303                dumpSwapPss = true;
15304            } else if ("-d".equals(opt)) {
15305                dumpDalvik = true;
15306            } else if ("-c".equals(opt)) {
15307                isCompact = true;
15308            } else if ("-s".equals(opt)) {
15309                dumpDetails = true;
15310                dumpSummaryOnly = true;
15311            } else if ("-S".equals(opt)) {
15312                dumpSwapPss = true;
15313            } else if ("--unreachable".equals(opt)) {
15314                dumpUnreachable = true;
15315            } else if ("--oom".equals(opt)) {
15316                oomOnly = true;
15317            } else if ("--local".equals(opt)) {
15318                localOnly = true;
15319            } else if ("--package".equals(opt)) {
15320                packages = true;
15321            } else if ("--checkin".equals(opt)) {
15322                isCheckinRequest = true;
15323
15324            } else if ("-h".equals(opt)) {
15325                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15326                pw.println("  -a: include all available information for each process.");
15327                pw.println("  -d: include dalvik details.");
15328                pw.println("  -c: dump in a compact machine-parseable representation.");
15329                pw.println("  -s: dump only summary of application memory usage.");
15330                pw.println("  -S: dump also SwapPss.");
15331                pw.println("  --oom: only show processes organized by oom adj.");
15332                pw.println("  --local: only collect details locally, don't call process.");
15333                pw.println("  --package: interpret process arg as package, dumping all");
15334                pw.println("             processes that have loaded that package.");
15335                pw.println("  --checkin: dump data for a checkin");
15336                pw.println("If [process] is specified it can be the name or ");
15337                pw.println("pid of a specific process to dump.");
15338                return;
15339            } else {
15340                pw.println("Unknown argument: " + opt + "; use -h for help");
15341            }
15342        }
15343
15344        long uptime = SystemClock.uptimeMillis();
15345        long realtime = SystemClock.elapsedRealtime();
15346        final long[] tmpLong = new long[1];
15347
15348        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15349        if (procs == null) {
15350            // No Java processes.  Maybe they want to print a native process.
15351            if (args != null && args.length > opti
15352                    && args[opti].charAt(0) != '-') {
15353                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15354                        = new ArrayList<ProcessCpuTracker.Stats>();
15355                updateCpuStatsNow();
15356                int findPid = -1;
15357                try {
15358                    findPid = Integer.parseInt(args[opti]);
15359                } catch (NumberFormatException e) {
15360                }
15361                synchronized (mProcessCpuTracker) {
15362                    final int N = mProcessCpuTracker.countStats();
15363                    for (int i=0; i<N; i++) {
15364                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15365                        if (st.pid == findPid || (st.baseName != null
15366                                && st.baseName.equals(args[opti]))) {
15367                            nativeProcs.add(st);
15368                        }
15369                    }
15370                }
15371                if (nativeProcs.size() > 0) {
15372                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15373                            isCompact);
15374                    Debug.MemoryInfo mi = null;
15375                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15376                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15377                        final int pid = r.pid;
15378                        if (!isCheckinRequest && dumpDetails) {
15379                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15380                        }
15381                        if (mi == null) {
15382                            mi = new Debug.MemoryInfo();
15383                        }
15384                        if (dumpDetails || (!brief && !oomOnly)) {
15385                            Debug.getMemoryInfo(pid, mi);
15386                        } else {
15387                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15388                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15389                        }
15390                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15391                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15392                        if (isCheckinRequest) {
15393                            pw.println();
15394                        }
15395                    }
15396                    return;
15397                }
15398            }
15399            pw.println("No process found for: " + args[opti]);
15400            return;
15401        }
15402
15403        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15404            dumpDetails = true;
15405        }
15406
15407        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15408
15409        String[] innerArgs = new String[args.length-opti];
15410        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15411
15412        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15413        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15414        long nativePss = 0;
15415        long nativeSwapPss = 0;
15416        long dalvikPss = 0;
15417        long dalvikSwapPss = 0;
15418        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15419                EmptyArray.LONG;
15420        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15421                EmptyArray.LONG;
15422        long otherPss = 0;
15423        long otherSwapPss = 0;
15424        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15425        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15426
15427        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15428        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15429        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15430                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15431
15432        long totalPss = 0;
15433        long totalSwapPss = 0;
15434        long cachedPss = 0;
15435        long cachedSwapPss = 0;
15436        boolean hasSwapPss = false;
15437
15438        Debug.MemoryInfo mi = null;
15439        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15440            final ProcessRecord r = procs.get(i);
15441            final IApplicationThread thread;
15442            final int pid;
15443            final int oomAdj;
15444            final boolean hasActivities;
15445            synchronized (this) {
15446                thread = r.thread;
15447                pid = r.pid;
15448                oomAdj = r.getSetAdjWithServices();
15449                hasActivities = r.activities.size() > 0;
15450            }
15451            if (thread != null) {
15452                if (!isCheckinRequest && dumpDetails) {
15453                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15454                }
15455                if (mi == null) {
15456                    mi = new Debug.MemoryInfo();
15457                }
15458                if (dumpDetails || (!brief && !oomOnly)) {
15459                    Debug.getMemoryInfo(pid, mi);
15460                    hasSwapPss = mi.hasSwappedOutPss;
15461                } else {
15462                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15463                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15464                }
15465                if (dumpDetails) {
15466                    if (localOnly) {
15467                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15468                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15469                        if (isCheckinRequest) {
15470                            pw.println();
15471                        }
15472                    } else {
15473                        try {
15474                            pw.flush();
15475                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15476                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15477                        } catch (RemoteException e) {
15478                            if (!isCheckinRequest) {
15479                                pw.println("Got RemoteException!");
15480                                pw.flush();
15481                            }
15482                        }
15483                    }
15484                }
15485
15486                final long myTotalPss = mi.getTotalPss();
15487                final long myTotalUss = mi.getTotalUss();
15488                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15489
15490                synchronized (this) {
15491                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15492                        // Record this for posterity if the process has been stable.
15493                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15494                    }
15495                }
15496
15497                if (!isCheckinRequest && mi != null) {
15498                    totalPss += myTotalPss;
15499                    totalSwapPss += myTotalSwapPss;
15500                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15501                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15502                            myTotalSwapPss, pid, hasActivities);
15503                    procMems.add(pssItem);
15504                    procMemsMap.put(pid, pssItem);
15505
15506                    nativePss += mi.nativePss;
15507                    nativeSwapPss += mi.nativeSwappedOutPss;
15508                    dalvikPss += mi.dalvikPss;
15509                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15510                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15511                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15512                        dalvikSubitemSwapPss[j] +=
15513                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15514                    }
15515                    otherPss += mi.otherPss;
15516                    otherSwapPss += mi.otherSwappedOutPss;
15517                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15518                        long mem = mi.getOtherPss(j);
15519                        miscPss[j] += mem;
15520                        otherPss -= mem;
15521                        mem = mi.getOtherSwappedOutPss(j);
15522                        miscSwapPss[j] += mem;
15523                        otherSwapPss -= mem;
15524                    }
15525
15526                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15527                        cachedPss += myTotalPss;
15528                        cachedSwapPss += myTotalSwapPss;
15529                    }
15530
15531                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15532                        if (oomIndex == (oomPss.length - 1)
15533                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15534                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15535                            oomPss[oomIndex] += myTotalPss;
15536                            oomSwapPss[oomIndex] += myTotalSwapPss;
15537                            if (oomProcs[oomIndex] == null) {
15538                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15539                            }
15540                            oomProcs[oomIndex].add(pssItem);
15541                            break;
15542                        }
15543                    }
15544                }
15545            }
15546        }
15547
15548        long nativeProcTotalPss = 0;
15549
15550        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15551            // If we are showing aggregations, also look for native processes to
15552            // include so that our aggregations are more accurate.
15553            updateCpuStatsNow();
15554            mi = null;
15555            synchronized (mProcessCpuTracker) {
15556                final int N = mProcessCpuTracker.countStats();
15557                for (int i=0; i<N; i++) {
15558                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15559                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15560                        if (mi == null) {
15561                            mi = new Debug.MemoryInfo();
15562                        }
15563                        if (!brief && !oomOnly) {
15564                            Debug.getMemoryInfo(st.pid, mi);
15565                        } else {
15566                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15567                            mi.nativePrivateDirty = (int)tmpLong[0];
15568                        }
15569
15570                        final long myTotalPss = mi.getTotalPss();
15571                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15572                        totalPss += myTotalPss;
15573                        nativeProcTotalPss += myTotalPss;
15574
15575                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15576                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15577                        procMems.add(pssItem);
15578
15579                        nativePss += mi.nativePss;
15580                        nativeSwapPss += mi.nativeSwappedOutPss;
15581                        dalvikPss += mi.dalvikPss;
15582                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15583                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15584                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15585                            dalvikSubitemSwapPss[j] +=
15586                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15587                        }
15588                        otherPss += mi.otherPss;
15589                        otherSwapPss += mi.otherSwappedOutPss;
15590                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15591                            long mem = mi.getOtherPss(j);
15592                            miscPss[j] += mem;
15593                            otherPss -= mem;
15594                            mem = mi.getOtherSwappedOutPss(j);
15595                            miscSwapPss[j] += mem;
15596                            otherSwapPss -= mem;
15597                        }
15598                        oomPss[0] += myTotalPss;
15599                        oomSwapPss[0] += myTotalSwapPss;
15600                        if (oomProcs[0] == null) {
15601                            oomProcs[0] = new ArrayList<MemItem>();
15602                        }
15603                        oomProcs[0].add(pssItem);
15604                    }
15605                }
15606            }
15607
15608            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15609
15610            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15611            final MemItem dalvikItem =
15612                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15613            if (dalvikSubitemPss.length > 0) {
15614                dalvikItem.subitems = new ArrayList<MemItem>();
15615                for (int j=0; j<dalvikSubitemPss.length; j++) {
15616                    final String name = Debug.MemoryInfo.getOtherLabel(
15617                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15618                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15619                                    dalvikSubitemSwapPss[j], j));
15620                }
15621            }
15622            catMems.add(dalvikItem);
15623            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15624            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15625                String label = Debug.MemoryInfo.getOtherLabel(j);
15626                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15627            }
15628
15629            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15630            for (int j=0; j<oomPss.length; j++) {
15631                if (oomPss[j] != 0) {
15632                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15633                            : DUMP_MEM_OOM_LABEL[j];
15634                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15635                            DUMP_MEM_OOM_ADJ[j]);
15636                    item.subitems = oomProcs[j];
15637                    oomMems.add(item);
15638                }
15639            }
15640
15641            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15642            if (!brief && !oomOnly && !isCompact) {
15643                pw.println();
15644                pw.println("Total PSS by process:");
15645                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15646                pw.println();
15647            }
15648            if (!isCompact) {
15649                pw.println("Total PSS by OOM adjustment:");
15650            }
15651            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15652            if (!brief && !oomOnly) {
15653                PrintWriter out = categoryPw != null ? categoryPw : pw;
15654                if (!isCompact) {
15655                    out.println();
15656                    out.println("Total PSS by category:");
15657                }
15658                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15659            }
15660            if (!isCompact) {
15661                pw.println();
15662            }
15663            MemInfoReader memInfo = new MemInfoReader();
15664            memInfo.readMemInfo();
15665            if (nativeProcTotalPss > 0) {
15666                synchronized (this) {
15667                    final long cachedKb = memInfo.getCachedSizeKb();
15668                    final long freeKb = memInfo.getFreeSizeKb();
15669                    final long zramKb = memInfo.getZramTotalSizeKb();
15670                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15671                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15672                            kernelKb*1024, nativeProcTotalPss*1024);
15673                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15674                            nativeProcTotalPss);
15675                }
15676            }
15677            if (!brief) {
15678                if (!isCompact) {
15679                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15680                    pw.print(" (status ");
15681                    switch (mLastMemoryLevel) {
15682                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15683                            pw.println("normal)");
15684                            break;
15685                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15686                            pw.println("moderate)");
15687                            break;
15688                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15689                            pw.println("low)");
15690                            break;
15691                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15692                            pw.println("critical)");
15693                            break;
15694                        default:
15695                            pw.print(mLastMemoryLevel);
15696                            pw.println(")");
15697                            break;
15698                    }
15699                    pw.print(" Free RAM: ");
15700                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15701                            + memInfo.getFreeSizeKb()));
15702                    pw.print(" (");
15703                    pw.print(stringifyKBSize(cachedPss));
15704                    pw.print(" cached pss + ");
15705                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15706                    pw.print(" cached kernel + ");
15707                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15708                    pw.println(" free)");
15709                } else {
15710                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15711                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15712                            + memInfo.getFreeSizeKb()); pw.print(",");
15713                    pw.println(totalPss - cachedPss);
15714                }
15715            }
15716            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15717                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15718                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15719            if (!isCompact) {
15720                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15721                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15722                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15723                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15724                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15725            } else {
15726                pw.print("lostram,"); pw.println(lostRAM);
15727            }
15728            if (!brief) {
15729                if (memInfo.getZramTotalSizeKb() != 0) {
15730                    if (!isCompact) {
15731                        pw.print("     ZRAM: ");
15732                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15733                                pw.print(" physical used for ");
15734                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15735                                        - memInfo.getSwapFreeSizeKb()));
15736                                pw.print(" in swap (");
15737                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15738                                pw.println(" total swap)");
15739                    } else {
15740                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15741                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15742                                pw.println(memInfo.getSwapFreeSizeKb());
15743                    }
15744                }
15745                final long[] ksm = getKsmInfo();
15746                if (!isCompact) {
15747                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15748                            || ksm[KSM_VOLATILE] != 0) {
15749                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15750                                pw.print(" saved from shared ");
15751                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15752                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15753                                pw.print(" unshared; ");
15754                                pw.print(stringifyKBSize(
15755                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15756                    }
15757                    pw.print("   Tuning: ");
15758                    pw.print(ActivityManager.staticGetMemoryClass());
15759                    pw.print(" (large ");
15760                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15761                    pw.print("), oom ");
15762                    pw.print(stringifySize(
15763                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15764                    pw.print(", restore limit ");
15765                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15766                    if (ActivityManager.isLowRamDeviceStatic()) {
15767                        pw.print(" (low-ram)");
15768                    }
15769                    if (ActivityManager.isHighEndGfx()) {
15770                        pw.print(" (high-end-gfx)");
15771                    }
15772                    pw.println();
15773                } else {
15774                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15775                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15776                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15777                    pw.print("tuning,");
15778                    pw.print(ActivityManager.staticGetMemoryClass());
15779                    pw.print(',');
15780                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15781                    pw.print(',');
15782                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15783                    if (ActivityManager.isLowRamDeviceStatic()) {
15784                        pw.print(",low-ram");
15785                    }
15786                    if (ActivityManager.isHighEndGfx()) {
15787                        pw.print(",high-end-gfx");
15788                    }
15789                    pw.println();
15790                }
15791            }
15792        }
15793    }
15794
15795    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15796            long memtrack, String name) {
15797        sb.append("  ");
15798        sb.append(ProcessList.makeOomAdjString(oomAdj));
15799        sb.append(' ');
15800        sb.append(ProcessList.makeProcStateString(procState));
15801        sb.append(' ');
15802        ProcessList.appendRamKb(sb, pss);
15803        sb.append(": ");
15804        sb.append(name);
15805        if (memtrack > 0) {
15806            sb.append(" (");
15807            sb.append(stringifyKBSize(memtrack));
15808            sb.append(" memtrack)");
15809        }
15810    }
15811
15812    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15813        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15814        sb.append(" (pid ");
15815        sb.append(mi.pid);
15816        sb.append(") ");
15817        sb.append(mi.adjType);
15818        sb.append('\n');
15819        if (mi.adjReason != null) {
15820            sb.append("                      ");
15821            sb.append(mi.adjReason);
15822            sb.append('\n');
15823        }
15824    }
15825
15826    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15827        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15828        for (int i=0, N=memInfos.size(); i<N; i++) {
15829            ProcessMemInfo mi = memInfos.get(i);
15830            infoMap.put(mi.pid, mi);
15831        }
15832        updateCpuStatsNow();
15833        long[] memtrackTmp = new long[1];
15834        synchronized (mProcessCpuTracker) {
15835            final int N = mProcessCpuTracker.countStats();
15836            for (int i=0; i<N; i++) {
15837                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15838                if (st.vsize > 0) {
15839                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15840                    if (pss > 0) {
15841                        if (infoMap.indexOfKey(st.pid) < 0) {
15842                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15843                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15844                            mi.pss = pss;
15845                            mi.memtrack = memtrackTmp[0];
15846                            memInfos.add(mi);
15847                        }
15848                    }
15849                }
15850            }
15851        }
15852
15853        long totalPss = 0;
15854        long totalMemtrack = 0;
15855        for (int i=0, N=memInfos.size(); i<N; i++) {
15856            ProcessMemInfo mi = memInfos.get(i);
15857            if (mi.pss == 0) {
15858                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15859                mi.memtrack = memtrackTmp[0];
15860            }
15861            totalPss += mi.pss;
15862            totalMemtrack += mi.memtrack;
15863        }
15864        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15865            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15866                if (lhs.oomAdj != rhs.oomAdj) {
15867                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15868                }
15869                if (lhs.pss != rhs.pss) {
15870                    return lhs.pss < rhs.pss ? 1 : -1;
15871                }
15872                return 0;
15873            }
15874        });
15875
15876        StringBuilder tag = new StringBuilder(128);
15877        StringBuilder stack = new StringBuilder(128);
15878        tag.append("Low on memory -- ");
15879        appendMemBucket(tag, totalPss, "total", false);
15880        appendMemBucket(stack, totalPss, "total", true);
15881
15882        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15883        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15884        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15885
15886        boolean firstLine = true;
15887        int lastOomAdj = Integer.MIN_VALUE;
15888        long extraNativeRam = 0;
15889        long extraNativeMemtrack = 0;
15890        long cachedPss = 0;
15891        for (int i=0, N=memInfos.size(); i<N; i++) {
15892            ProcessMemInfo mi = memInfos.get(i);
15893
15894            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15895                cachedPss += mi.pss;
15896            }
15897
15898            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15899                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15900                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15901                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15902                if (lastOomAdj != mi.oomAdj) {
15903                    lastOomAdj = mi.oomAdj;
15904                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15905                        tag.append(" / ");
15906                    }
15907                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15908                        if (firstLine) {
15909                            stack.append(":");
15910                            firstLine = false;
15911                        }
15912                        stack.append("\n\t at ");
15913                    } else {
15914                        stack.append("$");
15915                    }
15916                } else {
15917                    tag.append(" ");
15918                    stack.append("$");
15919                }
15920                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15921                    appendMemBucket(tag, mi.pss, mi.name, false);
15922                }
15923                appendMemBucket(stack, mi.pss, mi.name, true);
15924                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15925                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15926                    stack.append("(");
15927                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15928                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15929                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15930                            stack.append(":");
15931                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15932                        }
15933                    }
15934                    stack.append(")");
15935                }
15936            }
15937
15938            appendMemInfo(fullNativeBuilder, mi);
15939            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15940                // The short form only has native processes that are >= 512K.
15941                if (mi.pss >= 512) {
15942                    appendMemInfo(shortNativeBuilder, mi);
15943                } else {
15944                    extraNativeRam += mi.pss;
15945                    extraNativeMemtrack += mi.memtrack;
15946                }
15947            } else {
15948                // Short form has all other details, but if we have collected RAM
15949                // from smaller native processes let's dump a summary of that.
15950                if (extraNativeRam > 0) {
15951                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15952                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15953                    shortNativeBuilder.append('\n');
15954                    extraNativeRam = 0;
15955                }
15956                appendMemInfo(fullJavaBuilder, mi);
15957            }
15958        }
15959
15960        fullJavaBuilder.append("           ");
15961        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15962        fullJavaBuilder.append(": TOTAL");
15963        if (totalMemtrack > 0) {
15964            fullJavaBuilder.append(" (");
15965            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15966            fullJavaBuilder.append(" memtrack)");
15967        } else {
15968        }
15969        fullJavaBuilder.append("\n");
15970
15971        MemInfoReader memInfo = new MemInfoReader();
15972        memInfo.readMemInfo();
15973        final long[] infos = memInfo.getRawInfo();
15974
15975        StringBuilder memInfoBuilder = new StringBuilder(1024);
15976        Debug.getMemInfo(infos);
15977        memInfoBuilder.append("  MemInfo: ");
15978        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15979        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15980        memInfoBuilder.append(stringifyKBSize(
15981                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15982        memInfoBuilder.append(stringifyKBSize(
15983                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15984        memInfoBuilder.append(stringifyKBSize(
15985                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15986        memInfoBuilder.append("           ");
15987        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15988        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15989        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15990        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15991        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15992            memInfoBuilder.append("  ZRAM: ");
15993            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15994            memInfoBuilder.append(" RAM, ");
15995            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15996            memInfoBuilder.append(" swap total, ");
15997            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15998            memInfoBuilder.append(" swap free\n");
15999        }
16000        final long[] ksm = getKsmInfo();
16001        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16002                || ksm[KSM_VOLATILE] != 0) {
16003            memInfoBuilder.append("  KSM: ");
16004            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16005            memInfoBuilder.append(" saved from shared ");
16006            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16007            memInfoBuilder.append("\n       ");
16008            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16009            memInfoBuilder.append(" unshared; ");
16010            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16011            memInfoBuilder.append(" volatile\n");
16012        }
16013        memInfoBuilder.append("  Free RAM: ");
16014        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16015                + memInfo.getFreeSizeKb()));
16016        memInfoBuilder.append("\n");
16017        memInfoBuilder.append("  Used RAM: ");
16018        memInfoBuilder.append(stringifyKBSize(
16019                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16020        memInfoBuilder.append("\n");
16021        memInfoBuilder.append("  Lost RAM: ");
16022        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16023                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16024                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16025        memInfoBuilder.append("\n");
16026        Slog.i(TAG, "Low on memory:");
16027        Slog.i(TAG, shortNativeBuilder.toString());
16028        Slog.i(TAG, fullJavaBuilder.toString());
16029        Slog.i(TAG, memInfoBuilder.toString());
16030
16031        StringBuilder dropBuilder = new StringBuilder(1024);
16032        /*
16033        StringWriter oomSw = new StringWriter();
16034        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16035        StringWriter catSw = new StringWriter();
16036        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16037        String[] emptyArgs = new String[] { };
16038        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16039        oomPw.flush();
16040        String oomString = oomSw.toString();
16041        */
16042        dropBuilder.append("Low on memory:");
16043        dropBuilder.append(stack);
16044        dropBuilder.append('\n');
16045        dropBuilder.append(fullNativeBuilder);
16046        dropBuilder.append(fullJavaBuilder);
16047        dropBuilder.append('\n');
16048        dropBuilder.append(memInfoBuilder);
16049        dropBuilder.append('\n');
16050        /*
16051        dropBuilder.append(oomString);
16052        dropBuilder.append('\n');
16053        */
16054        StringWriter catSw = new StringWriter();
16055        synchronized (ActivityManagerService.this) {
16056            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16057            String[] emptyArgs = new String[] { };
16058            catPw.println();
16059            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16060            catPw.println();
16061            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16062                    false, false, null);
16063            catPw.println();
16064            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16065            catPw.flush();
16066        }
16067        dropBuilder.append(catSw.toString());
16068        addErrorToDropBox("lowmem", null, "system_server", null,
16069                null, tag.toString(), dropBuilder.toString(), null, null);
16070        //Slog.i(TAG, "Sent to dropbox:");
16071        //Slog.i(TAG, dropBuilder.toString());
16072        synchronized (ActivityManagerService.this) {
16073            long now = SystemClock.uptimeMillis();
16074            if (mLastMemUsageReportTime < now) {
16075                mLastMemUsageReportTime = now;
16076            }
16077        }
16078    }
16079
16080    /**
16081     * Searches array of arguments for the specified string
16082     * @param args array of argument strings
16083     * @param value value to search for
16084     * @return true if the value is contained in the array
16085     */
16086    private static boolean scanArgs(String[] args, String value) {
16087        if (args != null) {
16088            for (String arg : args) {
16089                if (value.equals(arg)) {
16090                    return true;
16091                }
16092            }
16093        }
16094        return false;
16095    }
16096
16097    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16098            ContentProviderRecord cpr, boolean always) {
16099        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16100
16101        if (!inLaunching || always) {
16102            synchronized (cpr) {
16103                cpr.launchingApp = null;
16104                cpr.notifyAll();
16105            }
16106            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16107            String names[] = cpr.info.authority.split(";");
16108            for (int j = 0; j < names.length; j++) {
16109                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16110            }
16111        }
16112
16113        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16114            ContentProviderConnection conn = cpr.connections.get(i);
16115            if (conn.waiting) {
16116                // If this connection is waiting for the provider, then we don't
16117                // need to mess with its process unless we are always removing
16118                // or for some reason the provider is not currently launching.
16119                if (inLaunching && !always) {
16120                    continue;
16121                }
16122            }
16123            ProcessRecord capp = conn.client;
16124            conn.dead = true;
16125            if (conn.stableCount > 0) {
16126                if (!capp.persistent && capp.thread != null
16127                        && capp.pid != 0
16128                        && capp.pid != MY_PID) {
16129                    capp.kill("depends on provider "
16130                            + cpr.name.flattenToShortString()
16131                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16132                }
16133            } else if (capp.thread != null && conn.provider.provider != null) {
16134                try {
16135                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16136                } catch (RemoteException e) {
16137                }
16138                // In the protocol here, we don't expect the client to correctly
16139                // clean up this connection, we'll just remove it.
16140                cpr.connections.remove(i);
16141                if (conn.client.conProviders.remove(conn)) {
16142                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16143                }
16144            }
16145        }
16146
16147        if (inLaunching && always) {
16148            mLaunchingProviders.remove(cpr);
16149        }
16150        return inLaunching;
16151    }
16152
16153    /**
16154     * Main code for cleaning up a process when it has gone away.  This is
16155     * called both as a result of the process dying, or directly when stopping
16156     * a process when running in single process mode.
16157     *
16158     * @return Returns true if the given process has been restarted, so the
16159     * app that was passed in must remain on the process lists.
16160     */
16161    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16162            boolean restarting, boolean allowRestart, int index) {
16163        if (index >= 0) {
16164            removeLruProcessLocked(app);
16165            ProcessList.remove(app.pid);
16166        }
16167
16168        mProcessesToGc.remove(app);
16169        mPendingPssProcesses.remove(app);
16170
16171        // Dismiss any open dialogs.
16172        if (app.crashDialog != null && !app.forceCrashReport) {
16173            app.crashDialog.dismiss();
16174            app.crashDialog = null;
16175        }
16176        if (app.anrDialog != null) {
16177            app.anrDialog.dismiss();
16178            app.anrDialog = null;
16179        }
16180        if (app.waitDialog != null) {
16181            app.waitDialog.dismiss();
16182            app.waitDialog = null;
16183        }
16184
16185        app.crashing = false;
16186        app.notResponding = false;
16187
16188        app.resetPackageList(mProcessStats);
16189        app.unlinkDeathRecipient();
16190        app.makeInactive(mProcessStats);
16191        app.waitingToKill = null;
16192        app.forcingToForeground = null;
16193        updateProcessForegroundLocked(app, false, false);
16194        app.foregroundActivities = false;
16195        app.hasShownUi = false;
16196        app.treatLikeActivity = false;
16197        app.hasAboveClient = false;
16198        app.hasClientActivities = false;
16199
16200        mServices.killServicesLocked(app, allowRestart);
16201
16202        boolean restart = false;
16203
16204        // Remove published content providers.
16205        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16206            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16207            final boolean always = app.bad || !allowRestart;
16208            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16209            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16210                // We left the provider in the launching list, need to
16211                // restart it.
16212                restart = true;
16213            }
16214
16215            cpr.provider = null;
16216            cpr.proc = null;
16217        }
16218        app.pubProviders.clear();
16219
16220        // Take care of any launching providers waiting for this process.
16221        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16222            restart = true;
16223        }
16224
16225        // Unregister from connected content providers.
16226        if (!app.conProviders.isEmpty()) {
16227            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16228                ContentProviderConnection conn = app.conProviders.get(i);
16229                conn.provider.connections.remove(conn);
16230                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16231                        conn.provider.name);
16232            }
16233            app.conProviders.clear();
16234        }
16235
16236        // At this point there may be remaining entries in mLaunchingProviders
16237        // where we were the only one waiting, so they are no longer of use.
16238        // Look for these and clean up if found.
16239        // XXX Commented out for now.  Trying to figure out a way to reproduce
16240        // the actual situation to identify what is actually going on.
16241        if (false) {
16242            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16243                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16244                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16245                    synchronized (cpr) {
16246                        cpr.launchingApp = null;
16247                        cpr.notifyAll();
16248                    }
16249                }
16250            }
16251        }
16252
16253        skipCurrentReceiverLocked(app);
16254
16255        // Unregister any receivers.
16256        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16257            removeReceiverLocked(app.receivers.valueAt(i));
16258        }
16259        app.receivers.clear();
16260
16261        // If the app is undergoing backup, tell the backup manager about it
16262        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16263            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16264                    + mBackupTarget.appInfo + " died during backup");
16265            try {
16266                IBackupManager bm = IBackupManager.Stub.asInterface(
16267                        ServiceManager.getService(Context.BACKUP_SERVICE));
16268                bm.agentDisconnected(app.info.packageName);
16269            } catch (RemoteException e) {
16270                // can't happen; backup manager is local
16271            }
16272        }
16273
16274        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16275            ProcessChangeItem item = mPendingProcessChanges.get(i);
16276            if (item.pid == app.pid) {
16277                mPendingProcessChanges.remove(i);
16278                mAvailProcessChanges.add(item);
16279            }
16280        }
16281        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16282                null).sendToTarget();
16283
16284        // If the caller is restarting this app, then leave it in its
16285        // current lists and let the caller take care of it.
16286        if (restarting) {
16287            return false;
16288        }
16289
16290        if (!app.persistent || app.isolated) {
16291            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16292                    "Removing non-persistent process during cleanup: " + app);
16293            removeProcessNameLocked(app.processName, app.uid);
16294            if (mHeavyWeightProcess == app) {
16295                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16296                        mHeavyWeightProcess.userId, 0));
16297                mHeavyWeightProcess = null;
16298            }
16299        } else if (!app.removed) {
16300            // This app is persistent, so we need to keep its record around.
16301            // If it is not already on the pending app list, add it there
16302            // and start a new process for it.
16303            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16304                mPersistentStartingProcesses.add(app);
16305                restart = true;
16306            }
16307        }
16308        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16309                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16310        mProcessesOnHold.remove(app);
16311
16312        if (app == mHomeProcess) {
16313            mHomeProcess = null;
16314        }
16315        if (app == mPreviousProcess) {
16316            mPreviousProcess = null;
16317        }
16318
16319        if (restart && !app.isolated) {
16320            // We have components that still need to be running in the
16321            // process, so re-launch it.
16322            if (index < 0) {
16323                ProcessList.remove(app.pid);
16324            }
16325            addProcessNameLocked(app);
16326            startProcessLocked(app, "restart", app.processName);
16327            return true;
16328        } else if (app.pid > 0 && app.pid != MY_PID) {
16329            // Goodbye!
16330            boolean removed;
16331            synchronized (mPidsSelfLocked) {
16332                mPidsSelfLocked.remove(app.pid);
16333                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16334            }
16335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16336            if (app.isolated) {
16337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16338            }
16339            app.setPid(0);
16340        }
16341        return false;
16342    }
16343
16344    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16345        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16346            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16347            if (cpr.launchingApp == app) {
16348                return true;
16349            }
16350        }
16351        return false;
16352    }
16353
16354    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16355        // Look through the content providers we are waiting to have launched,
16356        // and if any run in this process then either schedule a restart of
16357        // the process or kill the client waiting for it if this process has
16358        // gone bad.
16359        boolean restart = false;
16360        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16361            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16362            if (cpr.launchingApp == app) {
16363                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16364                    restart = true;
16365                } else {
16366                    removeDyingProviderLocked(app, cpr, true);
16367                }
16368            }
16369        }
16370        return restart;
16371    }
16372
16373    // =========================================================
16374    // SERVICES
16375    // =========================================================
16376
16377    @Override
16378    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16379            int flags) {
16380        enforceNotIsolatedCaller("getServices");
16381        synchronized (this) {
16382            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16383        }
16384    }
16385
16386    @Override
16387    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16388        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16389        synchronized (this) {
16390            return mServices.getRunningServiceControlPanelLocked(name);
16391        }
16392    }
16393
16394    @Override
16395    public ComponentName startService(IApplicationThread caller, Intent service,
16396            String resolvedType, String callingPackage, int userId)
16397            throws TransactionTooLargeException {
16398        enforceNotIsolatedCaller("startService");
16399        // Refuse possible leaked file descriptors
16400        if (service != null && service.hasFileDescriptors() == true) {
16401            throw new IllegalArgumentException("File descriptors passed in Intent");
16402        }
16403
16404        if (callingPackage == null) {
16405            throw new IllegalArgumentException("callingPackage cannot be null");
16406        }
16407
16408        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16409                "startService: " + service + " type=" + resolvedType);
16410        synchronized(this) {
16411            final int callingPid = Binder.getCallingPid();
16412            final int callingUid = Binder.getCallingUid();
16413            final long origId = Binder.clearCallingIdentity();
16414            ComponentName res = mServices.startServiceLocked(caller, service,
16415                    resolvedType, callingPid, callingUid, callingPackage, userId);
16416            Binder.restoreCallingIdentity(origId);
16417            return res;
16418        }
16419    }
16420
16421    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16422            String callingPackage, int userId)
16423            throws TransactionTooLargeException {
16424        synchronized(this) {
16425            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16426                    "startServiceInPackage: " + service + " type=" + resolvedType);
16427            final long origId = Binder.clearCallingIdentity();
16428            ComponentName res = mServices.startServiceLocked(null, service,
16429                    resolvedType, -1, uid, callingPackage, userId);
16430            Binder.restoreCallingIdentity(origId);
16431            return res;
16432        }
16433    }
16434
16435    @Override
16436    public int stopService(IApplicationThread caller, Intent service,
16437            String resolvedType, int userId) {
16438        enforceNotIsolatedCaller("stopService");
16439        // Refuse possible leaked file descriptors
16440        if (service != null && service.hasFileDescriptors() == true) {
16441            throw new IllegalArgumentException("File descriptors passed in Intent");
16442        }
16443
16444        synchronized(this) {
16445            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16446        }
16447    }
16448
16449    @Override
16450    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16451        enforceNotIsolatedCaller("peekService");
16452        // Refuse possible leaked file descriptors
16453        if (service != null && service.hasFileDescriptors() == true) {
16454            throw new IllegalArgumentException("File descriptors passed in Intent");
16455        }
16456
16457        if (callingPackage == null) {
16458            throw new IllegalArgumentException("callingPackage cannot be null");
16459        }
16460
16461        synchronized(this) {
16462            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16463        }
16464    }
16465
16466    @Override
16467    public boolean stopServiceToken(ComponentName className, IBinder token,
16468            int startId) {
16469        synchronized(this) {
16470            return mServices.stopServiceTokenLocked(className, token, startId);
16471        }
16472    }
16473
16474    @Override
16475    public void setServiceForeground(ComponentName className, IBinder token,
16476            int id, Notification notification, int flags) {
16477        synchronized(this) {
16478            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16479        }
16480    }
16481
16482    @Override
16483    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16484            boolean requireFull, String name, String callerPackage) {
16485        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16486                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16487    }
16488
16489    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16490            String className, int flags) {
16491        boolean result = false;
16492        // For apps that don't have pre-defined UIDs, check for permission
16493        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16494            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16495                if (ActivityManager.checkUidPermission(
16496                        INTERACT_ACROSS_USERS,
16497                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16498                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16499                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16500                            + " requests FLAG_SINGLE_USER, but app does not hold "
16501                            + INTERACT_ACROSS_USERS;
16502                    Slog.w(TAG, msg);
16503                    throw new SecurityException(msg);
16504                }
16505                // Permission passed
16506                result = true;
16507            }
16508        } else if ("system".equals(componentProcessName)) {
16509            result = true;
16510        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16511            // Phone app and persistent apps are allowed to export singleuser providers.
16512            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16513                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16514        }
16515        if (DEBUG_MU) Slog.v(TAG_MU,
16516                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16517                + Integer.toHexString(flags) + ") = " + result);
16518        return result;
16519    }
16520
16521    /**
16522     * Checks to see if the caller is in the same app as the singleton
16523     * component, or the component is in a special app. It allows special apps
16524     * to export singleton components but prevents exporting singleton
16525     * components for regular apps.
16526     */
16527    boolean isValidSingletonCall(int callingUid, int componentUid) {
16528        int componentAppId = UserHandle.getAppId(componentUid);
16529        return UserHandle.isSameApp(callingUid, componentUid)
16530                || componentAppId == Process.SYSTEM_UID
16531                || componentAppId == Process.PHONE_UID
16532                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16533                        == PackageManager.PERMISSION_GRANTED;
16534    }
16535
16536    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16537            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16538            int userId) throws TransactionTooLargeException {
16539        enforceNotIsolatedCaller("bindService");
16540
16541        // Refuse possible leaked file descriptors
16542        if (service != null && service.hasFileDescriptors() == true) {
16543            throw new IllegalArgumentException("File descriptors passed in Intent");
16544        }
16545
16546        if (callingPackage == null) {
16547            throw new IllegalArgumentException("callingPackage cannot be null");
16548        }
16549
16550        synchronized(this) {
16551            return mServices.bindServiceLocked(caller, token, service,
16552                    resolvedType, connection, flags, callingPackage, userId);
16553        }
16554    }
16555
16556    public boolean unbindService(IServiceConnection connection) {
16557        synchronized (this) {
16558            return mServices.unbindServiceLocked(connection);
16559        }
16560    }
16561
16562    public void publishService(IBinder token, Intent intent, IBinder service) {
16563        // Refuse possible leaked file descriptors
16564        if (intent != null && intent.hasFileDescriptors() == true) {
16565            throw new IllegalArgumentException("File descriptors passed in Intent");
16566        }
16567
16568        synchronized(this) {
16569            if (!(token instanceof ServiceRecord)) {
16570                throw new IllegalArgumentException("Invalid service token");
16571            }
16572            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16573        }
16574    }
16575
16576    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16577        // Refuse possible leaked file descriptors
16578        if (intent != null && intent.hasFileDescriptors() == true) {
16579            throw new IllegalArgumentException("File descriptors passed in Intent");
16580        }
16581
16582        synchronized(this) {
16583            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16584        }
16585    }
16586
16587    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16588        synchronized(this) {
16589            if (!(token instanceof ServiceRecord)) {
16590                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16591                throw new IllegalArgumentException("Invalid service token");
16592            }
16593            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16594        }
16595    }
16596
16597    // =========================================================
16598    // BACKUP AND RESTORE
16599    // =========================================================
16600
16601    // Cause the target app to be launched if necessary and its backup agent
16602    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16603    // activity manager to announce its creation.
16604    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16605        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16606                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16607        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16608
16609        synchronized(this) {
16610            // !!! TODO: currently no check here that we're already bound
16611            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16612            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16613            synchronized (stats) {
16614                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16615            }
16616
16617            // Backup agent is now in use, its package can't be stopped.
16618            try {
16619                AppGlobals.getPackageManager().setPackageStoppedState(
16620                        app.packageName, false, UserHandle.getUserId(app.uid));
16621            } catch (RemoteException e) {
16622            } catch (IllegalArgumentException e) {
16623                Slog.w(TAG, "Failed trying to unstop package "
16624                        + app.packageName + ": " + e);
16625            }
16626
16627            BackupRecord r = new BackupRecord(ss, app, backupMode);
16628            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16629                    ? new ComponentName(app.packageName, app.backupAgentName)
16630                    : new ComponentName("android", "FullBackupAgent");
16631            // startProcessLocked() returns existing proc's record if it's already running
16632            ProcessRecord proc = startProcessLocked(app.processName, app,
16633                    false, 0, "backup", hostingName, false, false, false);
16634            if (proc == null) {
16635                Slog.e(TAG, "Unable to start backup agent process " + r);
16636                return false;
16637            }
16638
16639            r.app = proc;
16640            mBackupTarget = r;
16641            mBackupAppName = app.packageName;
16642
16643            // Try not to kill the process during backup
16644            updateOomAdjLocked(proc);
16645
16646            // If the process is already attached, schedule the creation of the backup agent now.
16647            // If it is not yet live, this will be done when it attaches to the framework.
16648            if (proc.thread != null) {
16649                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16650                try {
16651                    proc.thread.scheduleCreateBackupAgent(app,
16652                            compatibilityInfoForPackageLocked(app), backupMode);
16653                } catch (RemoteException e) {
16654                    // Will time out on the backup manager side
16655                }
16656            } else {
16657                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16658            }
16659            // Invariants: at this point, the target app process exists and the application
16660            // is either already running or in the process of coming up.  mBackupTarget and
16661            // mBackupAppName describe the app, so that when it binds back to the AM we
16662            // know that it's scheduled for a backup-agent operation.
16663        }
16664
16665        return true;
16666    }
16667
16668    @Override
16669    public void clearPendingBackup() {
16670        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16671        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16672
16673        synchronized (this) {
16674            mBackupTarget = null;
16675            mBackupAppName = null;
16676        }
16677    }
16678
16679    // A backup agent has just come up
16680    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16681        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16682                + " = " + agent);
16683
16684        synchronized(this) {
16685            if (!agentPackageName.equals(mBackupAppName)) {
16686                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16687                return;
16688            }
16689        }
16690
16691        long oldIdent = Binder.clearCallingIdentity();
16692        try {
16693            IBackupManager bm = IBackupManager.Stub.asInterface(
16694                    ServiceManager.getService(Context.BACKUP_SERVICE));
16695            bm.agentConnected(agentPackageName, agent);
16696        } catch (RemoteException e) {
16697            // can't happen; the backup manager service is local
16698        } catch (Exception e) {
16699            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16700            e.printStackTrace();
16701        } finally {
16702            Binder.restoreCallingIdentity(oldIdent);
16703        }
16704    }
16705
16706    // done with this agent
16707    public void unbindBackupAgent(ApplicationInfo appInfo) {
16708        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16709        if (appInfo == null) {
16710            Slog.w(TAG, "unbind backup agent for null app");
16711            return;
16712        }
16713
16714        synchronized(this) {
16715            try {
16716                if (mBackupAppName == null) {
16717                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16718                    return;
16719                }
16720
16721                if (!mBackupAppName.equals(appInfo.packageName)) {
16722                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16723                    return;
16724                }
16725
16726                // Not backing this app up any more; reset its OOM adjustment
16727                final ProcessRecord proc = mBackupTarget.app;
16728                updateOomAdjLocked(proc);
16729
16730                // If the app crashed during backup, 'thread' will be null here
16731                if (proc.thread != null) {
16732                    try {
16733                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16734                                compatibilityInfoForPackageLocked(appInfo));
16735                    } catch (Exception e) {
16736                        Slog.e(TAG, "Exception when unbinding backup agent:");
16737                        e.printStackTrace();
16738                    }
16739                }
16740            } finally {
16741                mBackupTarget = null;
16742                mBackupAppName = null;
16743            }
16744        }
16745    }
16746    // =========================================================
16747    // BROADCASTS
16748    // =========================================================
16749
16750    boolean isPendingBroadcastProcessLocked(int pid) {
16751        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16752                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16753    }
16754
16755    void skipPendingBroadcastLocked(int pid) {
16756            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16757            for (BroadcastQueue queue : mBroadcastQueues) {
16758                queue.skipPendingBroadcastLocked(pid);
16759            }
16760    }
16761
16762    // The app just attached; send any pending broadcasts that it should receive
16763    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16764        boolean didSomething = false;
16765        for (BroadcastQueue queue : mBroadcastQueues) {
16766            didSomething |= queue.sendPendingBroadcastsLocked(app);
16767        }
16768        return didSomething;
16769    }
16770
16771    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16772            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16773        enforceNotIsolatedCaller("registerReceiver");
16774        ArrayList<Intent> stickyIntents = null;
16775        ProcessRecord callerApp = null;
16776        int callingUid;
16777        int callingPid;
16778        synchronized(this) {
16779            if (caller != null) {
16780                callerApp = getRecordForAppLocked(caller);
16781                if (callerApp == null) {
16782                    throw new SecurityException(
16783                            "Unable to find app for caller " + caller
16784                            + " (pid=" + Binder.getCallingPid()
16785                            + ") when registering receiver " + receiver);
16786                }
16787                if (callerApp.info.uid != Process.SYSTEM_UID &&
16788                        !callerApp.pkgList.containsKey(callerPackage) &&
16789                        !"android".equals(callerPackage)) {
16790                    throw new SecurityException("Given caller package " + callerPackage
16791                            + " is not running in process " + callerApp);
16792                }
16793                callingUid = callerApp.info.uid;
16794                callingPid = callerApp.pid;
16795            } else {
16796                callerPackage = null;
16797                callingUid = Binder.getCallingUid();
16798                callingPid = Binder.getCallingPid();
16799            }
16800
16801            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16802                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16803
16804            Iterator<String> actions = filter.actionsIterator();
16805            if (actions == null) {
16806                ArrayList<String> noAction = new ArrayList<String>(1);
16807                noAction.add(null);
16808                actions = noAction.iterator();
16809            }
16810
16811            // Collect stickies of users
16812            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16813            while (actions.hasNext()) {
16814                String action = actions.next();
16815                for (int id : userIds) {
16816                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16817                    if (stickies != null) {
16818                        ArrayList<Intent> intents = stickies.get(action);
16819                        if (intents != null) {
16820                            if (stickyIntents == null) {
16821                                stickyIntents = new ArrayList<Intent>();
16822                            }
16823                            stickyIntents.addAll(intents);
16824                        }
16825                    }
16826                }
16827            }
16828        }
16829
16830        ArrayList<Intent> allSticky = null;
16831        if (stickyIntents != null) {
16832            final ContentResolver resolver = mContext.getContentResolver();
16833            // Look for any matching sticky broadcasts...
16834            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16835                Intent intent = stickyIntents.get(i);
16836                // If intent has scheme "content", it will need to acccess
16837                // provider that needs to lock mProviderMap in ActivityThread
16838                // and also it may need to wait application response, so we
16839                // cannot lock ActivityManagerService here.
16840                if (filter.match(resolver, intent, true, TAG) >= 0) {
16841                    if (allSticky == null) {
16842                        allSticky = new ArrayList<Intent>();
16843                    }
16844                    allSticky.add(intent);
16845                }
16846            }
16847        }
16848
16849        // The first sticky in the list is returned directly back to the client.
16850        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16851        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16852        if (receiver == null) {
16853            return sticky;
16854        }
16855
16856        synchronized (this) {
16857            if (callerApp != null && (callerApp.thread == null
16858                    || callerApp.thread.asBinder() != caller.asBinder())) {
16859                // Original caller already died
16860                return null;
16861            }
16862            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16863            if (rl == null) {
16864                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16865                        userId, receiver);
16866                if (rl.app != null) {
16867                    rl.app.receivers.add(rl);
16868                } else {
16869                    try {
16870                        receiver.asBinder().linkToDeath(rl, 0);
16871                    } catch (RemoteException e) {
16872                        return sticky;
16873                    }
16874                    rl.linkedToDeath = true;
16875                }
16876                mRegisteredReceivers.put(receiver.asBinder(), rl);
16877            } else if (rl.uid != callingUid) {
16878                throw new IllegalArgumentException(
16879                        "Receiver requested to register for uid " + callingUid
16880                        + " was previously registered for uid " + rl.uid);
16881            } else if (rl.pid != callingPid) {
16882                throw new IllegalArgumentException(
16883                        "Receiver requested to register for pid " + callingPid
16884                        + " was previously registered for pid " + rl.pid);
16885            } else if (rl.userId != userId) {
16886                throw new IllegalArgumentException(
16887                        "Receiver requested to register for user " + userId
16888                        + " was previously registered for user " + rl.userId);
16889            }
16890            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16891                    permission, callingUid, userId);
16892            rl.add(bf);
16893            if (!bf.debugCheck()) {
16894                Slog.w(TAG, "==> For Dynamic broadcast");
16895            }
16896            mReceiverResolver.addFilter(bf);
16897
16898            // Enqueue broadcasts for all existing stickies that match
16899            // this filter.
16900            if (allSticky != null) {
16901                ArrayList receivers = new ArrayList();
16902                receivers.add(bf);
16903
16904                final int stickyCount = allSticky.size();
16905                for (int i = 0; i < stickyCount; i++) {
16906                    Intent intent = allSticky.get(i);
16907                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16908                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16909                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16910                            null, 0, null, null, false, true, true, -1);
16911                    queue.enqueueParallelBroadcastLocked(r);
16912                    queue.scheduleBroadcastsLocked();
16913                }
16914            }
16915
16916            return sticky;
16917        }
16918    }
16919
16920    public void unregisterReceiver(IIntentReceiver receiver) {
16921        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16922
16923        final long origId = Binder.clearCallingIdentity();
16924        try {
16925            boolean doTrim = false;
16926
16927            synchronized(this) {
16928                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16929                if (rl != null) {
16930                    final BroadcastRecord r = rl.curBroadcast;
16931                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16932                        final boolean doNext = r.queue.finishReceiverLocked(
16933                                r, r.resultCode, r.resultData, r.resultExtras,
16934                                r.resultAbort, false);
16935                        if (doNext) {
16936                            doTrim = true;
16937                            r.queue.processNextBroadcast(false);
16938                        }
16939                    }
16940
16941                    if (rl.app != null) {
16942                        rl.app.receivers.remove(rl);
16943                    }
16944                    removeReceiverLocked(rl);
16945                    if (rl.linkedToDeath) {
16946                        rl.linkedToDeath = false;
16947                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16948                    }
16949                }
16950            }
16951
16952            // If we actually concluded any broadcasts, we might now be able
16953            // to trim the recipients' apps from our working set
16954            if (doTrim) {
16955                trimApplications();
16956                return;
16957            }
16958
16959        } finally {
16960            Binder.restoreCallingIdentity(origId);
16961        }
16962    }
16963
16964    void removeReceiverLocked(ReceiverList rl) {
16965        mRegisteredReceivers.remove(rl.receiver.asBinder());
16966        for (int i = rl.size() - 1; i >= 0; i--) {
16967            mReceiverResolver.removeFilter(rl.get(i));
16968        }
16969    }
16970
16971    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16972        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16973            ProcessRecord r = mLruProcesses.get(i);
16974            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16975                try {
16976                    r.thread.dispatchPackageBroadcast(cmd, packages);
16977                } catch (RemoteException ex) {
16978                }
16979            }
16980        }
16981    }
16982
16983    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16984            int callingUid, int[] users) {
16985        // TODO: come back and remove this assumption to triage all broadcasts
16986        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16987
16988        List<ResolveInfo> receivers = null;
16989        try {
16990            HashSet<ComponentName> singleUserReceivers = null;
16991            boolean scannedFirstReceivers = false;
16992            for (int user : users) {
16993                // Skip users that have Shell restrictions, with exception of always permitted
16994                // Shell broadcasts
16995                if (callingUid == Process.SHELL_UID
16996                        && mUserController.hasUserRestriction(
16997                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16998                        && !isPermittedShellBroadcast(intent)) {
16999                    continue;
17000                }
17001                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17002                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17003                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17004                    // If this is not the system user, we need to check for
17005                    // any receivers that should be filtered out.
17006                    for (int i=0; i<newReceivers.size(); i++) {
17007                        ResolveInfo ri = newReceivers.get(i);
17008                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17009                            newReceivers.remove(i);
17010                            i--;
17011                        }
17012                    }
17013                }
17014                if (newReceivers != null && newReceivers.size() == 0) {
17015                    newReceivers = null;
17016                }
17017                if (receivers == null) {
17018                    receivers = newReceivers;
17019                } else if (newReceivers != null) {
17020                    // We need to concatenate the additional receivers
17021                    // found with what we have do far.  This would be easy,
17022                    // but we also need to de-dup any receivers that are
17023                    // singleUser.
17024                    if (!scannedFirstReceivers) {
17025                        // Collect any single user receivers we had already retrieved.
17026                        scannedFirstReceivers = true;
17027                        for (int i=0; i<receivers.size(); i++) {
17028                            ResolveInfo ri = receivers.get(i);
17029                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17030                                ComponentName cn = new ComponentName(
17031                                        ri.activityInfo.packageName, ri.activityInfo.name);
17032                                if (singleUserReceivers == null) {
17033                                    singleUserReceivers = new HashSet<ComponentName>();
17034                                }
17035                                singleUserReceivers.add(cn);
17036                            }
17037                        }
17038                    }
17039                    // Add the new results to the existing results, tracking
17040                    // and de-dupping single user receivers.
17041                    for (int i=0; i<newReceivers.size(); i++) {
17042                        ResolveInfo ri = newReceivers.get(i);
17043                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17044                            ComponentName cn = new ComponentName(
17045                                    ri.activityInfo.packageName, ri.activityInfo.name);
17046                            if (singleUserReceivers == null) {
17047                                singleUserReceivers = new HashSet<ComponentName>();
17048                            }
17049                            if (!singleUserReceivers.contains(cn)) {
17050                                singleUserReceivers.add(cn);
17051                                receivers.add(ri);
17052                            }
17053                        } else {
17054                            receivers.add(ri);
17055                        }
17056                    }
17057                }
17058            }
17059        } catch (RemoteException ex) {
17060            // pm is in same process, this will never happen.
17061        }
17062        return receivers;
17063    }
17064
17065    private boolean isPermittedShellBroadcast(Intent intent) {
17066        // remote bugreport should always be allowed to be taken
17067        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17068    }
17069
17070    final int broadcastIntentLocked(ProcessRecord callerApp,
17071            String callerPackage, Intent intent, String resolvedType,
17072            IIntentReceiver resultTo, int resultCode, String resultData,
17073            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17074            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17075        intent = new Intent(intent);
17076
17077        // By default broadcasts do not go to stopped apps.
17078        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17079
17080        // If we have not finished booting, don't allow this to launch new processes.
17081        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17082            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17083        }
17084
17085        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17086                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17087                + " ordered=" + ordered + " userid=" + userId);
17088        if ((resultTo != null) && !ordered) {
17089            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17090        }
17091
17092        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17093                ALLOW_NON_FULL, "broadcast", callerPackage);
17094
17095        // Make sure that the user who is receiving this broadcast is running.
17096        // If not, we will just skip it. Make an exception for shutdown broadcasts
17097        // and upgrade steps.
17098
17099        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17100            if ((callingUid != Process.SYSTEM_UID
17101                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17102                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17103                Slog.w(TAG, "Skipping broadcast of " + intent
17104                        + ": user " + userId + " is stopped");
17105                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17106            }
17107        }
17108
17109        BroadcastOptions brOptions = null;
17110        if (bOptions != null) {
17111            brOptions = new BroadcastOptions(bOptions);
17112            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17113                // See if the caller is allowed to do this.  Note we are checking against
17114                // the actual real caller (not whoever provided the operation as say a
17115                // PendingIntent), because that who is actually supplied the arguments.
17116                if (checkComponentPermission(
17117                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17118                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17119                        != PackageManager.PERMISSION_GRANTED) {
17120                    String msg = "Permission Denial: " + intent.getAction()
17121                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17122                            + ", uid=" + callingUid + ")"
17123                            + " requires "
17124                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17125                    Slog.w(TAG, msg);
17126                    throw new SecurityException(msg);
17127                }
17128            }
17129        }
17130
17131        // Verify that protected broadcasts are only being sent by system code,
17132        // and that system code is only sending protected broadcasts.
17133        final String action = intent.getAction();
17134        final boolean isProtectedBroadcast;
17135        try {
17136            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17137        } catch (RemoteException e) {
17138            Slog.w(TAG, "Remote exception", e);
17139            return ActivityManager.BROADCAST_SUCCESS;
17140        }
17141
17142        final boolean isCallerSystem;
17143        switch (UserHandle.getAppId(callingUid)) {
17144            case Process.ROOT_UID:
17145            case Process.SYSTEM_UID:
17146            case Process.PHONE_UID:
17147            case Process.BLUETOOTH_UID:
17148            case Process.NFC_UID:
17149                isCallerSystem = true;
17150                break;
17151            default:
17152                isCallerSystem = (callerApp != null) && callerApp.persistent;
17153                break;
17154        }
17155
17156        if (isCallerSystem) {
17157            if (isProtectedBroadcast
17158                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17159                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17160                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17161                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17162                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17163                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17164                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17165                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17166                // Broadcast is either protected, or it's a public action that
17167                // we've relaxed, so it's fine for system internals to send.
17168            } else {
17169                // The vast majority of broadcasts sent from system internals
17170                // should be protected to avoid security holes, so yell loudly
17171                // to ensure we examine these cases.
17172                Log.wtf(TAG, "Sending non-protected broadcast " + action
17173                        + " from system", new Throwable());
17174            }
17175
17176        } else {
17177            if (isProtectedBroadcast) {
17178                String msg = "Permission Denial: not allowed to send broadcast "
17179                        + action + " from pid="
17180                        + callingPid + ", uid=" + callingUid;
17181                Slog.w(TAG, msg);
17182                throw new SecurityException(msg);
17183
17184            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17185                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17186                // Special case for compatibility: we don't want apps to send this,
17187                // but historically it has not been protected and apps may be using it
17188                // to poke their own app widget.  So, instead of making it protected,
17189                // just limit it to the caller.
17190                if (callerPackage == null) {
17191                    String msg = "Permission Denial: not allowed to send broadcast "
17192                            + action + " from unknown caller.";
17193                    Slog.w(TAG, msg);
17194                    throw new SecurityException(msg);
17195                } else if (intent.getComponent() != null) {
17196                    // They are good enough to send to an explicit component...  verify
17197                    // it is being sent to the calling app.
17198                    if (!intent.getComponent().getPackageName().equals(
17199                            callerPackage)) {
17200                        String msg = "Permission Denial: not allowed to send broadcast "
17201                                + action + " to "
17202                                + intent.getComponent().getPackageName() + " from "
17203                                + callerPackage;
17204                        Slog.w(TAG, msg);
17205                        throw new SecurityException(msg);
17206                    }
17207                } else {
17208                    // Limit broadcast to their own package.
17209                    intent.setPackage(callerPackage);
17210                }
17211            }
17212        }
17213
17214        if (action != null) {
17215            switch (action) {
17216                case Intent.ACTION_UID_REMOVED:
17217                case Intent.ACTION_PACKAGE_REMOVED:
17218                case Intent.ACTION_PACKAGE_CHANGED:
17219                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17220                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17221                case Intent.ACTION_PACKAGES_SUSPENDED:
17222                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17223                    // Handle special intents: if this broadcast is from the package
17224                    // manager about a package being removed, we need to remove all of
17225                    // its activities from the history stack.
17226                    if (checkComponentPermission(
17227                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17228                            callingPid, callingUid, -1, true)
17229                            != PackageManager.PERMISSION_GRANTED) {
17230                        String msg = "Permission Denial: " + intent.getAction()
17231                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17232                                + ", uid=" + callingUid + ")"
17233                                + " requires "
17234                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17235                        Slog.w(TAG, msg);
17236                        throw new SecurityException(msg);
17237                    }
17238                    switch (action) {
17239                        case Intent.ACTION_UID_REMOVED:
17240                            final Bundle intentExtras = intent.getExtras();
17241                            final int uid = intentExtras != null
17242                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17243                            if (uid >= 0) {
17244                                mBatteryStatsService.removeUid(uid);
17245                                mAppOpsService.uidRemoved(uid);
17246                            }
17247                            break;
17248                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17249                            // If resources are unavailable just force stop all those packages
17250                            // and flush the attribute cache as well.
17251                            String list[] =
17252                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17253                            if (list != null && list.length > 0) {
17254                                for (int i = 0; i < list.length; i++) {
17255                                    forceStopPackageLocked(list[i], -1, false, true, true,
17256                                            false, false, userId, "storage unmount");
17257                                }
17258                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17259                                sendPackageBroadcastLocked(
17260                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17261                                        userId);
17262                            }
17263                            break;
17264                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17265                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17266                            break;
17267                        case Intent.ACTION_PACKAGE_REMOVED:
17268                        case Intent.ACTION_PACKAGE_CHANGED:
17269                            Uri data = intent.getData();
17270                            String ssp;
17271                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17272                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17273                                final boolean replacing =
17274                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17275                                final boolean killProcess =
17276                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17277                                final boolean fullUninstall = removed && !replacing;
17278                                if (killProcess) {
17279                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17280                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17281                                            false, true, true, false, fullUninstall, userId,
17282                                            removed ? "pkg removed" : "pkg changed");
17283                                }
17284                                if (removed) {
17285                                    final int cmd = killProcess
17286                                            ? IApplicationThread.PACKAGE_REMOVED
17287                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17288                                    sendPackageBroadcastLocked(cmd,
17289                                            new String[] {ssp}, userId);
17290                                    if (fullUninstall) {
17291                                        mAppOpsService.packageRemoved(
17292                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17293
17294                                        // Remove all permissions granted from/to this package
17295                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17296
17297                                        removeTasksByPackageNameLocked(ssp, userId);
17298                                        mBatteryStatsService.notePackageUninstalled(ssp);
17299                                    }
17300                                } else {
17301                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17302                                            intent.getStringArrayExtra(
17303                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17304                                }
17305                            }
17306                            break;
17307                        case Intent.ACTION_PACKAGES_SUSPENDED:
17308                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17309                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17310                                    intent.getAction());
17311                            final String[] packageNames = intent.getStringArrayExtra(
17312                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17313                            final int userHandle = intent.getIntExtra(
17314                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17315
17316                            synchronized(ActivityManagerService.this) {
17317                                mRecentTasks.onPackagesSuspendedChanged(
17318                                        packageNames, suspended, userHandle);
17319                            }
17320                            break;
17321                    }
17322                    break;
17323                case Intent.ACTION_PACKAGE_REPLACED:
17324                {
17325                    final Uri data = intent.getData();
17326                    final String ssp;
17327                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17328                        final ApplicationInfo aInfo =
17329                                getPackageManagerInternalLocked().getApplicationInfo(
17330                                        ssp,
17331                                        userId);
17332                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17333                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17334                                new String[] {ssp}, userId);
17335                    }
17336                    break;
17337                }
17338                case Intent.ACTION_PACKAGE_ADDED:
17339                {
17340                    // Special case for adding a package: by default turn on compatibility mode.
17341                    Uri data = intent.getData();
17342                    String ssp;
17343                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17344                        final boolean replacing =
17345                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17346                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17347
17348                        try {
17349                            ApplicationInfo ai = AppGlobals.getPackageManager().
17350                                    getApplicationInfo(ssp, 0, 0);
17351                            mBatteryStatsService.notePackageInstalled(ssp,
17352                                    ai != null ? ai.versionCode : 0);
17353                        } catch (RemoteException e) {
17354                        }
17355                    }
17356                    break;
17357                }
17358                case Intent.ACTION_TIMEZONE_CHANGED:
17359                    // If this is the time zone changed action, queue up a message that will reset
17360                    // the timezone of all currently running processes. This message will get
17361                    // queued up before the broadcast happens.
17362                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17363                    break;
17364                case Intent.ACTION_TIME_CHANGED:
17365                    // If the user set the time, let all running processes know.
17366                    final int is24Hour =
17367                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17368                                    : 0;
17369                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17370                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17371                    synchronized (stats) {
17372                        stats.noteCurrentTimeChangedLocked();
17373                    }
17374                    break;
17375                case Intent.ACTION_CLEAR_DNS_CACHE:
17376                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17377                    break;
17378                case Proxy.PROXY_CHANGE_ACTION:
17379                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17380                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17381                    break;
17382                case android.hardware.Camera.ACTION_NEW_PICTURE:
17383                case android.hardware.Camera.ACTION_NEW_VIDEO:
17384                    // These broadcasts are no longer allowed by the system, since they can
17385                    // cause significant thrashing at a crictical point (using the camera).
17386                    // Apps should use JobScehduler to monitor for media provider changes.
17387                    Slog.w(TAG, action + " no longer allowed; dropping from "
17388                            + UserHandle.formatUid(callingUid));
17389                    // Lie; we don't want to crash the app.
17390                    return ActivityManager.BROADCAST_SUCCESS;
17391            }
17392        }
17393
17394        // Add to the sticky list if requested.
17395        if (sticky) {
17396            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17397                    callingPid, callingUid)
17398                    != PackageManager.PERMISSION_GRANTED) {
17399                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17400                        + callingPid + ", uid=" + callingUid
17401                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17402                Slog.w(TAG, msg);
17403                throw new SecurityException(msg);
17404            }
17405            if (requiredPermissions != null && requiredPermissions.length > 0) {
17406                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17407                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17408                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17409            }
17410            if (intent.getComponent() != null) {
17411                throw new SecurityException(
17412                        "Sticky broadcasts can't target a specific component");
17413            }
17414            // We use userId directly here, since the "all" target is maintained
17415            // as a separate set of sticky broadcasts.
17416            if (userId != UserHandle.USER_ALL) {
17417                // But first, if this is not a broadcast to all users, then
17418                // make sure it doesn't conflict with an existing broadcast to
17419                // all users.
17420                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17421                        UserHandle.USER_ALL);
17422                if (stickies != null) {
17423                    ArrayList<Intent> list = stickies.get(intent.getAction());
17424                    if (list != null) {
17425                        int N = list.size();
17426                        int i;
17427                        for (i=0; i<N; i++) {
17428                            if (intent.filterEquals(list.get(i))) {
17429                                throw new IllegalArgumentException(
17430                                        "Sticky broadcast " + intent + " for user "
17431                                        + userId + " conflicts with existing global broadcast");
17432                            }
17433                        }
17434                    }
17435                }
17436            }
17437            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17438            if (stickies == null) {
17439                stickies = new ArrayMap<>();
17440                mStickyBroadcasts.put(userId, stickies);
17441            }
17442            ArrayList<Intent> list = stickies.get(intent.getAction());
17443            if (list == null) {
17444                list = new ArrayList<>();
17445                stickies.put(intent.getAction(), list);
17446            }
17447            final int stickiesCount = list.size();
17448            int i;
17449            for (i = 0; i < stickiesCount; i++) {
17450                if (intent.filterEquals(list.get(i))) {
17451                    // This sticky already exists, replace it.
17452                    list.set(i, new Intent(intent));
17453                    break;
17454                }
17455            }
17456            if (i >= stickiesCount) {
17457                list.add(new Intent(intent));
17458            }
17459        }
17460
17461        int[] users;
17462        if (userId == UserHandle.USER_ALL) {
17463            // Caller wants broadcast to go to all started users.
17464            users = mUserController.getStartedUserArrayLocked();
17465        } else {
17466            // Caller wants broadcast to go to one specific user.
17467            users = new int[] {userId};
17468        }
17469
17470        // Figure out who all will receive this broadcast.
17471        List receivers = null;
17472        List<BroadcastFilter> registeredReceivers = null;
17473        // Need to resolve the intent to interested receivers...
17474        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17475                 == 0) {
17476            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17477        }
17478        if (intent.getComponent() == null) {
17479            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17480                // Query one target user at a time, excluding shell-restricted users
17481                for (int i = 0; i < users.length; i++) {
17482                    if (mUserController.hasUserRestriction(
17483                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17484                        continue;
17485                    }
17486                    List<BroadcastFilter> registeredReceiversForUser =
17487                            mReceiverResolver.queryIntent(intent,
17488                                    resolvedType, false, users[i]);
17489                    if (registeredReceivers == null) {
17490                        registeredReceivers = registeredReceiversForUser;
17491                    } else if (registeredReceiversForUser != null) {
17492                        registeredReceivers.addAll(registeredReceiversForUser);
17493                    }
17494                }
17495            } else {
17496                registeredReceivers = mReceiverResolver.queryIntent(intent,
17497                        resolvedType, false, userId);
17498            }
17499        }
17500
17501        final boolean replacePending =
17502                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17503
17504        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17505                + " replacePending=" + replacePending);
17506
17507        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17508        if (!ordered && NR > 0) {
17509            // If we are not serializing this broadcast, then send the
17510            // registered receivers separately so they don't wait for the
17511            // components to be launched.
17512            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17513            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17514                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17515                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17516                    resultExtras, ordered, sticky, false, userId);
17517            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17518            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17519            if (!replaced) {
17520                queue.enqueueParallelBroadcastLocked(r);
17521                queue.scheduleBroadcastsLocked();
17522            }
17523            registeredReceivers = null;
17524            NR = 0;
17525        }
17526
17527        // Merge into one list.
17528        int ir = 0;
17529        if (receivers != null) {
17530            // A special case for PACKAGE_ADDED: do not allow the package
17531            // being added to see this broadcast.  This prevents them from
17532            // using this as a back door to get run as soon as they are
17533            // installed.  Maybe in the future we want to have a special install
17534            // broadcast or such for apps, but we'd like to deliberately make
17535            // this decision.
17536            String skipPackages[] = null;
17537            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17538                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17539                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17540                Uri data = intent.getData();
17541                if (data != null) {
17542                    String pkgName = data.getSchemeSpecificPart();
17543                    if (pkgName != null) {
17544                        skipPackages = new String[] { pkgName };
17545                    }
17546                }
17547            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17548                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17549            }
17550            if (skipPackages != null && (skipPackages.length > 0)) {
17551                for (String skipPackage : skipPackages) {
17552                    if (skipPackage != null) {
17553                        int NT = receivers.size();
17554                        for (int it=0; it<NT; it++) {
17555                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17556                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17557                                receivers.remove(it);
17558                                it--;
17559                                NT--;
17560                            }
17561                        }
17562                    }
17563                }
17564            }
17565
17566            int NT = receivers != null ? receivers.size() : 0;
17567            int it = 0;
17568            ResolveInfo curt = null;
17569            BroadcastFilter curr = null;
17570            while (it < NT && ir < NR) {
17571                if (curt == null) {
17572                    curt = (ResolveInfo)receivers.get(it);
17573                }
17574                if (curr == null) {
17575                    curr = registeredReceivers.get(ir);
17576                }
17577                if (curr.getPriority() >= curt.priority) {
17578                    // Insert this broadcast record into the final list.
17579                    receivers.add(it, curr);
17580                    ir++;
17581                    curr = null;
17582                    it++;
17583                    NT++;
17584                } else {
17585                    // Skip to the next ResolveInfo in the final list.
17586                    it++;
17587                    curt = null;
17588                }
17589            }
17590        }
17591        while (ir < NR) {
17592            if (receivers == null) {
17593                receivers = new ArrayList();
17594            }
17595            receivers.add(registeredReceivers.get(ir));
17596            ir++;
17597        }
17598
17599        if ((receivers != null && receivers.size() > 0)
17600                || resultTo != null) {
17601            BroadcastQueue queue = broadcastQueueForIntent(intent);
17602            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17603                    callerPackage, callingPid, callingUid, resolvedType,
17604                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17605                    resultData, resultExtras, ordered, sticky, false, userId);
17606
17607            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17608                    + ": prev had " + queue.mOrderedBroadcasts.size());
17609            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17610                    "Enqueueing broadcast " + r.intent.getAction());
17611
17612            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17613            if (!replaced) {
17614                queue.enqueueOrderedBroadcastLocked(r);
17615                queue.scheduleBroadcastsLocked();
17616            }
17617        }
17618
17619        return ActivityManager.BROADCAST_SUCCESS;
17620    }
17621
17622    final Intent verifyBroadcastLocked(Intent intent) {
17623        // Refuse possible leaked file descriptors
17624        if (intent != null && intent.hasFileDescriptors() == true) {
17625            throw new IllegalArgumentException("File descriptors passed in Intent");
17626        }
17627
17628        int flags = intent.getFlags();
17629
17630        if (!mProcessesReady) {
17631            // if the caller really truly claims to know what they're doing, go
17632            // ahead and allow the broadcast without launching any receivers
17633            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17634                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17635            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17636                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17637                        + " before boot completion");
17638                throw new IllegalStateException("Cannot broadcast before boot completed");
17639            }
17640        }
17641
17642        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17643            throw new IllegalArgumentException(
17644                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17645        }
17646
17647        return intent;
17648    }
17649
17650    public final int broadcastIntent(IApplicationThread caller,
17651            Intent intent, String resolvedType, IIntentReceiver resultTo,
17652            int resultCode, String resultData, Bundle resultExtras,
17653            String[] requiredPermissions, int appOp, Bundle bOptions,
17654            boolean serialized, boolean sticky, int userId) {
17655        enforceNotIsolatedCaller("broadcastIntent");
17656        synchronized(this) {
17657            intent = verifyBroadcastLocked(intent);
17658
17659            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17660            final int callingPid = Binder.getCallingPid();
17661            final int callingUid = Binder.getCallingUid();
17662            final long origId = Binder.clearCallingIdentity();
17663            int res = broadcastIntentLocked(callerApp,
17664                    callerApp != null ? callerApp.info.packageName : null,
17665                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17666                    requiredPermissions, appOp, bOptions, serialized, sticky,
17667                    callingPid, callingUid, userId);
17668            Binder.restoreCallingIdentity(origId);
17669            return res;
17670        }
17671    }
17672
17673
17674    int broadcastIntentInPackage(String packageName, int uid,
17675            Intent intent, String resolvedType, IIntentReceiver resultTo,
17676            int resultCode, String resultData, Bundle resultExtras,
17677            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17678            int userId) {
17679        synchronized(this) {
17680            intent = verifyBroadcastLocked(intent);
17681
17682            final long origId = Binder.clearCallingIdentity();
17683            String[] requiredPermissions = requiredPermission == null ? null
17684                    : new String[] {requiredPermission};
17685            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17686                    resultTo, resultCode, resultData, resultExtras,
17687                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17688                    sticky, -1, uid, userId);
17689            Binder.restoreCallingIdentity(origId);
17690            return res;
17691        }
17692    }
17693
17694    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17695        // Refuse possible leaked file descriptors
17696        if (intent != null && intent.hasFileDescriptors() == true) {
17697            throw new IllegalArgumentException("File descriptors passed in Intent");
17698        }
17699
17700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17701                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17702
17703        synchronized(this) {
17704            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17705                    != PackageManager.PERMISSION_GRANTED) {
17706                String msg = "Permission Denial: unbroadcastIntent() from pid="
17707                        + Binder.getCallingPid()
17708                        + ", uid=" + Binder.getCallingUid()
17709                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17710                Slog.w(TAG, msg);
17711                throw new SecurityException(msg);
17712            }
17713            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17714            if (stickies != null) {
17715                ArrayList<Intent> list = stickies.get(intent.getAction());
17716                if (list != null) {
17717                    int N = list.size();
17718                    int i;
17719                    for (i=0; i<N; i++) {
17720                        if (intent.filterEquals(list.get(i))) {
17721                            list.remove(i);
17722                            break;
17723                        }
17724                    }
17725                    if (list.size() <= 0) {
17726                        stickies.remove(intent.getAction());
17727                    }
17728                }
17729                if (stickies.size() <= 0) {
17730                    mStickyBroadcasts.remove(userId);
17731                }
17732            }
17733        }
17734    }
17735
17736    void backgroundServicesFinishedLocked(int userId) {
17737        for (BroadcastQueue queue : mBroadcastQueues) {
17738            queue.backgroundServicesFinishedLocked(userId);
17739        }
17740    }
17741
17742    public void finishReceiver(IBinder who, int resultCode, String resultData,
17743            Bundle resultExtras, boolean resultAbort, int flags) {
17744        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17745
17746        // Refuse possible leaked file descriptors
17747        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17748            throw new IllegalArgumentException("File descriptors passed in Bundle");
17749        }
17750
17751        final long origId = Binder.clearCallingIdentity();
17752        try {
17753            boolean doNext = false;
17754            BroadcastRecord r;
17755
17756            synchronized(this) {
17757                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17758                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17759                r = queue.getMatchingOrderedReceiver(who);
17760                if (r != null) {
17761                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17762                        resultData, resultExtras, resultAbort, true);
17763                }
17764            }
17765
17766            if (doNext) {
17767                r.queue.processNextBroadcast(false);
17768            }
17769            trimApplications();
17770        } finally {
17771            Binder.restoreCallingIdentity(origId);
17772        }
17773    }
17774
17775    // =========================================================
17776    // INSTRUMENTATION
17777    // =========================================================
17778
17779    public boolean startInstrumentation(ComponentName className,
17780            String profileFile, int flags, Bundle arguments,
17781            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17782            int userId, String abiOverride) {
17783        enforceNotIsolatedCaller("startInstrumentation");
17784        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17785                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17786        // Refuse possible leaked file descriptors
17787        if (arguments != null && arguments.hasFileDescriptors()) {
17788            throw new IllegalArgumentException("File descriptors passed in Bundle");
17789        }
17790
17791        synchronized(this) {
17792            InstrumentationInfo ii = null;
17793            ApplicationInfo ai = null;
17794            try {
17795                ii = mContext.getPackageManager().getInstrumentationInfo(
17796                    className, STOCK_PM_FLAGS);
17797                ai = AppGlobals.getPackageManager().getApplicationInfo(
17798                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17799            } catch (PackageManager.NameNotFoundException e) {
17800            } catch (RemoteException e) {
17801            }
17802            if (ii == null) {
17803                reportStartInstrumentationFailureLocked(watcher, className,
17804                        "Unable to find instrumentation info for: " + className);
17805                return false;
17806            }
17807            if (ai == null) {
17808                reportStartInstrumentationFailureLocked(watcher, className,
17809                        "Unable to find instrumentation target package: " + ii.targetPackage);
17810                return false;
17811            }
17812            if (!ai.hasCode()) {
17813                reportStartInstrumentationFailureLocked(watcher, className,
17814                        "Instrumentation target has no code: " + ii.targetPackage);
17815                return false;
17816            }
17817
17818            int match = mContext.getPackageManager().checkSignatures(
17819                    ii.targetPackage, ii.packageName);
17820            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17821                String msg = "Permission Denial: starting instrumentation "
17822                        + className + " from pid="
17823                        + Binder.getCallingPid()
17824                        + ", uid=" + Binder.getCallingPid()
17825                        + " not allowed because package " + ii.packageName
17826                        + " does not have a signature matching the target "
17827                        + ii.targetPackage;
17828                reportStartInstrumentationFailureLocked(watcher, className, msg);
17829                throw new SecurityException(msg);
17830            }
17831
17832            final long origId = Binder.clearCallingIdentity();
17833            // Instrumentation can kill and relaunch even persistent processes
17834            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17835                    "start instr");
17836            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17837            app.instrumentationClass = className;
17838            app.instrumentationInfo = ai;
17839            app.instrumentationProfileFile = profileFile;
17840            app.instrumentationArguments = arguments;
17841            app.instrumentationWatcher = watcher;
17842            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17843            app.instrumentationResultClass = className;
17844            Binder.restoreCallingIdentity(origId);
17845        }
17846
17847        return true;
17848    }
17849
17850    /**
17851     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17852     * error to the logs, but if somebody is watching, send the report there too.  This enables
17853     * the "am" command to report errors with more information.
17854     *
17855     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17856     * @param cn The component name of the instrumentation.
17857     * @param report The error report.
17858     */
17859    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17860            ComponentName cn, String report) {
17861        Slog.w(TAG, report);
17862        if (watcher != null) {
17863            Bundle results = new Bundle();
17864            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17865            results.putString("Error", report);
17866            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17867        }
17868    }
17869
17870    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17871        if (app.instrumentationWatcher != null) {
17872            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17873                    app.instrumentationClass, resultCode, results);
17874        }
17875
17876        // Can't call out of the system process with a lock held, so post a message.
17877        if (app.instrumentationUiAutomationConnection != null) {
17878            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17879                    app.instrumentationUiAutomationConnection).sendToTarget();
17880        }
17881
17882        app.instrumentationWatcher = null;
17883        app.instrumentationUiAutomationConnection = null;
17884        app.instrumentationClass = null;
17885        app.instrumentationInfo = null;
17886        app.instrumentationProfileFile = null;
17887        app.instrumentationArguments = null;
17888
17889        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17890                "finished inst");
17891    }
17892
17893    public void finishInstrumentation(IApplicationThread target,
17894            int resultCode, Bundle results) {
17895        int userId = UserHandle.getCallingUserId();
17896        // Refuse possible leaked file descriptors
17897        if (results != null && results.hasFileDescriptors()) {
17898            throw new IllegalArgumentException("File descriptors passed in Intent");
17899        }
17900
17901        synchronized(this) {
17902            ProcessRecord app = getRecordForAppLocked(target);
17903            if (app == null) {
17904                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17905                return;
17906            }
17907            final long origId = Binder.clearCallingIdentity();
17908            finishInstrumentationLocked(app, resultCode, results);
17909            Binder.restoreCallingIdentity(origId);
17910        }
17911    }
17912
17913    // =========================================================
17914    // CONFIGURATION
17915    // =========================================================
17916
17917    public ConfigurationInfo getDeviceConfigurationInfo() {
17918        ConfigurationInfo config = new ConfigurationInfo();
17919        synchronized (this) {
17920            config.reqTouchScreen = mConfiguration.touchscreen;
17921            config.reqKeyboardType = mConfiguration.keyboard;
17922            config.reqNavigation = mConfiguration.navigation;
17923            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17924                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17925                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17926            }
17927            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17928                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17929                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17930            }
17931            config.reqGlEsVersion = GL_ES_VERSION;
17932        }
17933        return config;
17934    }
17935
17936    ActivityStack getFocusedStack() {
17937        return mStackSupervisor.getFocusedStack();
17938    }
17939
17940    @Override
17941    public int getFocusedStackId() throws RemoteException {
17942        ActivityStack focusedStack = getFocusedStack();
17943        if (focusedStack != null) {
17944            return focusedStack.getStackId();
17945        }
17946        return -1;
17947    }
17948
17949    public Configuration getConfiguration() {
17950        Configuration ci;
17951        synchronized(this) {
17952            ci = new Configuration(mConfiguration);
17953            ci.userSetLocale = false;
17954        }
17955        return ci;
17956    }
17957
17958    @Override
17959    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17961        synchronized (this) {
17962            mSuppressResizeConfigChanges = suppress;
17963        }
17964    }
17965
17966    @Override
17967    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17968        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17969        if (fromStackId == HOME_STACK_ID) {
17970            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17971        }
17972        synchronized (this) {
17973            final long origId = Binder.clearCallingIdentity();
17974            try {
17975                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17976            } finally {
17977                Binder.restoreCallingIdentity(origId);
17978            }
17979        }
17980    }
17981
17982    @Override
17983    public void updatePersistentConfiguration(Configuration values) {
17984        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17985                "updateConfiguration()");
17986        enforceWriteSettingsPermission("updateConfiguration()");
17987        if (values == null) {
17988            throw new NullPointerException("Configuration must not be null");
17989        }
17990
17991        int userId = UserHandle.getCallingUserId();
17992
17993        synchronized(this) {
17994            final long origId = Binder.clearCallingIdentity();
17995            updateConfigurationLocked(values, null, false, true, userId);
17996            Binder.restoreCallingIdentity(origId);
17997        }
17998    }
17999
18000    private void updateFontScaleIfNeeded() {
18001        final int currentUserId;
18002        synchronized(this) {
18003            currentUserId = mUserController.getCurrentUserIdLocked();
18004        }
18005        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18006                FONT_SCALE, 1.0f, currentUserId);
18007        if (mConfiguration.fontScale != scaleFactor) {
18008            final Configuration configuration = mWindowManager.computeNewConfiguration();
18009            configuration.fontScale = scaleFactor;
18010            updatePersistentConfiguration(configuration);
18011        }
18012    }
18013
18014    private void enforceWriteSettingsPermission(String func) {
18015        int uid = Binder.getCallingUid();
18016        if (uid == Process.ROOT_UID) {
18017            return;
18018        }
18019
18020        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18021                Settings.getPackageNameForUid(mContext, uid), false)) {
18022            return;
18023        }
18024
18025        String msg = "Permission Denial: " + func + " from pid="
18026                + Binder.getCallingPid()
18027                + ", uid=" + uid
18028                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18029        Slog.w(TAG, msg);
18030        throw new SecurityException(msg);
18031    }
18032
18033    public void updateConfiguration(Configuration values) {
18034        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18035                "updateConfiguration()");
18036
18037        synchronized(this) {
18038            if (values == null && mWindowManager != null) {
18039                // sentinel: fetch the current configuration from the window manager
18040                values = mWindowManager.computeNewConfiguration();
18041            }
18042
18043            if (mWindowManager != null) {
18044                mProcessList.applyDisplaySize(mWindowManager);
18045            }
18046
18047            final long origId = Binder.clearCallingIdentity();
18048            if (values != null) {
18049                Settings.System.clearConfiguration(values);
18050            }
18051            updateConfigurationLocked(values, null, false);
18052            Binder.restoreCallingIdentity(origId);
18053        }
18054    }
18055
18056    void updateUserConfigurationLocked() {
18057        Configuration configuration = new Configuration(mConfiguration);
18058        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18059                mUserController.getCurrentUserIdLocked());
18060        updateConfigurationLocked(configuration, null, false);
18061    }
18062
18063    boolean updateConfigurationLocked(Configuration values,
18064            ActivityRecord starting, boolean initLocale) {
18065        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18066        return updateConfigurationLocked(values, starting, initLocale, false,
18067                UserHandle.USER_NULL);
18068    }
18069
18070    // To cache the list of supported system locales
18071    private String[] mSupportedSystemLocales = null;
18072
18073    /**
18074     * Do either or both things: (1) change the current configuration, and (2)
18075     * make sure the given activity is running with the (now) current
18076     * configuration.  Returns true if the activity has been left running, or
18077     * false if <var>starting</var> is being destroyed to match the new
18078     * configuration.
18079     *
18080     * @param userId is only used when persistent parameter is set to true to persist configuration
18081     *               for that particular user
18082     */
18083    private boolean updateConfigurationLocked(Configuration values,
18084            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18085        int changes = 0;
18086
18087        if (mWindowManager != null) {
18088            mWindowManager.deferSurfaceLayout();
18089        }
18090        if (values != null) {
18091            Configuration newConfig = new Configuration(mConfiguration);
18092            changes = newConfig.updateFrom(values);
18093            if (changes != 0) {
18094                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18095                        "Updating configuration to: " + values);
18096
18097                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18098
18099                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18100                    final Locale locale;
18101                    if (values.getLocales().size() == 1) {
18102                        // This is an optimization to avoid the JNI call when the result of
18103                        // getFirstMatch() does not depend on the supported locales.
18104                        locale = values.getLocales().get(0);
18105                    } else {
18106                        if (mSupportedSystemLocales == null) {
18107                            mSupportedSystemLocales =
18108                                    Resources.getSystem().getAssets().getLocales();
18109                        }
18110                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18111                    }
18112                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18113                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18114                            locale));
18115                }
18116
18117                mConfigurationSeq++;
18118                if (mConfigurationSeq <= 0) {
18119                    mConfigurationSeq = 1;
18120                }
18121                newConfig.seq = mConfigurationSeq;
18122                mConfiguration = newConfig;
18123                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18124                mUsageStatsService.reportConfigurationChange(newConfig,
18125                        mUserController.getCurrentUserIdLocked());
18126                //mUsageStatsService.noteStartConfig(newConfig);
18127
18128                final Configuration configCopy = new Configuration(mConfiguration);
18129
18130                // TODO: If our config changes, should we auto dismiss any currently
18131                // showing dialogs?
18132                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18133
18134                AttributeCache ac = AttributeCache.instance();
18135                if (ac != null) {
18136                    ac.updateConfiguration(configCopy);
18137                }
18138
18139                // Make sure all resources in our process are updated
18140                // right now, so that anyone who is going to retrieve
18141                // resource values after we return will be sure to get
18142                // the new ones.  This is especially important during
18143                // boot, where the first config change needs to guarantee
18144                // all resources have that config before following boot
18145                // code is executed.
18146                mSystemThread.applyConfigurationToResources(configCopy);
18147
18148                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18149                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18150                    msg.obj = new Configuration(configCopy);
18151                    msg.arg1 = userId;
18152                    mHandler.sendMessage(msg);
18153                }
18154
18155                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18156                if (isDensityChange) {
18157                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18158                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18159                }
18160
18161                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18162                    ProcessRecord app = mLruProcesses.get(i);
18163                    try {
18164                        if (app.thread != null) {
18165                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18166                                    + app.processName + " new config " + mConfiguration);
18167                            app.thread.scheduleConfigurationChanged(configCopy);
18168                        }
18169                    } catch (Exception e) {
18170                    }
18171                }
18172                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18173                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18174                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18175                        | Intent.FLAG_RECEIVER_FOREGROUND);
18176                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18177                        null, AppOpsManager.OP_NONE, null, false, false,
18178                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18179                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18180                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18181                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18182                    if (!mProcessesReady) {
18183                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18184                    }
18185                    broadcastIntentLocked(null, null, intent,
18186                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18187                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18188                }
18189            }
18190            // Update the configuration with WM first and check if any of the stacks need to be
18191            // resized due to the configuration change. If so, resize the stacks now and do any
18192            // relaunches if necessary. This way we don't need to relaunch again below in
18193            // ensureActivityConfigurationLocked().
18194            if (mWindowManager != null) {
18195                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18196                if (resizedStacks != null) {
18197                    for (int stackId : resizedStacks) {
18198                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18199                        mStackSupervisor.resizeStackLocked(
18200                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18201                    }
18202                }
18203            }
18204        }
18205
18206        boolean kept = true;
18207        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18208        // mainStack is null during startup.
18209        if (mainStack != null) {
18210            if (changes != 0 && starting == null) {
18211                // If the configuration changed, and the caller is not already
18212                // in the process of starting an activity, then find the top
18213                // activity to check if its configuration needs to change.
18214                starting = mainStack.topRunningActivityLocked();
18215            }
18216
18217            if (starting != null) {
18218                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18219                // And we need to make sure at this point that all other activities
18220                // are made visible with the correct configuration.
18221                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18222                        !PRESERVE_WINDOWS);
18223            }
18224        }
18225        if (mWindowManager != null) {
18226            mWindowManager.continueSurfaceLayout();
18227        }
18228        return kept;
18229    }
18230
18231    /**
18232     * Decide based on the configuration whether we should shouw the ANR,
18233     * crash, etc dialogs.  The idea is that if there is no affordnace to
18234     * press the on-screen buttons, we shouldn't show the dialog.
18235     *
18236     * A thought: SystemUI might also want to get told about this, the Power
18237     * dialog / global actions also might want different behaviors.
18238     */
18239    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18240        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18241                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18242                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18243        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18244                                    == Configuration.UI_MODE_TYPE_CAR);
18245        return inputMethodExists && uiIsNotCarType && !inVrMode;
18246    }
18247
18248    @Override
18249    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18250        synchronized (this) {
18251            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18252            if (srec != null) {
18253                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18254            }
18255        }
18256        return false;
18257    }
18258
18259    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18260            Intent resultData) {
18261
18262        synchronized (this) {
18263            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18264            if (r != null) {
18265                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18266            }
18267            return false;
18268        }
18269    }
18270
18271    public int getLaunchedFromUid(IBinder activityToken) {
18272        ActivityRecord srec;
18273        synchronized (this) {
18274            srec = ActivityRecord.forTokenLocked(activityToken);
18275        }
18276        if (srec == null) {
18277            return -1;
18278        }
18279        return srec.launchedFromUid;
18280    }
18281
18282    public String getLaunchedFromPackage(IBinder activityToken) {
18283        ActivityRecord srec;
18284        synchronized (this) {
18285            srec = ActivityRecord.forTokenLocked(activityToken);
18286        }
18287        if (srec == null) {
18288            return null;
18289        }
18290        return srec.launchedFromPackage;
18291    }
18292
18293    // =========================================================
18294    // LIFETIME MANAGEMENT
18295    // =========================================================
18296
18297    // Returns which broadcast queue the app is the current [or imminent] receiver
18298    // on, or 'null' if the app is not an active broadcast recipient.
18299    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18300        BroadcastRecord r = app.curReceiver;
18301        if (r != null) {
18302            return r.queue;
18303        }
18304
18305        // It's not the current receiver, but it might be starting up to become one
18306        synchronized (this) {
18307            for (BroadcastQueue queue : mBroadcastQueues) {
18308                r = queue.mPendingBroadcast;
18309                if (r != null && r.curApp == app) {
18310                    // found it; report which queue it's in
18311                    return queue;
18312                }
18313            }
18314        }
18315
18316        return null;
18317    }
18318
18319    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18320            int targetUid, ComponentName targetComponent, String targetProcess) {
18321        if (!mTrackingAssociations) {
18322            return null;
18323        }
18324        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18325                = mAssociations.get(targetUid);
18326        if (components == null) {
18327            components = new ArrayMap<>();
18328            mAssociations.put(targetUid, components);
18329        }
18330        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18331        if (sourceUids == null) {
18332            sourceUids = new SparseArray<>();
18333            components.put(targetComponent, sourceUids);
18334        }
18335        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18336        if (sourceProcesses == null) {
18337            sourceProcesses = new ArrayMap<>();
18338            sourceUids.put(sourceUid, sourceProcesses);
18339        }
18340        Association ass = sourceProcesses.get(sourceProcess);
18341        if (ass == null) {
18342            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18343                    targetProcess);
18344            sourceProcesses.put(sourceProcess, ass);
18345        }
18346        ass.mCount++;
18347        ass.mNesting++;
18348        if (ass.mNesting == 1) {
18349            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18350            ass.mLastState = sourceState;
18351        }
18352        return ass;
18353    }
18354
18355    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18356            ComponentName targetComponent) {
18357        if (!mTrackingAssociations) {
18358            return;
18359        }
18360        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18361                = mAssociations.get(targetUid);
18362        if (components == null) {
18363            return;
18364        }
18365        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18366        if (sourceUids == null) {
18367            return;
18368        }
18369        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18370        if (sourceProcesses == null) {
18371            return;
18372        }
18373        Association ass = sourceProcesses.get(sourceProcess);
18374        if (ass == null || ass.mNesting <= 0) {
18375            return;
18376        }
18377        ass.mNesting--;
18378        if (ass.mNesting == 0) {
18379            long uptime = SystemClock.uptimeMillis();
18380            ass.mTime += uptime - ass.mStartTime;
18381            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18382                    += uptime - ass.mLastStateUptime;
18383            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18384        }
18385    }
18386
18387    private void noteUidProcessState(final int uid, final int state) {
18388        mBatteryStatsService.noteUidProcessState(uid, state);
18389        if (mTrackingAssociations) {
18390            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18391                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18392                        = mAssociations.valueAt(i1);
18393                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18394                    SparseArray<ArrayMap<String, Association>> sourceUids
18395                            = targetComponents.valueAt(i2);
18396                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18397                    if (sourceProcesses != null) {
18398                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18399                            Association ass = sourceProcesses.valueAt(i4);
18400                            if (ass.mNesting >= 1) {
18401                                // currently associated
18402                                long uptime = SystemClock.uptimeMillis();
18403                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18404                                        += uptime - ass.mLastStateUptime;
18405                                ass.mLastState = state;
18406                                ass.mLastStateUptime = uptime;
18407                            }
18408                        }
18409                    }
18410                }
18411            }
18412        }
18413    }
18414
18415    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18416            boolean doingAll, long now) {
18417        if (mAdjSeq == app.adjSeq) {
18418            // This adjustment has already been computed.
18419            return app.curRawAdj;
18420        }
18421
18422        if (app.thread == null) {
18423            app.adjSeq = mAdjSeq;
18424            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18425            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18426            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18427        }
18428
18429        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18430        app.adjSource = null;
18431        app.adjTarget = null;
18432        app.empty = false;
18433        app.cached = false;
18434
18435        final int activitiesSize = app.activities.size();
18436
18437        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18438            // The max adjustment doesn't allow this app to be anything
18439            // below foreground, so it is not worth doing work for it.
18440            app.adjType = "fixed";
18441            app.adjSeq = mAdjSeq;
18442            app.curRawAdj = app.maxAdj;
18443            app.foregroundActivities = false;
18444            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18445            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18446            // System processes can do UI, and when they do we want to have
18447            // them trim their memory after the user leaves the UI.  To
18448            // facilitate this, here we need to determine whether or not it
18449            // is currently showing UI.
18450            app.systemNoUi = true;
18451            if (app == TOP_APP) {
18452                app.systemNoUi = false;
18453            } else if (activitiesSize > 0) {
18454                for (int j = 0; j < activitiesSize; j++) {
18455                    final ActivityRecord r = app.activities.get(j);
18456                    if (r.visible) {
18457                        app.systemNoUi = false;
18458                    }
18459                }
18460            }
18461            if (!app.systemNoUi) {
18462                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18463            }
18464            return (app.curAdj=app.maxAdj);
18465        }
18466
18467        app.systemNoUi = false;
18468
18469        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18470
18471        // Determine the importance of the process, starting with most
18472        // important to least, and assign an appropriate OOM adjustment.
18473        int adj;
18474        int schedGroup;
18475        int procState;
18476        boolean foregroundActivities = false;
18477        BroadcastQueue queue;
18478        if (app == TOP_APP) {
18479            // The last app on the list is the foreground app.
18480            adj = ProcessList.FOREGROUND_APP_ADJ;
18481            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18482            app.adjType = "top-activity";
18483            foregroundActivities = true;
18484            procState = PROCESS_STATE_CUR_TOP;
18485        } else if (app.instrumentationClass != null) {
18486            // Don't want to kill running instrumentation.
18487            adj = ProcessList.FOREGROUND_APP_ADJ;
18488            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18489            app.adjType = "instrumentation";
18490            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18491        } else if ((queue = isReceivingBroadcast(app)) != null) {
18492            // An app that is currently receiving a broadcast also
18493            // counts as being in the foreground for OOM killer purposes.
18494            // It's placed in a sched group based on the nature of the
18495            // broadcast as reflected by which queue it's active in.
18496            adj = ProcessList.FOREGROUND_APP_ADJ;
18497            schedGroup = (queue == mFgBroadcastQueue)
18498                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18499            app.adjType = "broadcast";
18500            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18501        } else if (app.executingServices.size() > 0) {
18502            // An app that is currently executing a service callback also
18503            // counts as being in the foreground.
18504            adj = ProcessList.FOREGROUND_APP_ADJ;
18505            schedGroup = app.execServicesFg ?
18506                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18507            app.adjType = "exec-service";
18508            procState = ActivityManager.PROCESS_STATE_SERVICE;
18509            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18510        } else {
18511            // As far as we know the process is empty.  We may change our mind later.
18512            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18513            // At this point we don't actually know the adjustment.  Use the cached adj
18514            // value that the caller wants us to.
18515            adj = cachedAdj;
18516            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18517            app.cached = true;
18518            app.empty = true;
18519            app.adjType = "cch-empty";
18520        }
18521
18522        // Examine all activities if not already foreground.
18523        if (!foregroundActivities && activitiesSize > 0) {
18524            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18525            for (int j = 0; j < activitiesSize; j++) {
18526                final ActivityRecord r = app.activities.get(j);
18527                if (r.app != app) {
18528                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18529                            + " instead of expected " + app);
18530                    if (r.app == null || (r.app.uid == app.uid)) {
18531                        // Only fix things up when they look sane
18532                        r.app = app;
18533                    } else {
18534                        continue;
18535                    }
18536                }
18537                if (r.visible) {
18538                    // App has a visible activity; only upgrade adjustment.
18539                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18540                        adj = ProcessList.VISIBLE_APP_ADJ;
18541                        app.adjType = "visible";
18542                    }
18543                    if (procState > PROCESS_STATE_CUR_TOP) {
18544                        procState = PROCESS_STATE_CUR_TOP;
18545                    }
18546                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18547                    app.cached = false;
18548                    app.empty = false;
18549                    foregroundActivities = true;
18550                    if (r.task != null && minLayer > 0) {
18551                        final int layer = r.task.mLayerRank;
18552                        if (layer >= 0 && minLayer > layer) {
18553                            minLayer = layer;
18554                        }
18555                    }
18556                    break;
18557                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18558                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18559                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18560                        app.adjType = "pausing";
18561                    }
18562                    if (procState > PROCESS_STATE_CUR_TOP) {
18563                        procState = PROCESS_STATE_CUR_TOP;
18564                    }
18565                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18566                    app.cached = false;
18567                    app.empty = false;
18568                    foregroundActivities = true;
18569                } else if (r.state == ActivityState.STOPPING) {
18570                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18571                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18572                        app.adjType = "stopping";
18573                    }
18574                    // For the process state, we will at this point consider the
18575                    // process to be cached.  It will be cached either as an activity
18576                    // or empty depending on whether the activity is finishing.  We do
18577                    // this so that we can treat the process as cached for purposes of
18578                    // memory trimming (determing current memory level, trim command to
18579                    // send to process) since there can be an arbitrary number of stopping
18580                    // processes and they should soon all go into the cached state.
18581                    if (!r.finishing) {
18582                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18583                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18584                        }
18585                    }
18586                    app.cached = false;
18587                    app.empty = false;
18588                    foregroundActivities = true;
18589                } else {
18590                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18591                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18592                        app.adjType = "cch-act";
18593                    }
18594                }
18595            }
18596            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18597                adj += minLayer;
18598            }
18599        }
18600
18601        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18602                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18603            if (app.foregroundServices) {
18604                // The user is aware of this app, so make it visible.
18605                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18606                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18607                app.cached = false;
18608                app.adjType = "fg-service";
18609                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18610            } else if (app.forcingToForeground != null) {
18611                // The user is aware of this app, so make it visible.
18612                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18613                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18614                app.cached = false;
18615                app.adjType = "force-fg";
18616                app.adjSource = app.forcingToForeground;
18617                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18618            }
18619        }
18620
18621        if (app == mHeavyWeightProcess) {
18622            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18623                // We don't want to kill the current heavy-weight process.
18624                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18625                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18626                app.cached = false;
18627                app.adjType = "heavy";
18628            }
18629            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18630                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18631            }
18632        }
18633
18634        if (app == mHomeProcess) {
18635            if (adj > ProcessList.HOME_APP_ADJ) {
18636                // This process is hosting what we currently consider to be the
18637                // home app, so we don't want to let it go into the background.
18638                adj = ProcessList.HOME_APP_ADJ;
18639                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18640                app.cached = false;
18641                app.adjType = "home";
18642            }
18643            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18644                procState = ActivityManager.PROCESS_STATE_HOME;
18645            }
18646        }
18647
18648        if (app == mPreviousProcess && app.activities.size() > 0) {
18649            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18650                // This was the previous process that showed UI to the user.
18651                // We want to try to keep it around more aggressively, to give
18652                // a good experience around switching between two apps.
18653                adj = ProcessList.PREVIOUS_APP_ADJ;
18654                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18655                app.cached = false;
18656                app.adjType = "previous";
18657            }
18658            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18659                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18660            }
18661        }
18662
18663        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18664                + " reason=" + app.adjType);
18665
18666        // By default, we use the computed adjustment.  It may be changed if
18667        // there are applications dependent on our services or providers, but
18668        // this gives us a baseline and makes sure we don't get into an
18669        // infinite recursion.
18670        app.adjSeq = mAdjSeq;
18671        app.curRawAdj = adj;
18672        app.hasStartedServices = false;
18673
18674        if (mBackupTarget != null && app == mBackupTarget.app) {
18675            // If possible we want to avoid killing apps while they're being backed up
18676            if (adj > ProcessList.BACKUP_APP_ADJ) {
18677                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18678                adj = ProcessList.BACKUP_APP_ADJ;
18679                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18680                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18681                }
18682                app.adjType = "backup";
18683                app.cached = false;
18684            }
18685            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18686                procState = ActivityManager.PROCESS_STATE_BACKUP;
18687            }
18688        }
18689
18690        boolean mayBeTop = false;
18691
18692        for (int is = app.services.size()-1;
18693                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18694                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18695                        || procState > ActivityManager.PROCESS_STATE_TOP);
18696                is--) {
18697            ServiceRecord s = app.services.valueAt(is);
18698            if (s.startRequested) {
18699                app.hasStartedServices = true;
18700                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18701                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18702                }
18703                if (app.hasShownUi && app != mHomeProcess) {
18704                    // If this process has shown some UI, let it immediately
18705                    // go to the LRU list because it may be pretty heavy with
18706                    // UI stuff.  We'll tag it with a label just to help
18707                    // debug and understand what is going on.
18708                    if (adj > ProcessList.SERVICE_ADJ) {
18709                        app.adjType = "cch-started-ui-services";
18710                    }
18711                } else {
18712                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18713                        // This service has seen some activity within
18714                        // recent memory, so we will keep its process ahead
18715                        // of the background processes.
18716                        if (adj > ProcessList.SERVICE_ADJ) {
18717                            adj = ProcessList.SERVICE_ADJ;
18718                            app.adjType = "started-services";
18719                            app.cached = false;
18720                        }
18721                    }
18722                    // If we have let the service slide into the background
18723                    // state, still have some text describing what it is doing
18724                    // even though the service no longer has an impact.
18725                    if (adj > ProcessList.SERVICE_ADJ) {
18726                        app.adjType = "cch-started-services";
18727                    }
18728                }
18729            }
18730            for (int conni = s.connections.size()-1;
18731                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18732                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18733                            || procState > ActivityManager.PROCESS_STATE_TOP);
18734                    conni--) {
18735                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18736                for (int i = 0;
18737                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18738                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18739                                || procState > ActivityManager.PROCESS_STATE_TOP);
18740                        i++) {
18741                    // XXX should compute this based on the max of
18742                    // all connected clients.
18743                    ConnectionRecord cr = clist.get(i);
18744                    if (cr.binding.client == app) {
18745                        // Binding to ourself is not interesting.
18746                        continue;
18747                    }
18748                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18749                        ProcessRecord client = cr.binding.client;
18750                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18751                                TOP_APP, doingAll, now);
18752                        int clientProcState = client.curProcState;
18753                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18754                            // If the other app is cached for any reason, for purposes here
18755                            // we are going to consider it empty.  The specific cached state
18756                            // doesn't propagate except under certain conditions.
18757                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18758                        }
18759                        String adjType = null;
18760                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18761                            // Not doing bind OOM management, so treat
18762                            // this guy more like a started service.
18763                            if (app.hasShownUi && app != mHomeProcess) {
18764                                // If this process has shown some UI, let it immediately
18765                                // go to the LRU list because it may be pretty heavy with
18766                                // UI stuff.  We'll tag it with a label just to help
18767                                // debug and understand what is going on.
18768                                if (adj > clientAdj) {
18769                                    adjType = "cch-bound-ui-services";
18770                                }
18771                                app.cached = false;
18772                                clientAdj = adj;
18773                                clientProcState = procState;
18774                            } else {
18775                                if (now >= (s.lastActivity
18776                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18777                                    // This service has not seen activity within
18778                                    // recent memory, so allow it to drop to the
18779                                    // LRU list if there is no other reason to keep
18780                                    // it around.  We'll also tag it with a label just
18781                                    // to help debug and undertand what is going on.
18782                                    if (adj > clientAdj) {
18783                                        adjType = "cch-bound-services";
18784                                    }
18785                                    clientAdj = adj;
18786                                }
18787                            }
18788                        }
18789                        if (adj > clientAdj) {
18790                            // If this process has recently shown UI, and
18791                            // the process that is binding to it is less
18792                            // important than being visible, then we don't
18793                            // care about the binding as much as we care
18794                            // about letting this process get into the LRU
18795                            // list to be killed and restarted if needed for
18796                            // memory.
18797                            if (app.hasShownUi && app != mHomeProcess
18798                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18799                                adjType = "cch-bound-ui-services";
18800                            } else {
18801                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18802                                        |Context.BIND_IMPORTANT)) != 0) {
18803                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18804                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18805                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18806                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18807                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18808                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18809                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18810                                    adj = clientAdj;
18811                                } else {
18812                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18813                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18814                                    }
18815                                }
18816                                if (!client.cached) {
18817                                    app.cached = false;
18818                                }
18819                                adjType = "service";
18820                            }
18821                        }
18822                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18823                            // This will treat important bound services identically to
18824                            // the top app, which may behave differently than generic
18825                            // foreground work.
18826                            if (client.curSchedGroup > schedGroup) {
18827                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18828                                    schedGroup = client.curSchedGroup;
18829                                } else {
18830                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18831                                }
18832                            }
18833                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18834                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18835                                    // Special handling of clients who are in the top state.
18836                                    // We *may* want to consider this process to be in the
18837                                    // top state as well, but only if there is not another
18838                                    // reason for it to be running.  Being on the top is a
18839                                    // special state, meaning you are specifically running
18840                                    // for the current top app.  If the process is already
18841                                    // running in the background for some other reason, it
18842                                    // is more important to continue considering it to be
18843                                    // in the background state.
18844                                    mayBeTop = true;
18845                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18846                                } else {
18847                                    // Special handling for above-top states (persistent
18848                                    // processes).  These should not bring the current process
18849                                    // into the top state, since they are not on top.  Instead
18850                                    // give them the best state after that.
18851                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18852                                        clientProcState =
18853                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18854                                    } else if (mWakefulness
18855                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18856                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18857                                                    != 0) {
18858                                        clientProcState =
18859                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18860                                    } else {
18861                                        clientProcState =
18862                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18863                                    }
18864                                }
18865                            }
18866                        } else {
18867                            if (clientProcState <
18868                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18869                                clientProcState =
18870                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18871                            }
18872                        }
18873                        if (procState > clientProcState) {
18874                            procState = clientProcState;
18875                        }
18876                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18877                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18878                            app.pendingUiClean = true;
18879                        }
18880                        if (adjType != null) {
18881                            app.adjType = adjType;
18882                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18883                                    .REASON_SERVICE_IN_USE;
18884                            app.adjSource = cr.binding.client;
18885                            app.adjSourceProcState = clientProcState;
18886                            app.adjTarget = s.name;
18887                        }
18888                    }
18889                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18890                        app.treatLikeActivity = true;
18891                    }
18892                    final ActivityRecord a = cr.activity;
18893                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18894                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18895                            (a.visible || a.state == ActivityState.RESUMED ||
18896                             a.state == ActivityState.PAUSING)) {
18897                            adj = ProcessList.FOREGROUND_APP_ADJ;
18898                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18899                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18900                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18901                                } else {
18902                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18903                                }
18904                            }
18905                            app.cached = false;
18906                            app.adjType = "service";
18907                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18908                                    .REASON_SERVICE_IN_USE;
18909                            app.adjSource = a;
18910                            app.adjSourceProcState = procState;
18911                            app.adjTarget = s.name;
18912                        }
18913                    }
18914                }
18915            }
18916        }
18917
18918        for (int provi = app.pubProviders.size()-1;
18919                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18920                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18921                        || procState > ActivityManager.PROCESS_STATE_TOP);
18922                provi--) {
18923            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18924            for (int i = cpr.connections.size()-1;
18925                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18926                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18927                            || procState > ActivityManager.PROCESS_STATE_TOP);
18928                    i--) {
18929                ContentProviderConnection conn = cpr.connections.get(i);
18930                ProcessRecord client = conn.client;
18931                if (client == app) {
18932                    // Being our own client is not interesting.
18933                    continue;
18934                }
18935                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18936                int clientProcState = client.curProcState;
18937                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18938                    // If the other app is cached for any reason, for purposes here
18939                    // we are going to consider it empty.
18940                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18941                }
18942                if (adj > clientAdj) {
18943                    if (app.hasShownUi && app != mHomeProcess
18944                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18945                        app.adjType = "cch-ui-provider";
18946                    } else {
18947                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18948                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18949                        app.adjType = "provider";
18950                    }
18951                    app.cached &= client.cached;
18952                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18953                            .REASON_PROVIDER_IN_USE;
18954                    app.adjSource = client;
18955                    app.adjSourceProcState = clientProcState;
18956                    app.adjTarget = cpr.name;
18957                }
18958                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18959                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18960                        // Special handling of clients who are in the top state.
18961                        // We *may* want to consider this process to be in the
18962                        // top state as well, but only if there is not another
18963                        // reason for it to be running.  Being on the top is a
18964                        // special state, meaning you are specifically running
18965                        // for the current top app.  If the process is already
18966                        // running in the background for some other reason, it
18967                        // is more important to continue considering it to be
18968                        // in the background state.
18969                        mayBeTop = true;
18970                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18971                    } else {
18972                        // Special handling for above-top states (persistent
18973                        // processes).  These should not bring the current process
18974                        // into the top state, since they are not on top.  Instead
18975                        // give them the best state after that.
18976                        clientProcState =
18977                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18978                    }
18979                }
18980                if (procState > clientProcState) {
18981                    procState = clientProcState;
18982                }
18983                if (client.curSchedGroup > schedGroup) {
18984                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18985                }
18986            }
18987            // If the provider has external (non-framework) process
18988            // dependencies, ensure that its adjustment is at least
18989            // FOREGROUND_APP_ADJ.
18990            if (cpr.hasExternalProcessHandles()) {
18991                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18992                    adj = ProcessList.FOREGROUND_APP_ADJ;
18993                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18994                    app.cached = false;
18995                    app.adjType = "provider";
18996                    app.adjTarget = cpr.name;
18997                }
18998                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18999                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19000                }
19001            }
19002        }
19003
19004        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19005            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19006                adj = ProcessList.PREVIOUS_APP_ADJ;
19007                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19008                app.cached = false;
19009                app.adjType = "provider";
19010            }
19011            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19012                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19013            }
19014        }
19015
19016        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19017            // A client of one of our services or providers is in the top state.  We
19018            // *may* want to be in the top state, but not if we are already running in
19019            // the background for some other reason.  For the decision here, we are going
19020            // to pick out a few specific states that we want to remain in when a client
19021            // is top (states that tend to be longer-term) and otherwise allow it to go
19022            // to the top state.
19023            switch (procState) {
19024                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19025                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19026                case ActivityManager.PROCESS_STATE_SERVICE:
19027                    // These all are longer-term states, so pull them up to the top
19028                    // of the background states, but not all the way to the top state.
19029                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19030                    break;
19031                default:
19032                    // Otherwise, top is a better choice, so take it.
19033                    procState = ActivityManager.PROCESS_STATE_TOP;
19034                    break;
19035            }
19036        }
19037
19038        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19039            if (app.hasClientActivities) {
19040                // This is a cached process, but with client activities.  Mark it so.
19041                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19042                app.adjType = "cch-client-act";
19043            } else if (app.treatLikeActivity) {
19044                // This is a cached process, but somebody wants us to treat it like it has
19045                // an activity, okay!
19046                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19047                app.adjType = "cch-as-act";
19048            }
19049        }
19050
19051        if (adj == ProcessList.SERVICE_ADJ) {
19052            if (doingAll) {
19053                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19054                mNewNumServiceProcs++;
19055                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19056                if (!app.serviceb) {
19057                    // This service isn't far enough down on the LRU list to
19058                    // normally be a B service, but if we are low on RAM and it
19059                    // is large we want to force it down since we would prefer to
19060                    // keep launcher over it.
19061                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19062                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19063                        app.serviceHighRam = true;
19064                        app.serviceb = true;
19065                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19066                    } else {
19067                        mNewNumAServiceProcs++;
19068                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19069                    }
19070                } else {
19071                    app.serviceHighRam = false;
19072                }
19073            }
19074            if (app.serviceb) {
19075                adj = ProcessList.SERVICE_B_ADJ;
19076            }
19077        }
19078
19079        app.curRawAdj = adj;
19080
19081        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19082        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19083        if (adj > app.maxAdj) {
19084            adj = app.maxAdj;
19085            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19086                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19087            }
19088        }
19089
19090        // Do final modification to adj.  Everything we do between here and applying
19091        // the final setAdj must be done in this function, because we will also use
19092        // it when computing the final cached adj later.  Note that we don't need to
19093        // worry about this for max adj above, since max adj will always be used to
19094        // keep it out of the cached vaues.
19095        app.curAdj = app.modifyRawOomAdj(adj);
19096        app.curSchedGroup = schedGroup;
19097        app.curProcState = procState;
19098        app.foregroundActivities = foregroundActivities;
19099
19100        return app.curRawAdj;
19101    }
19102
19103    /**
19104     * Record new PSS sample for a process.
19105     */
19106    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19107            long now) {
19108        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19109                swapPss * 1024);
19110        proc.lastPssTime = now;
19111        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19112        if (DEBUG_PSS) Slog.d(TAG_PSS,
19113                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19114                + " state=" + ProcessList.makeProcStateString(procState));
19115        if (proc.initialIdlePss == 0) {
19116            proc.initialIdlePss = pss;
19117        }
19118        proc.lastPss = pss;
19119        proc.lastSwapPss = swapPss;
19120        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19121            proc.lastCachedPss = pss;
19122            proc.lastCachedSwapPss = swapPss;
19123        }
19124
19125        final SparseArray<Pair<Long, String>> watchUids
19126                = mMemWatchProcesses.getMap().get(proc.processName);
19127        Long check = null;
19128        if (watchUids != null) {
19129            Pair<Long, String> val = watchUids.get(proc.uid);
19130            if (val == null) {
19131                val = watchUids.get(0);
19132            }
19133            if (val != null) {
19134                check = val.first;
19135            }
19136        }
19137        if (check != null) {
19138            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19139                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19140                if (!isDebuggable) {
19141                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19142                        isDebuggable = true;
19143                    }
19144                }
19145                if (isDebuggable) {
19146                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19147                    final ProcessRecord myProc = proc;
19148                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19149                    mMemWatchDumpProcName = proc.processName;
19150                    mMemWatchDumpFile = heapdumpFile.toString();
19151                    mMemWatchDumpPid = proc.pid;
19152                    mMemWatchDumpUid = proc.uid;
19153                    BackgroundThread.getHandler().post(new Runnable() {
19154                        @Override
19155                        public void run() {
19156                            revokeUriPermission(ActivityThread.currentActivityThread()
19157                                            .getApplicationThread(),
19158                                    DumpHeapActivity.JAVA_URI,
19159                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19160                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19161                                    UserHandle.myUserId());
19162                            ParcelFileDescriptor fd = null;
19163                            try {
19164                                heapdumpFile.delete();
19165                                fd = ParcelFileDescriptor.open(heapdumpFile,
19166                                        ParcelFileDescriptor.MODE_CREATE |
19167                                                ParcelFileDescriptor.MODE_TRUNCATE |
19168                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19169                                                ParcelFileDescriptor.MODE_APPEND);
19170                                IApplicationThread thread = myProc.thread;
19171                                if (thread != null) {
19172                                    try {
19173                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19174                                                "Requesting dump heap from "
19175                                                + myProc + " to " + heapdumpFile);
19176                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19177                                    } catch (RemoteException e) {
19178                                    }
19179                                }
19180                            } catch (FileNotFoundException e) {
19181                                e.printStackTrace();
19182                            } finally {
19183                                if (fd != null) {
19184                                    try {
19185                                        fd.close();
19186                                    } catch (IOException e) {
19187                                    }
19188                                }
19189                            }
19190                        }
19191                    });
19192                } else {
19193                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19194                            + ", but debugging not enabled");
19195                }
19196            }
19197        }
19198    }
19199
19200    /**
19201     * Schedule PSS collection of a process.
19202     */
19203    void requestPssLocked(ProcessRecord proc, int procState) {
19204        if (mPendingPssProcesses.contains(proc)) {
19205            return;
19206        }
19207        if (mPendingPssProcesses.size() == 0) {
19208            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19209        }
19210        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19211        proc.pssProcState = procState;
19212        mPendingPssProcesses.add(proc);
19213    }
19214
19215    /**
19216     * Schedule PSS collection of all processes.
19217     */
19218    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19219        if (!always) {
19220            if (now < (mLastFullPssTime +
19221                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19222                return;
19223            }
19224        }
19225        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19226        mLastFullPssTime = now;
19227        mFullPssPending = true;
19228        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19229        mPendingPssProcesses.clear();
19230        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19231            ProcessRecord app = mLruProcesses.get(i);
19232            if (app.thread == null
19233                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19234                continue;
19235            }
19236            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19237                app.pssProcState = app.setProcState;
19238                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19239                        mTestPssMode, isSleeping(), now);
19240                mPendingPssProcesses.add(app);
19241            }
19242        }
19243        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19244    }
19245
19246    public void setTestPssMode(boolean enabled) {
19247        synchronized (this) {
19248            mTestPssMode = enabled;
19249            if (enabled) {
19250                // Whenever we enable the mode, we want to take a snapshot all of current
19251                // process mem use.
19252                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19253            }
19254        }
19255    }
19256
19257    /**
19258     * Ask a given process to GC right now.
19259     */
19260    final void performAppGcLocked(ProcessRecord app) {
19261        try {
19262            app.lastRequestedGc = SystemClock.uptimeMillis();
19263            if (app.thread != null) {
19264                if (app.reportLowMemory) {
19265                    app.reportLowMemory = false;
19266                    app.thread.scheduleLowMemory();
19267                } else {
19268                    app.thread.processInBackground();
19269                }
19270            }
19271        } catch (Exception e) {
19272            // whatever.
19273        }
19274    }
19275
19276    /**
19277     * Returns true if things are idle enough to perform GCs.
19278     */
19279    private final boolean canGcNowLocked() {
19280        boolean processingBroadcasts = false;
19281        for (BroadcastQueue q : mBroadcastQueues) {
19282            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19283                processingBroadcasts = true;
19284            }
19285        }
19286        return !processingBroadcasts
19287                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19288    }
19289
19290    /**
19291     * Perform GCs on all processes that are waiting for it, but only
19292     * if things are idle.
19293     */
19294    final void performAppGcsLocked() {
19295        final int N = mProcessesToGc.size();
19296        if (N <= 0) {
19297            return;
19298        }
19299        if (canGcNowLocked()) {
19300            while (mProcessesToGc.size() > 0) {
19301                ProcessRecord proc = mProcessesToGc.remove(0);
19302                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19303                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19304                            <= SystemClock.uptimeMillis()) {
19305                        // To avoid spamming the system, we will GC processes one
19306                        // at a time, waiting a few seconds between each.
19307                        performAppGcLocked(proc);
19308                        scheduleAppGcsLocked();
19309                        return;
19310                    } else {
19311                        // It hasn't been long enough since we last GCed this
19312                        // process...  put it in the list to wait for its time.
19313                        addProcessToGcListLocked(proc);
19314                        break;
19315                    }
19316                }
19317            }
19318
19319            scheduleAppGcsLocked();
19320        }
19321    }
19322
19323    /**
19324     * If all looks good, perform GCs on all processes waiting for them.
19325     */
19326    final void performAppGcsIfAppropriateLocked() {
19327        if (canGcNowLocked()) {
19328            performAppGcsLocked();
19329            return;
19330        }
19331        // Still not idle, wait some more.
19332        scheduleAppGcsLocked();
19333    }
19334
19335    /**
19336     * Schedule the execution of all pending app GCs.
19337     */
19338    final void scheduleAppGcsLocked() {
19339        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19340
19341        if (mProcessesToGc.size() > 0) {
19342            // Schedule a GC for the time to the next process.
19343            ProcessRecord proc = mProcessesToGc.get(0);
19344            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19345
19346            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19347            long now = SystemClock.uptimeMillis();
19348            if (when < (now+GC_TIMEOUT)) {
19349                when = now + GC_TIMEOUT;
19350            }
19351            mHandler.sendMessageAtTime(msg, when);
19352        }
19353    }
19354
19355    /**
19356     * Add a process to the array of processes waiting to be GCed.  Keeps the
19357     * list in sorted order by the last GC time.  The process can't already be
19358     * on the list.
19359     */
19360    final void addProcessToGcListLocked(ProcessRecord proc) {
19361        boolean added = false;
19362        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19363            if (mProcessesToGc.get(i).lastRequestedGc <
19364                    proc.lastRequestedGc) {
19365                added = true;
19366                mProcessesToGc.add(i+1, proc);
19367                break;
19368            }
19369        }
19370        if (!added) {
19371            mProcessesToGc.add(0, proc);
19372        }
19373    }
19374
19375    /**
19376     * Set up to ask a process to GC itself.  This will either do it
19377     * immediately, or put it on the list of processes to gc the next
19378     * time things are idle.
19379     */
19380    final void scheduleAppGcLocked(ProcessRecord app) {
19381        long now = SystemClock.uptimeMillis();
19382        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19383            return;
19384        }
19385        if (!mProcessesToGc.contains(app)) {
19386            addProcessToGcListLocked(app);
19387            scheduleAppGcsLocked();
19388        }
19389    }
19390
19391    final void checkExcessivePowerUsageLocked(boolean doKills) {
19392        updateCpuStatsNow();
19393
19394        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19395        boolean doWakeKills = doKills;
19396        boolean doCpuKills = doKills;
19397        if (mLastPowerCheckRealtime == 0) {
19398            doWakeKills = false;
19399        }
19400        if (mLastPowerCheckUptime == 0) {
19401            doCpuKills = false;
19402        }
19403        if (stats.isScreenOn()) {
19404            doWakeKills = false;
19405        }
19406        final long curRealtime = SystemClock.elapsedRealtime();
19407        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19408        final long curUptime = SystemClock.uptimeMillis();
19409        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19410        mLastPowerCheckRealtime = curRealtime;
19411        mLastPowerCheckUptime = curUptime;
19412        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19413            doWakeKills = false;
19414        }
19415        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19416            doCpuKills = false;
19417        }
19418        int i = mLruProcesses.size();
19419        while (i > 0) {
19420            i--;
19421            ProcessRecord app = mLruProcesses.get(i);
19422            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19423                long wtime;
19424                synchronized (stats) {
19425                    wtime = stats.getProcessWakeTime(app.info.uid,
19426                            app.pid, curRealtime);
19427                }
19428                long wtimeUsed = wtime - app.lastWakeTime;
19429                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19430                if (DEBUG_POWER) {
19431                    StringBuilder sb = new StringBuilder(128);
19432                    sb.append("Wake for ");
19433                    app.toShortString(sb);
19434                    sb.append(": over ");
19435                    TimeUtils.formatDuration(realtimeSince, sb);
19436                    sb.append(" used ");
19437                    TimeUtils.formatDuration(wtimeUsed, sb);
19438                    sb.append(" (");
19439                    sb.append((wtimeUsed*100)/realtimeSince);
19440                    sb.append("%)");
19441                    Slog.i(TAG_POWER, sb.toString());
19442                    sb.setLength(0);
19443                    sb.append("CPU for ");
19444                    app.toShortString(sb);
19445                    sb.append(": over ");
19446                    TimeUtils.formatDuration(uptimeSince, sb);
19447                    sb.append(" used ");
19448                    TimeUtils.formatDuration(cputimeUsed, sb);
19449                    sb.append(" (");
19450                    sb.append((cputimeUsed*100)/uptimeSince);
19451                    sb.append("%)");
19452                    Slog.i(TAG_POWER, sb.toString());
19453                }
19454                // If a process has held a wake lock for more
19455                // than 50% of the time during this period,
19456                // that sounds bad.  Kill!
19457                if (doWakeKills && realtimeSince > 0
19458                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19459                    synchronized (stats) {
19460                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19461                                realtimeSince, wtimeUsed);
19462                    }
19463                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19464                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19465                } else if (doCpuKills && uptimeSince > 0
19466                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19467                    synchronized (stats) {
19468                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19469                                uptimeSince, cputimeUsed);
19470                    }
19471                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19472                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19473                } else {
19474                    app.lastWakeTime = wtime;
19475                    app.lastCpuTime = app.curCpuTime;
19476                }
19477            }
19478        }
19479    }
19480
19481    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19482            long nowElapsed) {
19483        boolean success = true;
19484
19485        if (app.curRawAdj != app.setRawAdj) {
19486            app.setRawAdj = app.curRawAdj;
19487        }
19488
19489        int changes = 0;
19490
19491        if (app.curAdj != app.setAdj) {
19492            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19493            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19494                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19495                    + app.adjType);
19496            app.setAdj = app.curAdj;
19497        }
19498
19499        if (app.setSchedGroup != app.curSchedGroup) {
19500            app.setSchedGroup = app.curSchedGroup;
19501            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19502                    "Setting sched group of " + app.processName
19503                    + " to " + app.curSchedGroup);
19504            if (app.waitingToKill != null && app.curReceiver == null
19505                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19506                app.kill(app.waitingToKill, true);
19507                success = false;
19508            } else {
19509                int processGroup;
19510                switch (app.curSchedGroup) {
19511                    case ProcessList.SCHED_GROUP_BACKGROUND:
19512                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19513                        break;
19514                    case ProcessList.SCHED_GROUP_TOP_APP:
19515                        processGroup = Process.THREAD_GROUP_TOP_APP;
19516                        break;
19517                    default:
19518                        processGroup = Process.THREAD_GROUP_DEFAULT;
19519                        break;
19520                }
19521                if (true) {
19522                    long oldId = Binder.clearCallingIdentity();
19523                    try {
19524                        Process.setProcessGroup(app.pid, processGroup);
19525                    } catch (Exception e) {
19526                        Slog.w(TAG, "Failed setting process group of " + app.pid
19527                                + " to " + app.curSchedGroup);
19528                        e.printStackTrace();
19529                    } finally {
19530                        Binder.restoreCallingIdentity(oldId);
19531                    }
19532                } else {
19533                    if (app.thread != null) {
19534                        try {
19535                            app.thread.setSchedulingGroup(processGroup);
19536                        } catch (RemoteException e) {
19537                        }
19538                    }
19539                }
19540            }
19541        }
19542        if (app.repForegroundActivities != app.foregroundActivities) {
19543            app.repForegroundActivities = app.foregroundActivities;
19544            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19545        }
19546        if (app.repProcState != app.curProcState) {
19547            app.repProcState = app.curProcState;
19548            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19549            if (app.thread != null) {
19550                try {
19551                    if (false) {
19552                        //RuntimeException h = new RuntimeException("here");
19553                        Slog.i(TAG, "Sending new process state " + app.repProcState
19554                                + " to " + app /*, h*/);
19555                    }
19556                    app.thread.setProcessState(app.repProcState);
19557                } catch (RemoteException e) {
19558                }
19559            }
19560        }
19561        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19562                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19563            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19564                // Experimental code to more aggressively collect pss while
19565                // running test...  the problem is that this tends to collect
19566                // the data right when a process is transitioning between process
19567                // states, which well tend to give noisy data.
19568                long start = SystemClock.uptimeMillis();
19569                long pss = Debug.getPss(app.pid, mTmpLong, null);
19570                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19571                mPendingPssProcesses.remove(app);
19572                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19573                        + " to " + app.curProcState + ": "
19574                        + (SystemClock.uptimeMillis()-start) + "ms");
19575            }
19576            app.lastStateTime = now;
19577            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19578                    mTestPssMode, isSleeping(), now);
19579            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19580                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19581                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19582                    + (app.nextPssTime-now) + ": " + app);
19583        } else {
19584            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19585                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19586                    mTestPssMode)))) {
19587                requestPssLocked(app, app.setProcState);
19588                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19589                        mTestPssMode, isSleeping(), now);
19590            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19591                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19592        }
19593        if (app.setProcState != app.curProcState) {
19594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19595                    "Proc state change of " + app.processName
19596                            + " to " + app.curProcState);
19597            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19598            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19599            if (setImportant && !curImportant) {
19600                // This app is no longer something we consider important enough to allow to
19601                // use arbitrary amounts of battery power.  Note
19602                // its current wake lock time to later know to kill it if
19603                // it is not behaving well.
19604                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19605                synchronized (stats) {
19606                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19607                            app.pid, nowElapsed);
19608                }
19609                app.lastCpuTime = app.curCpuTime;
19610
19611            }
19612            // Inform UsageStats of important process state change
19613            // Must be called before updating setProcState
19614            maybeUpdateUsageStatsLocked(app, nowElapsed);
19615
19616            app.setProcState = app.curProcState;
19617            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19618                app.notCachedSinceIdle = false;
19619            }
19620            if (!doingAll) {
19621                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19622            } else {
19623                app.procStateChanged = true;
19624            }
19625        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19626                > USAGE_STATS_INTERACTION_INTERVAL) {
19627            // For apps that sit around for a long time in the interactive state, we need
19628            // to report this at least once a day so they don't go idle.
19629            maybeUpdateUsageStatsLocked(app, nowElapsed);
19630        }
19631
19632        if (changes != 0) {
19633            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19634                    "Changes in " + app + ": " + changes);
19635            int i = mPendingProcessChanges.size()-1;
19636            ProcessChangeItem item = null;
19637            while (i >= 0) {
19638                item = mPendingProcessChanges.get(i);
19639                if (item.pid == app.pid) {
19640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19641                            "Re-using existing item: " + item);
19642                    break;
19643                }
19644                i--;
19645            }
19646            if (i < 0) {
19647                // No existing item in pending changes; need a new one.
19648                final int NA = mAvailProcessChanges.size();
19649                if (NA > 0) {
19650                    item = mAvailProcessChanges.remove(NA-1);
19651                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19652                            "Retrieving available item: " + item);
19653                } else {
19654                    item = new ProcessChangeItem();
19655                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19656                            "Allocating new item: " + item);
19657                }
19658                item.changes = 0;
19659                item.pid = app.pid;
19660                item.uid = app.info.uid;
19661                if (mPendingProcessChanges.size() == 0) {
19662                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19663                            "*** Enqueueing dispatch processes changed!");
19664                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19665                }
19666                mPendingProcessChanges.add(item);
19667            }
19668            item.changes |= changes;
19669            item.processState = app.repProcState;
19670            item.foregroundActivities = app.repForegroundActivities;
19671            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19672                    "Item " + Integer.toHexString(System.identityHashCode(item))
19673                    + " " + app.toShortString() + ": changes=" + item.changes
19674                    + " procState=" + item.processState
19675                    + " foreground=" + item.foregroundActivities
19676                    + " type=" + app.adjType + " source=" + app.adjSource
19677                    + " target=" + app.adjTarget);
19678        }
19679
19680        return success;
19681    }
19682
19683    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19684        final UidRecord.ChangeItem pendingChange;
19685        if (uidRec == null || uidRec.pendingChange == null) {
19686            if (mPendingUidChanges.size() == 0) {
19687                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19688                        "*** Enqueueing dispatch uid changed!");
19689                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19690            }
19691            final int NA = mAvailUidChanges.size();
19692            if (NA > 0) {
19693                pendingChange = mAvailUidChanges.remove(NA-1);
19694                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19695                        "Retrieving available item: " + pendingChange);
19696            } else {
19697                pendingChange = new UidRecord.ChangeItem();
19698                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19699                        "Allocating new item: " + pendingChange);
19700            }
19701            if (uidRec != null) {
19702                uidRec.pendingChange = pendingChange;
19703                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19704                    // If this uid is going away, and we haven't yet reported it is gone,
19705                    // then do so now.
19706                    change = UidRecord.CHANGE_GONE_IDLE;
19707                }
19708            } else if (uid < 0) {
19709                throw new IllegalArgumentException("No UidRecord or uid");
19710            }
19711            pendingChange.uidRecord = uidRec;
19712            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19713            mPendingUidChanges.add(pendingChange);
19714        } else {
19715            pendingChange = uidRec.pendingChange;
19716            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19717                change = UidRecord.CHANGE_GONE_IDLE;
19718            }
19719        }
19720        pendingChange.change = change;
19721        pendingChange.processState = uidRec != null
19722                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19723    }
19724
19725    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19726            String authority) {
19727        if (app == null) return;
19728        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19729            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19730            if (userState == null) return;
19731            final long now = SystemClock.elapsedRealtime();
19732            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19733            if (lastReported == null || lastReported < now - 60 * 1000L) {
19734                mUsageStatsService.reportContentProviderUsage(
19735                        authority, providerPkgName, app.userId);
19736                userState.mProviderLastReportedFg.put(authority, now);
19737            }
19738        }
19739    }
19740
19741    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19742        if (DEBUG_USAGE_STATS) {
19743            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19744                    + "] state changes: old = " + app.setProcState + ", new = "
19745                    + app.curProcState);
19746        }
19747        if (mUsageStatsService == null) {
19748            return;
19749        }
19750        boolean isInteraction;
19751        // To avoid some abuse patterns, we are going to be careful about what we consider
19752        // to be an app interaction.  Being the top activity doesn't count while the display
19753        // is sleeping, nor do short foreground services.
19754        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19755            isInteraction = true;
19756            app.fgInteractionTime = 0;
19757        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19758            if (app.fgInteractionTime == 0) {
19759                app.fgInteractionTime = nowElapsed;
19760                isInteraction = false;
19761            } else {
19762                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19763            }
19764        } else {
19765            isInteraction = app.curProcState
19766                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19767            app.fgInteractionTime = 0;
19768        }
19769        if (isInteraction && (!app.reportedInteraction
19770                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19771            app.interactionEventTime = nowElapsed;
19772            String[] packages = app.getPackageList();
19773            if (packages != null) {
19774                for (int i = 0; i < packages.length; i++) {
19775                    mUsageStatsService.reportEvent(packages[i], app.userId,
19776                            UsageEvents.Event.SYSTEM_INTERACTION);
19777                }
19778            }
19779        }
19780        app.reportedInteraction = isInteraction;
19781        if (!isInteraction) {
19782            app.interactionEventTime = 0;
19783        }
19784    }
19785
19786    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19787        if (proc.thread != null) {
19788            if (proc.baseProcessTracker != null) {
19789                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19790            }
19791        }
19792    }
19793
19794    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19795            ProcessRecord TOP_APP, boolean doingAll, long now) {
19796        if (app.thread == null) {
19797            return false;
19798        }
19799
19800        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19801
19802        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19803    }
19804
19805    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19806            boolean oomAdj) {
19807        if (isForeground != proc.foregroundServices) {
19808            proc.foregroundServices = isForeground;
19809            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19810                    proc.info.uid);
19811            if (isForeground) {
19812                if (curProcs == null) {
19813                    curProcs = new ArrayList<ProcessRecord>();
19814                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19815                }
19816                if (!curProcs.contains(proc)) {
19817                    curProcs.add(proc);
19818                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19819                            proc.info.packageName, proc.info.uid);
19820                }
19821            } else {
19822                if (curProcs != null) {
19823                    if (curProcs.remove(proc)) {
19824                        mBatteryStatsService.noteEvent(
19825                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19826                                proc.info.packageName, proc.info.uid);
19827                        if (curProcs.size() <= 0) {
19828                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19829                        }
19830                    }
19831                }
19832            }
19833            if (oomAdj) {
19834                updateOomAdjLocked();
19835            }
19836        }
19837    }
19838
19839    private final ActivityRecord resumedAppLocked() {
19840        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19841        String pkg;
19842        int uid;
19843        if (act != null) {
19844            pkg = act.packageName;
19845            uid = act.info.applicationInfo.uid;
19846        } else {
19847            pkg = null;
19848            uid = -1;
19849        }
19850        // Has the UID or resumed package name changed?
19851        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19852                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19853            if (mCurResumedPackage != null) {
19854                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19855                        mCurResumedPackage, mCurResumedUid);
19856            }
19857            mCurResumedPackage = pkg;
19858            mCurResumedUid = uid;
19859            if (mCurResumedPackage != null) {
19860                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19861                        mCurResumedPackage, mCurResumedUid);
19862            }
19863        }
19864        return act;
19865    }
19866
19867    final boolean updateOomAdjLocked(ProcessRecord app) {
19868        final ActivityRecord TOP_ACT = resumedAppLocked();
19869        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19870        final boolean wasCached = app.cached;
19871
19872        mAdjSeq++;
19873
19874        // This is the desired cached adjusment we want to tell it to use.
19875        // If our app is currently cached, we know it, and that is it.  Otherwise,
19876        // we don't know it yet, and it needs to now be cached we will then
19877        // need to do a complete oom adj.
19878        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19879                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19880        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19881                SystemClock.uptimeMillis());
19882        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19883            // Changed to/from cached state, so apps after it in the LRU
19884            // list may also be changed.
19885            updateOomAdjLocked();
19886        }
19887        return success;
19888    }
19889
19890    final void updateOomAdjLocked() {
19891        final ActivityRecord TOP_ACT = resumedAppLocked();
19892        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19893        final long now = SystemClock.uptimeMillis();
19894        final long nowElapsed = SystemClock.elapsedRealtime();
19895        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19896        final int N = mLruProcesses.size();
19897
19898        if (false) {
19899            RuntimeException e = new RuntimeException();
19900            e.fillInStackTrace();
19901            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19902        }
19903
19904        // Reset state in all uid records.
19905        for (int i=mActiveUids.size()-1; i>=0; i--) {
19906            final UidRecord uidRec = mActiveUids.valueAt(i);
19907            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19908                    "Starting update of " + uidRec);
19909            uidRec.reset();
19910        }
19911
19912        mStackSupervisor.rankTaskLayersIfNeeded();
19913
19914        mAdjSeq++;
19915        mNewNumServiceProcs = 0;
19916        mNewNumAServiceProcs = 0;
19917
19918        final int emptyProcessLimit;
19919        final int cachedProcessLimit;
19920        if (mProcessLimit <= 0) {
19921            emptyProcessLimit = cachedProcessLimit = 0;
19922        } else if (mProcessLimit == 1) {
19923            emptyProcessLimit = 1;
19924            cachedProcessLimit = 0;
19925        } else {
19926            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19927            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19928        }
19929
19930        // Let's determine how many processes we have running vs.
19931        // how many slots we have for background processes; we may want
19932        // to put multiple processes in a slot of there are enough of
19933        // them.
19934        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19935                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19936        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19937        if (numEmptyProcs > cachedProcessLimit) {
19938            // If there are more empty processes than our limit on cached
19939            // processes, then use the cached process limit for the factor.
19940            // This ensures that the really old empty processes get pushed
19941            // down to the bottom, so if we are running low on memory we will
19942            // have a better chance at keeping around more cached processes
19943            // instead of a gazillion empty processes.
19944            numEmptyProcs = cachedProcessLimit;
19945        }
19946        int emptyFactor = numEmptyProcs/numSlots;
19947        if (emptyFactor < 1) emptyFactor = 1;
19948        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19949        if (cachedFactor < 1) cachedFactor = 1;
19950        int stepCached = 0;
19951        int stepEmpty = 0;
19952        int numCached = 0;
19953        int numEmpty = 0;
19954        int numTrimming = 0;
19955
19956        mNumNonCachedProcs = 0;
19957        mNumCachedHiddenProcs = 0;
19958
19959        // First update the OOM adjustment for each of the
19960        // application processes based on their current state.
19961        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19962        int nextCachedAdj = curCachedAdj+1;
19963        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19964        int nextEmptyAdj = curEmptyAdj+2;
19965        for (int i=N-1; i>=0; i--) {
19966            ProcessRecord app = mLruProcesses.get(i);
19967            if (!app.killedByAm && app.thread != null) {
19968                app.procStateChanged = false;
19969                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19970
19971                // If we haven't yet assigned the final cached adj
19972                // to the process, do that now.
19973                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19974                    switch (app.curProcState) {
19975                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19976                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19977                            // This process is a cached process holding activities...
19978                            // assign it the next cached value for that type, and then
19979                            // step that cached level.
19980                            app.curRawAdj = curCachedAdj;
19981                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19982                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19983                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19984                                    + ")");
19985                            if (curCachedAdj != nextCachedAdj) {
19986                                stepCached++;
19987                                if (stepCached >= cachedFactor) {
19988                                    stepCached = 0;
19989                                    curCachedAdj = nextCachedAdj;
19990                                    nextCachedAdj += 2;
19991                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19992                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19993                                    }
19994                                }
19995                            }
19996                            break;
19997                        default:
19998                            // For everything else, assign next empty cached process
19999                            // level and bump that up.  Note that this means that
20000                            // long-running services that have dropped down to the
20001                            // cached level will be treated as empty (since their process
20002                            // state is still as a service), which is what we want.
20003                            app.curRawAdj = curEmptyAdj;
20004                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20005                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20006                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20007                                    + ")");
20008                            if (curEmptyAdj != nextEmptyAdj) {
20009                                stepEmpty++;
20010                                if (stepEmpty >= emptyFactor) {
20011                                    stepEmpty = 0;
20012                                    curEmptyAdj = nextEmptyAdj;
20013                                    nextEmptyAdj += 2;
20014                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20015                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20016                                    }
20017                                }
20018                            }
20019                            break;
20020                    }
20021                }
20022
20023                applyOomAdjLocked(app, true, now, nowElapsed);
20024
20025                // Count the number of process types.
20026                switch (app.curProcState) {
20027                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20028                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20029                        mNumCachedHiddenProcs++;
20030                        numCached++;
20031                        if (numCached > cachedProcessLimit) {
20032                            app.kill("cached #" + numCached, true);
20033                        }
20034                        break;
20035                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20036                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20037                                && app.lastActivityTime < oldTime) {
20038                            app.kill("empty for "
20039                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20040                                    / 1000) + "s", true);
20041                        } else {
20042                            numEmpty++;
20043                            if (numEmpty > emptyProcessLimit) {
20044                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20045                            }
20046                        }
20047                        break;
20048                    default:
20049                        mNumNonCachedProcs++;
20050                        break;
20051                }
20052
20053                if (app.isolated && app.services.size() <= 0) {
20054                    // If this is an isolated process, and there are no
20055                    // services running in it, then the process is no longer
20056                    // needed.  We agressively kill these because we can by
20057                    // definition not re-use the same process again, and it is
20058                    // good to avoid having whatever code was running in them
20059                    // left sitting around after no longer needed.
20060                    app.kill("isolated not needed", true);
20061                } else {
20062                    // Keeping this process, update its uid.
20063                    final UidRecord uidRec = app.uidRecord;
20064                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20065                        uidRec.curProcState = app.curProcState;
20066                    }
20067                }
20068
20069                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20070                        && !app.killedByAm) {
20071                    numTrimming++;
20072                }
20073            }
20074        }
20075
20076        mNumServiceProcs = mNewNumServiceProcs;
20077
20078        // Now determine the memory trimming level of background processes.
20079        // Unfortunately we need to start at the back of the list to do this
20080        // properly.  We only do this if the number of background apps we
20081        // are managing to keep around is less than half the maximum we desire;
20082        // if we are keeping a good number around, we'll let them use whatever
20083        // memory they want.
20084        final int numCachedAndEmpty = numCached + numEmpty;
20085        int memFactor;
20086        if (numCached <= ProcessList.TRIM_CACHED_APPS
20087                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20088            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20089                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20090            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20091                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20092            } else {
20093                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20094            }
20095        } else {
20096            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20097        }
20098        // We always allow the memory level to go up (better).  We only allow it to go
20099        // down if we are in a state where that is allowed, *and* the total number of processes
20100        // has gone down since last time.
20101        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20102                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20103                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20104        if (memFactor > mLastMemoryLevel) {
20105            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20106                memFactor = mLastMemoryLevel;
20107                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20108            }
20109        }
20110        if (memFactor != mLastMemoryLevel) {
20111            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20112        }
20113        mLastMemoryLevel = memFactor;
20114        mLastNumProcesses = mLruProcesses.size();
20115        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20116        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20117        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20118            if (mLowRamStartTime == 0) {
20119                mLowRamStartTime = now;
20120            }
20121            int step = 0;
20122            int fgTrimLevel;
20123            switch (memFactor) {
20124                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20125                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20126                    break;
20127                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20128                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20129                    break;
20130                default:
20131                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20132                    break;
20133            }
20134            int factor = numTrimming/3;
20135            int minFactor = 2;
20136            if (mHomeProcess != null) minFactor++;
20137            if (mPreviousProcess != null) minFactor++;
20138            if (factor < minFactor) factor = minFactor;
20139            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20140            for (int i=N-1; i>=0; i--) {
20141                ProcessRecord app = mLruProcesses.get(i);
20142                if (allChanged || app.procStateChanged) {
20143                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20144                    app.procStateChanged = false;
20145                }
20146                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20147                        && !app.killedByAm) {
20148                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20149                        try {
20150                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20151                                    "Trimming memory of " + app.processName + " to " + curLevel);
20152                            app.thread.scheduleTrimMemory(curLevel);
20153                        } catch (RemoteException e) {
20154                        }
20155                        if (false) {
20156                            // For now we won't do this; our memory trimming seems
20157                            // to be good enough at this point that destroying
20158                            // activities causes more harm than good.
20159                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20160                                    && app != mHomeProcess && app != mPreviousProcess) {
20161                                // Need to do this on its own message because the stack may not
20162                                // be in a consistent state at this point.
20163                                // For these apps we will also finish their activities
20164                                // to help them free memory.
20165                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20166                            }
20167                        }
20168                    }
20169                    app.trimMemoryLevel = curLevel;
20170                    step++;
20171                    if (step >= factor) {
20172                        step = 0;
20173                        switch (curLevel) {
20174                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20175                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20176                                break;
20177                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20178                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20179                                break;
20180                        }
20181                    }
20182                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20183                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20184                            && app.thread != null) {
20185                        try {
20186                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20187                                    "Trimming memory of heavy-weight " + app.processName
20188                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20189                            app.thread.scheduleTrimMemory(
20190                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20191                        } catch (RemoteException e) {
20192                        }
20193                    }
20194                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20195                } else {
20196                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20197                            || app.systemNoUi) && app.pendingUiClean) {
20198                        // If this application is now in the background and it
20199                        // had done UI, then give it the special trim level to
20200                        // have it free UI resources.
20201                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20202                        if (app.trimMemoryLevel < level && app.thread != null) {
20203                            try {
20204                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20205                                        "Trimming memory of bg-ui " + app.processName
20206                                        + " to " + level);
20207                                app.thread.scheduleTrimMemory(level);
20208                            } catch (RemoteException e) {
20209                            }
20210                        }
20211                        app.pendingUiClean = false;
20212                    }
20213                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20214                        try {
20215                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20216                                    "Trimming memory of fg " + app.processName
20217                                    + " to " + fgTrimLevel);
20218                            app.thread.scheduleTrimMemory(fgTrimLevel);
20219                        } catch (RemoteException e) {
20220                        }
20221                    }
20222                    app.trimMemoryLevel = fgTrimLevel;
20223                }
20224            }
20225        } else {
20226            if (mLowRamStartTime != 0) {
20227                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20228                mLowRamStartTime = 0;
20229            }
20230            for (int i=N-1; i>=0; i--) {
20231                ProcessRecord app = mLruProcesses.get(i);
20232                if (allChanged || app.procStateChanged) {
20233                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20234                    app.procStateChanged = false;
20235                }
20236                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20237                        || app.systemNoUi) && app.pendingUiClean) {
20238                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20239                            && app.thread != null) {
20240                        try {
20241                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20242                                    "Trimming memory of ui hidden " + app.processName
20243                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20244                            app.thread.scheduleTrimMemory(
20245                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20246                        } catch (RemoteException e) {
20247                        }
20248                    }
20249                    app.pendingUiClean = false;
20250                }
20251                app.trimMemoryLevel = 0;
20252            }
20253        }
20254
20255        if (mAlwaysFinishActivities) {
20256            // Need to do this on its own message because the stack may not
20257            // be in a consistent state at this point.
20258            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20259        }
20260
20261        if (allChanged) {
20262            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20263        }
20264
20265        // Update from any uid changes.
20266        for (int i=mActiveUids.size()-1; i>=0; i--) {
20267            final UidRecord uidRec = mActiveUids.valueAt(i);
20268            int uidChange = UidRecord.CHANGE_PROCSTATE;
20269            if (uidRec.setProcState != uidRec.curProcState) {
20270                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20271                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20272                        + " to " + uidRec.curProcState);
20273                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20274                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20275                        uidRec.lastBackgroundTime = nowElapsed;
20276                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20277                            // Note: the background settle time is in elapsed realtime, while
20278                            // the handler time base is uptime.  All this means is that we may
20279                            // stop background uids later than we had intended, but that only
20280                            // happens because the device was sleeping so we are okay anyway.
20281                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20282                        }
20283                    }
20284                } else {
20285                    if (uidRec.idle) {
20286                        uidChange = UidRecord.CHANGE_ACTIVE;
20287                        uidRec.idle = false;
20288                    }
20289                    uidRec.lastBackgroundTime = 0;
20290                }
20291                uidRec.setProcState = uidRec.curProcState;
20292                enqueueUidChangeLocked(uidRec, -1, uidChange);
20293                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20294            }
20295        }
20296
20297        if (mProcessStats.shouldWriteNowLocked(now)) {
20298            mHandler.post(new Runnable() {
20299                @Override public void run() {
20300                    synchronized (ActivityManagerService.this) {
20301                        mProcessStats.writeStateAsyncLocked();
20302                    }
20303                }
20304            });
20305        }
20306
20307        if (DEBUG_OOM_ADJ) {
20308            final long duration = SystemClock.uptimeMillis() - now;
20309            if (false) {
20310                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20311                        new RuntimeException("here").fillInStackTrace());
20312            } else {
20313                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20314            }
20315        }
20316    }
20317
20318    final void idleUids() {
20319        synchronized (this) {
20320            final long nowElapsed = SystemClock.elapsedRealtime();
20321            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20322            long nextTime = 0;
20323            for (int i=mActiveUids.size()-1; i>=0; i--) {
20324                final UidRecord uidRec = mActiveUids.valueAt(i);
20325                final long bgTime = uidRec.lastBackgroundTime;
20326                if (bgTime > 0 && !uidRec.idle) {
20327                    if (bgTime <= maxBgTime) {
20328                        uidRec.idle = true;
20329                        doStopUidLocked(uidRec.uid, uidRec);
20330                    } else {
20331                        if (nextTime == 0 || nextTime > bgTime) {
20332                            nextTime = bgTime;
20333                        }
20334                    }
20335                }
20336            }
20337            if (nextTime > 0) {
20338                mHandler.removeMessages(IDLE_UIDS_MSG);
20339                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20340                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20341            }
20342        }
20343    }
20344
20345    final void runInBackgroundDisabled(int uid) {
20346        synchronized (this) {
20347            UidRecord uidRec = mActiveUids.get(uid);
20348            if (uidRec != null) {
20349                // This uid is actually running...  should it be considered background now?
20350                if (uidRec.idle) {
20351                    doStopUidLocked(uidRec.uid, uidRec);
20352                }
20353            } else {
20354                // This uid isn't actually running...  still send a report about it being "stopped".
20355                doStopUidLocked(uid, null);
20356            }
20357        }
20358    }
20359
20360    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20361        mServices.stopInBackgroundLocked(uid);
20362        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20363    }
20364
20365    final void trimApplications() {
20366        synchronized (this) {
20367            int i;
20368
20369            // First remove any unused application processes whose package
20370            // has been removed.
20371            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20372                final ProcessRecord app = mRemovedProcesses.get(i);
20373                if (app.activities.size() == 0
20374                        && app.curReceiver == null && app.services.size() == 0) {
20375                    Slog.i(
20376                        TAG, "Exiting empty application process "
20377                        + app.processName + " ("
20378                        + (app.thread != null ? app.thread.asBinder() : null)
20379                        + ")\n");
20380                    if (app.pid > 0 && app.pid != MY_PID) {
20381                        app.kill("empty", false);
20382                    } else {
20383                        try {
20384                            app.thread.scheduleExit();
20385                        } catch (Exception e) {
20386                            // Ignore exceptions.
20387                        }
20388                    }
20389                    cleanUpApplicationRecordLocked(app, false, true, -1);
20390                    mRemovedProcesses.remove(i);
20391
20392                    if (app.persistent) {
20393                        addAppLocked(app.info, false, null /* ABI override */);
20394                    }
20395                }
20396            }
20397
20398            // Now update the oom adj for all processes.
20399            updateOomAdjLocked();
20400        }
20401    }
20402
20403    /** This method sends the specified signal to each of the persistent apps */
20404    public void signalPersistentProcesses(int sig) throws RemoteException {
20405        if (sig != Process.SIGNAL_USR1) {
20406            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20407        }
20408
20409        synchronized (this) {
20410            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20411                    != PackageManager.PERMISSION_GRANTED) {
20412                throw new SecurityException("Requires permission "
20413                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20414            }
20415
20416            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20417                ProcessRecord r = mLruProcesses.get(i);
20418                if (r.thread != null && r.persistent) {
20419                    Process.sendSignal(r.pid, sig);
20420                }
20421            }
20422        }
20423    }
20424
20425    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20426        if (proc == null || proc == mProfileProc) {
20427            proc = mProfileProc;
20428            profileType = mProfileType;
20429            clearProfilerLocked();
20430        }
20431        if (proc == null) {
20432            return;
20433        }
20434        try {
20435            proc.thread.profilerControl(false, null, profileType);
20436        } catch (RemoteException e) {
20437            throw new IllegalStateException("Process disappeared");
20438        }
20439    }
20440
20441    private void clearProfilerLocked() {
20442        if (mProfileFd != null) {
20443            try {
20444                mProfileFd.close();
20445            } catch (IOException e) {
20446            }
20447        }
20448        mProfileApp = null;
20449        mProfileProc = null;
20450        mProfileFile = null;
20451        mProfileType = 0;
20452        mAutoStopProfiler = false;
20453        mSamplingInterval = 0;
20454    }
20455
20456    public boolean profileControl(String process, int userId, boolean start,
20457            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20458
20459        try {
20460            synchronized (this) {
20461                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20462                // its own permission.
20463                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20464                        != PackageManager.PERMISSION_GRANTED) {
20465                    throw new SecurityException("Requires permission "
20466                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20467                }
20468
20469                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20470                    throw new IllegalArgumentException("null profile info or fd");
20471                }
20472
20473                ProcessRecord proc = null;
20474                if (process != null) {
20475                    proc = findProcessLocked(process, userId, "profileControl");
20476                }
20477
20478                if (start && (proc == null || proc.thread == null)) {
20479                    throw new IllegalArgumentException("Unknown process: " + process);
20480                }
20481
20482                if (start) {
20483                    stopProfilerLocked(null, 0);
20484                    setProfileApp(proc.info, proc.processName, profilerInfo);
20485                    mProfileProc = proc;
20486                    mProfileType = profileType;
20487                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20488                    try {
20489                        fd = fd.dup();
20490                    } catch (IOException e) {
20491                        fd = null;
20492                    }
20493                    profilerInfo.profileFd = fd;
20494                    proc.thread.profilerControl(start, profilerInfo, profileType);
20495                    fd = null;
20496                    mProfileFd = null;
20497                } else {
20498                    stopProfilerLocked(proc, profileType);
20499                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20500                        try {
20501                            profilerInfo.profileFd.close();
20502                        } catch (IOException e) {
20503                        }
20504                    }
20505                }
20506
20507                return true;
20508            }
20509        } catch (RemoteException e) {
20510            throw new IllegalStateException("Process disappeared");
20511        } finally {
20512            if (profilerInfo != null && profilerInfo.profileFd != null) {
20513                try {
20514                    profilerInfo.profileFd.close();
20515                } catch (IOException e) {
20516                }
20517            }
20518        }
20519    }
20520
20521    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20522        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20523                userId, true, ALLOW_FULL_ONLY, callName, null);
20524        ProcessRecord proc = null;
20525        try {
20526            int pid = Integer.parseInt(process);
20527            synchronized (mPidsSelfLocked) {
20528                proc = mPidsSelfLocked.get(pid);
20529            }
20530        } catch (NumberFormatException e) {
20531        }
20532
20533        if (proc == null) {
20534            ArrayMap<String, SparseArray<ProcessRecord>> all
20535                    = mProcessNames.getMap();
20536            SparseArray<ProcessRecord> procs = all.get(process);
20537            if (procs != null && procs.size() > 0) {
20538                proc = procs.valueAt(0);
20539                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20540                    for (int i=1; i<procs.size(); i++) {
20541                        ProcessRecord thisProc = procs.valueAt(i);
20542                        if (thisProc.userId == userId) {
20543                            proc = thisProc;
20544                            break;
20545                        }
20546                    }
20547                }
20548            }
20549        }
20550
20551        return proc;
20552    }
20553
20554    public boolean dumpHeap(String process, int userId, boolean managed,
20555            String path, ParcelFileDescriptor fd) throws RemoteException {
20556
20557        try {
20558            synchronized (this) {
20559                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20560                // its own permission (same as profileControl).
20561                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20562                        != PackageManager.PERMISSION_GRANTED) {
20563                    throw new SecurityException("Requires permission "
20564                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20565                }
20566
20567                if (fd == null) {
20568                    throw new IllegalArgumentException("null fd");
20569                }
20570
20571                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20572                if (proc == null || proc.thread == null) {
20573                    throw new IllegalArgumentException("Unknown process: " + process);
20574                }
20575
20576                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20577                if (!isDebuggable) {
20578                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20579                        throw new SecurityException("Process not debuggable: " + proc);
20580                    }
20581                }
20582
20583                proc.thread.dumpHeap(managed, path, fd);
20584                fd = null;
20585                return true;
20586            }
20587        } catch (RemoteException e) {
20588            throw new IllegalStateException("Process disappeared");
20589        } finally {
20590            if (fd != null) {
20591                try {
20592                    fd.close();
20593                } catch (IOException e) {
20594                }
20595            }
20596        }
20597    }
20598
20599    @Override
20600    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20601            String reportPackage) {
20602        if (processName != null) {
20603            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20604                    "setDumpHeapDebugLimit()");
20605        } else {
20606            synchronized (mPidsSelfLocked) {
20607                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20608                if (proc == null) {
20609                    throw new SecurityException("No process found for calling pid "
20610                            + Binder.getCallingPid());
20611                }
20612                if (!Build.IS_DEBUGGABLE
20613                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20614                    throw new SecurityException("Not running a debuggable build");
20615                }
20616                processName = proc.processName;
20617                uid = proc.uid;
20618                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20619                    throw new SecurityException("Package " + reportPackage + " is not running in "
20620                            + proc);
20621                }
20622            }
20623        }
20624        synchronized (this) {
20625            if (maxMemSize > 0) {
20626                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20627            } else {
20628                if (uid != 0) {
20629                    mMemWatchProcesses.remove(processName, uid);
20630                } else {
20631                    mMemWatchProcesses.getMap().remove(processName);
20632                }
20633            }
20634        }
20635    }
20636
20637    @Override
20638    public void dumpHeapFinished(String path) {
20639        synchronized (this) {
20640            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20641                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20642                        + " does not match last pid " + mMemWatchDumpPid);
20643                return;
20644            }
20645            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20646                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20647                        + " does not match last path " + mMemWatchDumpFile);
20648                return;
20649            }
20650            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20651            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20652        }
20653    }
20654
20655    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20656    public void monitor() {
20657        synchronized (this) { }
20658    }
20659
20660    void onCoreSettingsChange(Bundle settings) {
20661        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20662            ProcessRecord processRecord = mLruProcesses.get(i);
20663            try {
20664                if (processRecord.thread != null) {
20665                    processRecord.thread.setCoreSettings(settings);
20666                }
20667            } catch (RemoteException re) {
20668                /* ignore */
20669            }
20670        }
20671    }
20672
20673    // Multi-user methods
20674
20675    /**
20676     * Start user, if its not already running, but don't bring it to foreground.
20677     */
20678    @Override
20679    public boolean startUserInBackground(final int userId) {
20680        return mUserController.startUser(userId, /* foreground */ false);
20681    }
20682
20683    @Override
20684    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20685        return mUserController.unlockUser(userId, token, secret, listener);
20686    }
20687
20688    @Override
20689    public boolean switchUser(final int targetUserId) {
20690        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20691        UserInfo currentUserInfo;
20692        UserInfo targetUserInfo;
20693        synchronized (this) {
20694            int currentUserId = mUserController.getCurrentUserIdLocked();
20695            currentUserInfo = mUserController.getUserInfo(currentUserId);
20696            targetUserInfo = mUserController.getUserInfo(targetUserId);
20697            if (targetUserInfo == null) {
20698                Slog.w(TAG, "No user info for user #" + targetUserId);
20699                return false;
20700            }
20701            if (!targetUserInfo.supportsSwitchTo()) {
20702                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20703                return false;
20704            }
20705            if (targetUserInfo.isManagedProfile()) {
20706                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20707                return false;
20708            }
20709            mUserController.setTargetUserIdLocked(targetUserId);
20710        }
20711        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20712        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20713        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20714        return true;
20715    }
20716
20717    void scheduleStartProfilesLocked() {
20718        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20719            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20720                    DateUtils.SECOND_IN_MILLIS);
20721        }
20722    }
20723
20724    @Override
20725    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20726        return mUserController.stopUser(userId, force, callback);
20727    }
20728
20729    @Override
20730    public UserInfo getCurrentUser() {
20731        return mUserController.getCurrentUser();
20732    }
20733
20734    @Override
20735    public boolean isUserRunning(int userId, int flags) {
20736        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20737                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20738            String msg = "Permission Denial: isUserRunning() from pid="
20739                    + Binder.getCallingPid()
20740                    + ", uid=" + Binder.getCallingUid()
20741                    + " requires " + INTERACT_ACROSS_USERS;
20742            Slog.w(TAG, msg);
20743            throw new SecurityException(msg);
20744        }
20745        synchronized (this) {
20746            return mUserController.isUserRunningLocked(userId, flags);
20747        }
20748    }
20749
20750    @Override
20751    public int[] getRunningUserIds() {
20752        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20753                != PackageManager.PERMISSION_GRANTED) {
20754            String msg = "Permission Denial: isUserRunning() from pid="
20755                    + Binder.getCallingPid()
20756                    + ", uid=" + Binder.getCallingUid()
20757                    + " requires " + INTERACT_ACROSS_USERS;
20758            Slog.w(TAG, msg);
20759            throw new SecurityException(msg);
20760        }
20761        synchronized (this) {
20762            return mUserController.getStartedUserArrayLocked();
20763        }
20764    }
20765
20766    @Override
20767    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20768        mUserController.registerUserSwitchObserver(observer);
20769    }
20770
20771    @Override
20772    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20773        mUserController.unregisterUserSwitchObserver(observer);
20774    }
20775
20776    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20777        if (info == null) return null;
20778        ApplicationInfo newInfo = new ApplicationInfo(info);
20779        newInfo.initForUser(userId);
20780        return newInfo;
20781    }
20782
20783    public boolean isUserStopped(int userId) {
20784        synchronized (this) {
20785            return mUserController.getStartedUserStateLocked(userId) == null;
20786        }
20787    }
20788
20789    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20790        if (aInfo == null
20791                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20792            return aInfo;
20793        }
20794
20795        ActivityInfo info = new ActivityInfo(aInfo);
20796        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20797        return info;
20798    }
20799
20800    private boolean processSanityChecksLocked(ProcessRecord process) {
20801        if (process == null || process.thread == null) {
20802            return false;
20803        }
20804
20805        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20806        if (!isDebuggable) {
20807            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20808                return false;
20809            }
20810        }
20811
20812        return true;
20813    }
20814
20815    public boolean startBinderTracking() throws RemoteException {
20816        synchronized (this) {
20817            mBinderTransactionTrackingEnabled = true;
20818            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20819            // permission (same as profileControl).
20820            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20821                    != PackageManager.PERMISSION_GRANTED) {
20822                throw new SecurityException("Requires permission "
20823                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20824            }
20825
20826            for (int i = 0; i < mLruProcesses.size(); i++) {
20827                ProcessRecord process = mLruProcesses.get(i);
20828                if (!processSanityChecksLocked(process)) {
20829                    continue;
20830                }
20831                try {
20832                    process.thread.startBinderTracking();
20833                } catch (RemoteException e) {
20834                    Log.v(TAG, "Process disappared");
20835                }
20836            }
20837            return true;
20838        }
20839    }
20840
20841    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20842        try {
20843            synchronized (this) {
20844                mBinderTransactionTrackingEnabled = false;
20845                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20846                // permission (same as profileControl).
20847                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20848                        != PackageManager.PERMISSION_GRANTED) {
20849                    throw new SecurityException("Requires permission "
20850                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20851                }
20852
20853                if (fd == null) {
20854                    throw new IllegalArgumentException("null fd");
20855                }
20856
20857                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20858                pw.println("Binder transaction traces for all processes.\n");
20859                for (ProcessRecord process : mLruProcesses) {
20860                    if (!processSanityChecksLocked(process)) {
20861                        continue;
20862                    }
20863
20864                    pw.println("Traces for process: " + process.processName);
20865                    pw.flush();
20866                    try {
20867                        TransferPipe tp = new TransferPipe();
20868                        try {
20869                            process.thread.stopBinderTrackingAndDump(
20870                                    tp.getWriteFd().getFileDescriptor());
20871                            tp.go(fd.getFileDescriptor());
20872                        } finally {
20873                            tp.kill();
20874                        }
20875                    } catch (IOException e) {
20876                        pw.println("Failure while dumping IPC traces from " + process +
20877                                ".  Exception: " + e);
20878                        pw.flush();
20879                    } catch (RemoteException e) {
20880                        pw.println("Got a RemoteException while dumping IPC traces from " +
20881                                process + ".  Exception: " + e);
20882                        pw.flush();
20883                    }
20884                }
20885                fd = null;
20886                return true;
20887            }
20888        } finally {
20889            if (fd != null) {
20890                try {
20891                    fd.close();
20892                } catch (IOException e) {
20893                }
20894            }
20895        }
20896    }
20897
20898    private final class LocalService extends ActivityManagerInternal {
20899        @Override
20900        public void onWakefulnessChanged(int wakefulness) {
20901            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20902        }
20903
20904        @Override
20905        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20906                String processName, String abiOverride, int uid, Runnable crashHandler) {
20907            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20908                    processName, abiOverride, uid, crashHandler);
20909        }
20910
20911        @Override
20912        public SleepToken acquireSleepToken(String tag) {
20913            Preconditions.checkNotNull(tag);
20914
20915            synchronized (ActivityManagerService.this) {
20916                SleepTokenImpl token = new SleepTokenImpl(tag);
20917                mSleepTokens.add(token);
20918                updateSleepIfNeededLocked();
20919                applyVrModeIfNeededLocked(mFocusedActivity, false);
20920                return token;
20921            }
20922        }
20923
20924        @Override
20925        public ComponentName getHomeActivityForUser(int userId) {
20926            synchronized (ActivityManagerService.this) {
20927                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20928                return homeActivity == null ? null : homeActivity.realActivity;
20929            }
20930        }
20931
20932        @Override
20933        public void onUserRemoved(int userId) {
20934            synchronized (ActivityManagerService.this) {
20935                ActivityManagerService.this.onUserStoppedLocked(userId);
20936            }
20937        }
20938
20939        @Override
20940        public void onLocalVoiceInteractionStarted(IBinder activity,
20941                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20942            synchronized (ActivityManagerService.this) {
20943                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20944                        voiceSession, voiceInteractor);
20945            }
20946        }
20947
20948        @Override
20949        public void notifyStartingWindowDrawn() {
20950            synchronized (ActivityManagerService.this) {
20951                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20952            }
20953        }
20954
20955        @Override
20956        public void notifyAppTransitionStarting(int reason) {
20957            synchronized (ActivityManagerService.this) {
20958                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20959            }
20960        }
20961
20962        @Override
20963        public void notifyAppTransitionFinished() {
20964            synchronized (ActivityManagerService.this) {
20965                mStackSupervisor.notifyAppTransitionDone();
20966            }
20967        }
20968
20969        @Override
20970        public void notifyAppTransitionCancelled() {
20971            synchronized (ActivityManagerService.this) {
20972                mStackSupervisor.notifyAppTransitionDone();
20973            }
20974        }
20975
20976        @Override
20977        public List<IBinder> getTopVisibleActivities() {
20978            synchronized (ActivityManagerService.this) {
20979                return mStackSupervisor.getTopVisibleActivities();
20980            }
20981        }
20982
20983        @Override
20984        public void notifyDockedStackMinimizedChanged(boolean minimized) {
20985            synchronized (ActivityManagerService.this) {
20986                mStackSupervisor.setDockedStackMinimized(minimized);
20987            }
20988        }
20989
20990        @Override
20991        public void killForegroundAppsForUser(int userHandle) {
20992            synchronized (ActivityManagerService.this) {
20993                final ArrayList<ProcessRecord> procs = new ArrayList<>();
20994                final int NP = mProcessNames.getMap().size();
20995                for (int ip = 0; ip < NP; ip++) {
20996                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
20997                    final int NA = apps.size();
20998                    for (int ia = 0; ia < NA; ia++) {
20999                        final ProcessRecord app = apps.valueAt(ia);
21000                        if (app.persistent) {
21001                            // We don't kill persistent processes.
21002                            continue;
21003                        }
21004                        if (app.removed) {
21005                            procs.add(app);
21006                        } else if (app.userId == userHandle && app.foregroundActivities) {
21007                            app.removed = true;
21008                            procs.add(app);
21009                        }
21010                    }
21011                }
21012
21013                final int N = procs.size();
21014                for (int i = 0; i < N; i++) {
21015                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21016                }
21017            }
21018        }
21019    }
21020
21021    private final class SleepTokenImpl extends SleepToken {
21022        private final String mTag;
21023        private final long mAcquireTime;
21024
21025        public SleepTokenImpl(String tag) {
21026            mTag = tag;
21027            mAcquireTime = SystemClock.uptimeMillis();
21028        }
21029
21030        @Override
21031        public void release() {
21032            synchronized (ActivityManagerService.this) {
21033                if (mSleepTokens.remove(this)) {
21034                    updateSleepIfNeededLocked();
21035                }
21036            }
21037        }
21038
21039        @Override
21040        public String toString() {
21041            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21042        }
21043    }
21044
21045    /**
21046     * An implementation of IAppTask, that allows an app to manage its own tasks via
21047     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21048     * only the process that calls getAppTasks() can call the AppTask methods.
21049     */
21050    class AppTaskImpl extends IAppTask.Stub {
21051        private int mTaskId;
21052        private int mCallingUid;
21053
21054        public AppTaskImpl(int taskId, int callingUid) {
21055            mTaskId = taskId;
21056            mCallingUid = callingUid;
21057        }
21058
21059        private void checkCaller() {
21060            if (mCallingUid != Binder.getCallingUid()) {
21061                throw new SecurityException("Caller " + mCallingUid
21062                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21063            }
21064        }
21065
21066        @Override
21067        public void finishAndRemoveTask() {
21068            checkCaller();
21069
21070            synchronized (ActivityManagerService.this) {
21071                long origId = Binder.clearCallingIdentity();
21072                try {
21073                    // We remove the task from recents to preserve backwards
21074                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21075                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21076                    }
21077                } finally {
21078                    Binder.restoreCallingIdentity(origId);
21079                }
21080            }
21081        }
21082
21083        @Override
21084        public ActivityManager.RecentTaskInfo getTaskInfo() {
21085            checkCaller();
21086
21087            synchronized (ActivityManagerService.this) {
21088                long origId = Binder.clearCallingIdentity();
21089                try {
21090                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21091                    if (tr == null) {
21092                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21093                    }
21094                    return createRecentTaskInfoFromTaskRecord(tr);
21095                } finally {
21096                    Binder.restoreCallingIdentity(origId);
21097                }
21098            }
21099        }
21100
21101        @Override
21102        public void moveToFront() {
21103            checkCaller();
21104            // Will bring task to front if it already has a root activity.
21105            final long origId = Binder.clearCallingIdentity();
21106            try {
21107                synchronized (this) {
21108                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21109                }
21110            } finally {
21111                Binder.restoreCallingIdentity(origId);
21112            }
21113        }
21114
21115        @Override
21116        public int startActivity(IBinder whoThread, String callingPackage,
21117                Intent intent, String resolvedType, Bundle bOptions) {
21118            checkCaller();
21119
21120            int callingUser = UserHandle.getCallingUserId();
21121            TaskRecord tr;
21122            IApplicationThread appThread;
21123            synchronized (ActivityManagerService.this) {
21124                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21125                if (tr == null) {
21126                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21127                }
21128                appThread = ApplicationThreadNative.asInterface(whoThread);
21129                if (appThread == null) {
21130                    throw new IllegalArgumentException("Bad app thread " + appThread);
21131                }
21132            }
21133            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21134                    resolvedType, null, null, null, null, 0, 0, null, null,
21135                    null, bOptions, false, callingUser, null, tr);
21136        }
21137
21138        @Override
21139        public void setExcludeFromRecents(boolean exclude) {
21140            checkCaller();
21141
21142            synchronized (ActivityManagerService.this) {
21143                long origId = Binder.clearCallingIdentity();
21144                try {
21145                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21146                    if (tr == null) {
21147                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21148                    }
21149                    Intent intent = tr.getBaseIntent();
21150                    if (exclude) {
21151                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21152                    } else {
21153                        intent.setFlags(intent.getFlags()
21154                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21155                    }
21156                } finally {
21157                    Binder.restoreCallingIdentity(origId);
21158                }
21159            }
21160        }
21161    }
21162
21163    /**
21164     * Kill processes for the user with id userId and that depend on the package named packageName
21165     */
21166    @Override
21167    public void killPackageDependents(String packageName, int userId) {
21168        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21169        if (packageName == null) {
21170            throw new NullPointerException(
21171                    "Cannot kill the dependents of a package without its name.");
21172        }
21173
21174        long callingId = Binder.clearCallingIdentity();
21175        IPackageManager pm = AppGlobals.getPackageManager();
21176        int pkgUid = -1;
21177        try {
21178            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21179        } catch (RemoteException e) {
21180        }
21181        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21182            throw new IllegalArgumentException(
21183                    "Cannot kill dependents of non-existing package " + packageName);
21184        }
21185        try {
21186            synchronized(this) {
21187                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21188                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21189                        "dep: " + packageName);
21190            }
21191        } finally {
21192            Binder.restoreCallingIdentity(callingId);
21193        }
21194    }
21195}
21196