ActivityManagerService.java revision ed69570795b25835687986cd5c48df4baedd8723
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.ActivityRecord.RECENTS_ACTIVITY_TYPE;
345import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
346import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
347import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
348import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
349import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
350import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
351import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
360import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
361import static org.xmlpull.v1.XmlPullParser.START_TAG;
362
363public final class ActivityManagerService extends ActivityManagerNative
364        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
365
366    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
367    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
368    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
369    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
370    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
371    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
372    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
373    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
374    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
375    private static final String TAG_LRU = TAG + POSTFIX_LRU;
376    private static final String TAG_MU = TAG + POSTFIX_MU;
377    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
378    private static final String TAG_POWER = TAG + POSTFIX_POWER;
379    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
380    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
381    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
382    private static final String TAG_PSS = TAG + POSTFIX_PSS;
383    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
384    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
385    private static final String TAG_STACK = TAG + POSTFIX_STACK;
386    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
387    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
388    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
389    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
390    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
391
392    /** Control over CPU and battery monitoring */
393    // write battery stats every 30 minutes.
394    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
395    static final boolean MONITOR_CPU_USAGE = true;
396    // don't sample cpu less than every 5 seconds.
397    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
398    // wait possibly forever for next cpu sample.
399    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
400    static final boolean MONITOR_THREAD_CPU_USAGE = false;
401
402    // The flags that are set for all calls we make to the package manager.
403    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
404
405    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
406
407    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
408
409    // Amount of time after a call to stopAppSwitches() during which we will
410    // prevent further untrusted switches from happening.
411    static final long APP_SWITCH_DELAY_TIME = 5*1000;
412
413    // How long we wait for a launched process to attach to the activity manager
414    // before we decide it's never going to come up for real.
415    static final int PROC_START_TIMEOUT = 10*1000;
416    // How long we wait for an attached process to publish its content providers
417    // before we decide it must be hung.
418    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
419
420    // How long we will retain processes hosting content providers in the "last activity"
421    // state before allowing them to drop down to the regular cached LRU list.  This is
422    // to avoid thrashing of provider processes under low memory situations.
423    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
424
425    // How long we wait for a launched process to attach to the activity manager
426    // before we decide it's never going to come up for real, when the process was
427    // started with a wrapper for instrumentation (such as Valgrind) because it
428    // could take much longer than usual.
429    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
430
431    // How long to wait after going idle before forcing apps to GC.
432    static final int GC_TIMEOUT = 5*1000;
433
434    // The minimum amount of time between successive GC requests for a process.
435    static final int GC_MIN_INTERVAL = 60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process.
438    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
439
440    // The minimum amount of time between successive PSS requests for a process
441    // when the request is due to the memory state being lowered.
442    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
443
444    // The rate at which we check for apps using excessive power -- 15 mins.
445    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
446
447    // The minimum sample duration we will allow before deciding we have
448    // enough data on wake locks to start killing things.
449    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
450
451    // The minimum sample duration we will allow before deciding we have
452    // enough data on CPU usage to start killing things.
453    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455    // How long we allow a receiver to run before giving up on it.
456    static final int BROADCAST_FG_TIMEOUT = 10*1000;
457    static final int BROADCAST_BG_TIMEOUT = 60*1000;
458
459    // How long we wait until we timeout on key dispatching.
460    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
461
462    // How long we wait until we timeout on key dispatching during instrumentation.
463    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
464
465    // This is the amount of time an app needs to be running a foreground service before
466    // we will consider it to be doing interaction for usage stats.
467    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
468
469    // Maximum amount of time we will allow to elapse before re-reporting usage stats
470    // interaction with foreground processes.
471    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
472
473    // This is the amount of time we allow an app to settle after it goes into the background,
474    // before we start restricting what it can do.
475    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
476
477    // How long to wait in getAssistContextExtras for the activity and foreground services
478    // to respond with the result.
479    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
480
481    // How long top wait when going through the modern assist (which doesn't need to block
482    // on getting this result before starting to launch its UI).
483    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
484
485    // Maximum number of persisted Uri grants a package is allowed
486    static final int MAX_PERSISTED_URI_GRANTS = 128;
487
488    static final int MY_PID = Process.myPid();
489
490    static final String[] EMPTY_STRING_ARRAY = new String[0];
491
492    // How many bytes to write into the dropbox log before truncating
493    static final int DROPBOX_MAX_SIZE = 256 * 1024;
494
495    // Access modes for handleIncomingUser.
496    static final int ALLOW_NON_FULL = 0;
497    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
498    static final int ALLOW_FULL_ONLY = 2;
499
500    // Delay in notifying task stack change listeners (in millis)
501    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
502
503    // Necessary ApplicationInfo flags to mark an app as persistent
504    private static final int PERSISTENT_MASK =
505            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
506
507    // Intent sent when remote bugreport collection has been completed
508    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
509            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
510
511    // Delay to disable app launch boost
512    static final int APP_BOOST_MESSAGE_DELAY = 3000;
513    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
514    static final int APP_BOOST_TIMEOUT = 2500;
515
516    // Used to indicate that a task is removed it should also be removed from recents.
517    private static final boolean REMOVE_FROM_RECENTS = true;
518    // Used to indicate that an app transition should be animated.
519    static final boolean ANIMATE = true;
520
521    // Determines whether to take full screen screenshots
522    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
523    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
524
525    private static native int nativeMigrateToBoost();
526    private static native int nativeMigrateFromBoost();
527    private boolean mIsBoosted = false;
528    private long mBoostStartTime = 0;
529
530    /** All system services */
531    SystemServiceManager mSystemServiceManager;
532
533    private Installer mInstaller;
534
535    /** Run all ActivityStacks through this */
536    final ActivityStackSupervisor mStackSupervisor;
537
538    final ActivityStarter mActivityStarter;
539
540    /** Task stack change listeners. */
541    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
542            new RemoteCallbackList<ITaskStackListener>();
543
544    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
545
546    public IntentFirewall mIntentFirewall;
547
548    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
549    // default actuion automatically.  Important for devices without direct input
550    // devices.
551    private boolean mShowDialogs = true;
552    private boolean mInVrMode = false;
553
554    BroadcastQueue mFgBroadcastQueue;
555    BroadcastQueue mBgBroadcastQueue;
556    // Convenient for easy iteration over the queues. Foreground is first
557    // so that dispatch of foreground broadcasts gets precedence.
558    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
559
560    BroadcastQueue broadcastQueueForIntent(Intent intent) {
561        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
562        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
563                "Broadcast intent " + intent + " on "
564                + (isFg ? "foreground" : "background") + " queue");
565        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
566    }
567
568    /**
569     * Activity we have told the window manager to have key focus.
570     */
571    ActivityRecord mFocusedActivity = null;
572
573    /**
574     * User id of the last activity mFocusedActivity was set to.
575     */
576    private int mLastFocusedUserId;
577
578    /**
579     * If non-null, we are tracking the time the user spends in the currently focused app.
580     */
581    private AppTimeTracker mCurAppTimeTracker;
582
583    /**
584     * List of intents that were used to start the most recent tasks.
585     */
586    final RecentTasks mRecentTasks;
587
588    /**
589     * For addAppTask: cached of the last activity component that was added.
590     */
591    ComponentName mLastAddedTaskComponent;
592
593    /**
594     * For addAppTask: cached of the last activity uid that was added.
595     */
596    int mLastAddedTaskUid;
597
598    /**
599     * For addAppTask: cached of the last ActivityInfo that was added.
600     */
601    ActivityInfo mLastAddedTaskActivity;
602
603    /**
604     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
605     */
606    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
607
608    /**
609     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
610     */
611    String mDeviceOwnerName;
612
613    final UserController mUserController;
614
615    final AppErrors mAppErrors;
616
617    boolean mDoingSetFocusedActivity;
618
619    public boolean canShowErrorDialogs() {
620        return mShowDialogs && !mSleeping && !mShuttingDown;
621    }
622
623    public class PendingAssistExtras extends Binder implements Runnable {
624        public final ActivityRecord activity;
625        public final Bundle extras;
626        public final Intent intent;
627        public final String hint;
628        public final IResultReceiver receiver;
629        public final int userHandle;
630        public boolean haveResult = false;
631        public Bundle result = null;
632        public AssistStructure structure = null;
633        public AssistContent content = null;
634        public Bundle receiverExtras;
635
636        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
637                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
638            activity = _activity;
639            extras = _extras;
640            intent = _intent;
641            hint = _hint;
642            receiver = _receiver;
643            receiverExtras = _receiverExtras;
644            userHandle = _userHandle;
645        }
646        @Override
647        public void run() {
648            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
649            synchronized (this) {
650                haveResult = true;
651                notifyAll();
652            }
653            pendingAssistExtrasTimedOut(this);
654        }
655    }
656
657    final ArrayList<PendingAssistExtras> mPendingAssistExtras
658            = new ArrayList<PendingAssistExtras>();
659
660    /**
661     * Process management.
662     */
663    final ProcessList mProcessList = new ProcessList();
664
665    /**
666     * All of the applications we currently have running organized by name.
667     * The keys are strings of the application package name (as
668     * returned by the package manager), and the keys are ApplicationRecord
669     * objects.
670     */
671    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
672
673    /**
674     * Tracking long-term execution of processes to look for abuse and other
675     * bad app behavior.
676     */
677    final ProcessStatsService mProcessStats;
678
679    /**
680     * The currently running isolated processes.
681     */
682    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
683
684    /**
685     * Counter for assigning isolated process uids, to avoid frequently reusing the
686     * same ones.
687     */
688    int mNextIsolatedProcessUid = 0;
689
690    /**
691     * The currently running heavy-weight process, if any.
692     */
693    ProcessRecord mHeavyWeightProcess = null;
694
695    /**
696     * All of the processes we currently have running organized by pid.
697     * The keys are the pid running the application.
698     *
699     * <p>NOTE: This object is protected by its own lock, NOT the global
700     * activity manager lock!
701     */
702    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
703
704    /**
705     * All of the processes that have been forced to be foreground.  The key
706     * is the pid of the caller who requested it (we hold a death
707     * link on it).
708     */
709    abstract class ForegroundToken implements IBinder.DeathRecipient {
710        int pid;
711        IBinder token;
712    }
713    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
714
715    /**
716     * List of records for processes that someone had tried to start before the
717     * system was ready.  We don't start them at that point, but ensure they
718     * are started by the time booting is complete.
719     */
720    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
721
722    /**
723     * List of persistent applications that are in the process
724     * of being started.
725     */
726    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * Processes that are being forcibly torn down.
730     */
731    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * List of running applications, sorted by recent usage.
735     * The first entry in the list is the least recently used.
736     */
737    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * Where in mLruProcesses that the processes hosting activities start.
741     */
742    int mLruProcessActivityStart = 0;
743
744    /**
745     * Where in mLruProcesses that the processes hosting services start.
746     * This is after (lower index) than mLruProcessesActivityStart.
747     */
748    int mLruProcessServiceStart = 0;
749
750    /**
751     * List of processes that should gc as soon as things are idle.
752     */
753    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
754
755    /**
756     * Processes we want to collect PSS data from.
757     */
758    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
759
760    private boolean mBinderTransactionTrackingEnabled = false;
761
762    /**
763     * Last time we requested PSS data of all processes.
764     */
765    long mLastFullPssTime = SystemClock.uptimeMillis();
766
767    /**
768     * If set, the next time we collect PSS data we should do a full collection
769     * with data from native processes and the kernel.
770     */
771    boolean mFullPssPending = false;
772
773    /**
774     * This is the process holding what we currently consider to be
775     * the "home" activity.
776     */
777    ProcessRecord mHomeProcess;
778
779    /**
780     * This is the process holding the activity the user last visited that
781     * is in a different process from the one they are currently in.
782     */
783    ProcessRecord mPreviousProcess;
784
785    /**
786     * The time at which the previous process was last visible.
787     */
788    long mPreviousProcessVisibleTime;
789
790    /**
791     * Track all uids that have actively running processes.
792     */
793    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
794
795    /**
796     * This is for verifying the UID report flow.
797     */
798    static final boolean VALIDATE_UID_STATES = true;
799    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
800
801    /**
802     * Packages that the user has asked to have run in screen size
803     * compatibility mode instead of filling the screen.
804     */
805    final CompatModePackages mCompatModePackages;
806
807    /**
808     * Set of IntentSenderRecord objects that are currently active.
809     */
810    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
811            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
812
813    /**
814     * Fingerprints (hashCode()) of stack traces that we've
815     * already logged DropBox entries for.  Guarded by itself.  If
816     * something (rogue user app) forces this over
817     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
818     */
819    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
820    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
821
822    /**
823     * Strict Mode background batched logging state.
824     *
825     * The string buffer is guarded by itself, and its lock is also
826     * used to determine if another batched write is already
827     * in-flight.
828     */
829    private final StringBuilder mStrictModeBuffer = new StringBuilder();
830
831    /**
832     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
833     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
834     */
835    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
836
837    /**
838     * Resolver for broadcast intents to registered receivers.
839     * Holds BroadcastFilter (subclass of IntentFilter).
840     */
841    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
842            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
843        @Override
844        protected boolean allowFilterResult(
845                BroadcastFilter filter, List<BroadcastFilter> dest) {
846            IBinder target = filter.receiverList.receiver.asBinder();
847            for (int i = dest.size() - 1; i >= 0; i--) {
848                if (dest.get(i).receiverList.receiver.asBinder() == target) {
849                    return false;
850                }
851            }
852            return true;
853        }
854
855        @Override
856        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
857            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
858                    || userId == filter.owningUserId) {
859                return super.newResult(filter, match, userId);
860            }
861            return null;
862        }
863
864        @Override
865        protected BroadcastFilter[] newArray(int size) {
866            return new BroadcastFilter[size];
867        }
868
869        @Override
870        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
871            return packageName.equals(filter.packageName);
872        }
873    };
874
875    /**
876     * State of all active sticky broadcasts per user.  Keys are the action of the
877     * sticky Intent, values are an ArrayList of all broadcasted intents with
878     * that action (which should usually be one).  The SparseArray is keyed
879     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
880     * for stickies that are sent to all users.
881     */
882    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
883            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
884
885    final ActiveServices mServices;
886
887    final static class Association {
888        final int mSourceUid;
889        final String mSourceProcess;
890        final int mTargetUid;
891        final ComponentName mTargetComponent;
892        final String mTargetProcess;
893
894        int mCount;
895        long mTime;
896
897        int mNesting;
898        long mStartTime;
899
900        // states of the source process when the bind occurred.
901        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
902        long mLastStateUptime;
903        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
904                - ActivityManager.MIN_PROCESS_STATE+1];
905
906        Association(int sourceUid, String sourceProcess, int targetUid,
907                ComponentName targetComponent, String targetProcess) {
908            mSourceUid = sourceUid;
909            mSourceProcess = sourceProcess;
910            mTargetUid = targetUid;
911            mTargetComponent = targetComponent;
912            mTargetProcess = targetProcess;
913        }
914    }
915
916    /**
917     * When service association tracking is enabled, this is all of the associations we
918     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
919     * -> association data.
920     */
921    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
922            mAssociations = new SparseArray<>();
923    boolean mTrackingAssociations;
924
925    /**
926     * Backup/restore process management
927     */
928    String mBackupAppName = null;
929    BackupRecord mBackupTarget = null;
930
931    final ProviderMap mProviderMap;
932
933    /**
934     * List of content providers who have clients waiting for them.  The
935     * application is currently being launched and the provider will be
936     * removed from this list once it is published.
937     */
938    final ArrayList<ContentProviderRecord> mLaunchingProviders
939            = new ArrayList<ContentProviderRecord>();
940
941    /**
942     * File storing persisted {@link #mGrantedUriPermissions}.
943     */
944    private final AtomicFile mGrantFile;
945
946    /** XML constants used in {@link #mGrantFile} */
947    private static final String TAG_URI_GRANTS = "uri-grants";
948    private static final String TAG_URI_GRANT = "uri-grant";
949    private static final String ATTR_USER_HANDLE = "userHandle";
950    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
951    private static final String ATTR_TARGET_USER_ID = "targetUserId";
952    private static final String ATTR_SOURCE_PKG = "sourcePkg";
953    private static final String ATTR_TARGET_PKG = "targetPkg";
954    private static final String ATTR_URI = "uri";
955    private static final String ATTR_MODE_FLAGS = "modeFlags";
956    private static final String ATTR_CREATED_TIME = "createdTime";
957    private static final String ATTR_PREFIX = "prefix";
958
959    /**
960     * Global set of specific {@link Uri} permissions that have been granted.
961     * This optimized lookup structure maps from {@link UriPermission#targetUid}
962     * to {@link UriPermission#uri} to {@link UriPermission}.
963     */
964    @GuardedBy("this")
965    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
966            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
967
968    public static class GrantUri {
969        public final int sourceUserId;
970        public final Uri uri;
971        public boolean prefix;
972
973        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
974            this.sourceUserId = sourceUserId;
975            this.uri = uri;
976            this.prefix = prefix;
977        }
978
979        @Override
980        public int hashCode() {
981            int hashCode = 1;
982            hashCode = 31 * hashCode + sourceUserId;
983            hashCode = 31 * hashCode + uri.hashCode();
984            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
985            return hashCode;
986        }
987
988        @Override
989        public boolean equals(Object o) {
990            if (o instanceof GrantUri) {
991                GrantUri other = (GrantUri) o;
992                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
993                        && prefix == other.prefix;
994            }
995            return false;
996        }
997
998        @Override
999        public String toString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public String toSafeString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1012            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1013                    ContentProvider.getUriWithoutUserId(uri), false);
1014        }
1015    }
1016
1017    CoreSettingsObserver mCoreSettingsObserver;
1018
1019    FontScaleSettingObserver mFontScaleSettingObserver;
1020
1021    private final class FontScaleSettingObserver extends ContentObserver {
1022        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1023
1024        public FontScaleSettingObserver() {
1025            super(mHandler);
1026            ContentResolver resolver = mContext.getContentResolver();
1027            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1028        }
1029
1030        @Override
1031        public void onChange(boolean selfChange, Uri uri) {
1032            if (mFontScaleUri.equals(uri)) {
1033                updateFontScaleIfNeeded();
1034            }
1035        }
1036    }
1037
1038    /**
1039     * Thread-local storage used to carry caller permissions over through
1040     * indirect content-provider access.
1041     */
1042    private class Identity {
1043        public final IBinder token;
1044        public final int pid;
1045        public final int uid;
1046
1047        Identity(IBinder _token, int _pid, int _uid) {
1048            token = _token;
1049            pid = _pid;
1050            uid = _uid;
1051        }
1052    }
1053
1054    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1055
1056    /**
1057     * All information we have collected about the runtime performance of
1058     * any user id that can impact battery performance.
1059     */
1060    final BatteryStatsService mBatteryStatsService;
1061
1062    /**
1063     * Information about component usage
1064     */
1065    UsageStatsManagerInternal mUsageStatsService;
1066
1067    /**
1068     * Access to DeviceIdleController service.
1069     */
1070    DeviceIdleController.LocalService mLocalDeviceIdleController;
1071
1072    /**
1073     * Information about and control over application operations
1074     */
1075    final AppOpsService mAppOpsService;
1076
1077    /**
1078     * Current configuration information.  HistoryRecord objects are given
1079     * a reference to this object to indicate which configuration they are
1080     * currently running in, so this object must be kept immutable.
1081     */
1082    Configuration mConfiguration = new Configuration();
1083
1084    /**
1085     * Current sequencing integer of the configuration, for skipping old
1086     * configurations.
1087     */
1088    int mConfigurationSeq = 0;
1089
1090    boolean mSuppressResizeConfigChanges = false;
1091
1092    /**
1093     * Hardware-reported OpenGLES version.
1094     */
1095    final int GL_ES_VERSION;
1096
1097    /**
1098     * List of initialization arguments to pass to all processes when binding applications to them.
1099     * For example, references to the commonly used services.
1100     */
1101    HashMap<String, IBinder> mAppBindArgs;
1102
1103    /**
1104     * Temporary to avoid allocations.  Protected by main lock.
1105     */
1106    final StringBuilder mStringBuilder = new StringBuilder(256);
1107
1108    /**
1109     * Used to control how we initialize the service.
1110     */
1111    ComponentName mTopComponent;
1112    String mTopAction = Intent.ACTION_MAIN;
1113    String mTopData;
1114
1115    volatile boolean mProcessesReady = false;
1116    volatile boolean mSystemReady = false;
1117    volatile boolean mOnBattery = false;
1118    volatile int mFactoryTest;
1119
1120    @GuardedBy("this") boolean mBooting = false;
1121    @GuardedBy("this") boolean mCallFinishBooting = false;
1122    @GuardedBy("this") boolean mBootAnimationComplete = false;
1123    @GuardedBy("this") boolean mLaunchWarningShown = false;
1124    @GuardedBy("this") boolean mCheckedForSetup = false;
1125
1126    Context mContext;
1127
1128    /**
1129     * The time at which we will allow normal application switches again,
1130     * after a call to {@link #stopAppSwitches()}.
1131     */
1132    long mAppSwitchesAllowedTime;
1133
1134    /**
1135     * This is set to true after the first switch after mAppSwitchesAllowedTime
1136     * is set; any switches after that will clear the time.
1137     */
1138    boolean mDidAppSwitch;
1139
1140    /**
1141     * Last time (in realtime) at which we checked for power usage.
1142     */
1143    long mLastPowerCheckRealtime;
1144
1145    /**
1146     * Last time (in uptime) at which we checked for power usage.
1147     */
1148    long mLastPowerCheckUptime;
1149
1150    /**
1151     * Set while we are wanting to sleep, to prevent any
1152     * activities from being started/resumed.
1153     */
1154    private boolean mSleeping = false;
1155
1156    /**
1157     * The process state used for processes that are running the top activities.
1158     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1159     */
1160    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1161
1162    /**
1163     * Set while we are running a voice interaction.  This overrides
1164     * sleeping while it is active.
1165     */
1166    private IVoiceInteractionSession mRunningVoice;
1167
1168    /**
1169     * For some direct access we need to power manager.
1170     */
1171    PowerManagerInternal mLocalPowerManager;
1172
1173    /**
1174     * We want to hold a wake lock while running a voice interaction session, since
1175     * this may happen with the screen off and we need to keep the CPU running to
1176     * be able to continue to interact with the user.
1177     */
1178    PowerManager.WakeLock mVoiceWakeLock;
1179
1180    /**
1181     * State of external calls telling us if the device is awake or asleep.
1182     */
1183    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1184
1185    /**
1186     * A list of tokens that cause the top activity to be put to sleep.
1187     * They are used by components that may hide and block interaction with underlying
1188     * activities.
1189     */
1190    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1191
1192    static final int LOCK_SCREEN_HIDDEN = 0;
1193    static final int LOCK_SCREEN_LEAVING = 1;
1194    static final int LOCK_SCREEN_SHOWN = 2;
1195    /**
1196     * State of external call telling us if the lock screen is shown.
1197     */
1198    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1199
1200    /**
1201     * Set if we are shutting down the system, similar to sleeping.
1202     */
1203    boolean mShuttingDown = false;
1204
1205    /**
1206     * Current sequence id for oom_adj computation traversal.
1207     */
1208    int mAdjSeq = 0;
1209
1210    /**
1211     * Current sequence id for process LRU updating.
1212     */
1213    int mLruSeq = 0;
1214
1215    /**
1216     * Keep track of the non-cached/empty process we last found, to help
1217     * determine how to distribute cached/empty processes next time.
1218     */
1219    int mNumNonCachedProcs = 0;
1220
1221    /**
1222     * Keep track of the number of cached hidden procs, to balance oom adj
1223     * distribution between those and empty procs.
1224     */
1225    int mNumCachedHiddenProcs = 0;
1226
1227    /**
1228     * Keep track of the number of service processes we last found, to
1229     * determine on the next iteration which should be B services.
1230     */
1231    int mNumServiceProcs = 0;
1232    int mNewNumAServiceProcs = 0;
1233    int mNewNumServiceProcs = 0;
1234
1235    /**
1236     * Allow the current computed overall memory level of the system to go down?
1237     * This is set to false when we are killing processes for reasons other than
1238     * memory management, so that the now smaller process list will not be taken as
1239     * an indication that memory is tighter.
1240     */
1241    boolean mAllowLowerMemLevel = false;
1242
1243    /**
1244     * The last computed memory level, for holding when we are in a state that
1245     * processes are going away for other reasons.
1246     */
1247    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1248
1249    /**
1250     * The last total number of process we have, to determine if changes actually look
1251     * like a shrinking number of process due to lower RAM.
1252     */
1253    int mLastNumProcesses;
1254
1255    /**
1256     * The uptime of the last time we performed idle maintenance.
1257     */
1258    long mLastIdleTime = SystemClock.uptimeMillis();
1259
1260    /**
1261     * Total time spent with RAM that has been added in the past since the last idle time.
1262     */
1263    long mLowRamTimeSinceLastIdle = 0;
1264
1265    /**
1266     * If RAM is currently low, when that horrible situation started.
1267     */
1268    long mLowRamStartTime = 0;
1269
1270    /**
1271     * For reporting to battery stats the current top application.
1272     */
1273    private String mCurResumedPackage = null;
1274    private int mCurResumedUid = -1;
1275
1276    /**
1277     * For reporting to battery stats the apps currently running foreground
1278     * service.  The ProcessMap is package/uid tuples; each of these contain
1279     * an array of the currently foreground processes.
1280     */
1281    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1282            = new ProcessMap<ArrayList<ProcessRecord>>();
1283
1284    /**
1285     * This is set if we had to do a delayed dexopt of an app before launching
1286     * it, to increase the ANR timeouts in that case.
1287     */
1288    boolean mDidDexOpt;
1289
1290    /**
1291     * Set if the systemServer made a call to enterSafeMode.
1292     */
1293    boolean mSafeMode;
1294
1295    /**
1296     * If true, we are running under a test environment so will sample PSS from processes
1297     * much more rapidly to try to collect better data when the tests are rapidly
1298     * running through apps.
1299     */
1300    boolean mTestPssMode = false;
1301
1302    String mDebugApp = null;
1303    boolean mWaitForDebugger = false;
1304    boolean mDebugTransient = false;
1305    String mOrigDebugApp = null;
1306    boolean mOrigWaitForDebugger = false;
1307    boolean mAlwaysFinishActivities = false;
1308    boolean mLenientBackgroundCheck = false;
1309    boolean mForceResizableActivities;
1310    boolean mSupportsMultiWindow;
1311    boolean mSupportsFreeformWindowManagement;
1312    boolean mSupportsPictureInPicture;
1313    Rect mDefaultPinnedStackBounds;
1314    IActivityController mController = null;
1315    boolean mControllerIsAMonkey = false;
1316    String mProfileApp = null;
1317    ProcessRecord mProfileProc = null;
1318    String mProfileFile;
1319    ParcelFileDescriptor mProfileFd;
1320    int mSamplingInterval = 0;
1321    boolean mAutoStopProfiler = false;
1322    int mProfileType = 0;
1323    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1324    String mMemWatchDumpProcName;
1325    String mMemWatchDumpFile;
1326    int mMemWatchDumpPid;
1327    int mMemWatchDumpUid;
1328    String mTrackAllocationApp = null;
1329    String mNativeDebuggingApp = null;
1330
1331    final long[] mTmpLong = new long[2];
1332
1333    static final class ProcessChangeItem {
1334        static final int CHANGE_ACTIVITIES = 1<<0;
1335        static final int CHANGE_PROCESS_STATE = 1<<1;
1336        int changes;
1337        int uid;
1338        int pid;
1339        int processState;
1340        boolean foregroundActivities;
1341    }
1342
1343    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1344    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1345
1346    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1347    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1348
1349    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1350    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1351
1352    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1353    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1354
1355    /**
1356     * Runtime CPU use collection thread.  This object's lock is used to
1357     * perform synchronization with the thread (notifying it to run).
1358     */
1359    final Thread mProcessCpuThread;
1360
1361    /**
1362     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1363     * Must acquire this object's lock when accessing it.
1364     * NOTE: this lock will be held while doing long operations (trawling
1365     * through all processes in /proc), so it should never be acquired by
1366     * any critical paths such as when holding the main activity manager lock.
1367     */
1368    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1369            MONITOR_THREAD_CPU_USAGE);
1370    final AtomicLong mLastCpuTime = new AtomicLong(0);
1371    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1372
1373    long mLastWriteTime = 0;
1374
1375    /**
1376     * Used to retain an update lock when the foreground activity is in
1377     * immersive mode.
1378     */
1379    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1380
1381    /**
1382     * Set to true after the system has finished booting.
1383     */
1384    boolean mBooted = false;
1385
1386    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1387    int mProcessLimitOverride = -1;
1388
1389    WindowManagerService mWindowManager;
1390    final ActivityThread mSystemThread;
1391
1392    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1393        final ProcessRecord mApp;
1394        final int mPid;
1395        final IApplicationThread mAppThread;
1396
1397        AppDeathRecipient(ProcessRecord app, int pid,
1398                IApplicationThread thread) {
1399            if (DEBUG_ALL) Slog.v(
1400                TAG, "New death recipient " + this
1401                + " for thread " + thread.asBinder());
1402            mApp = app;
1403            mPid = pid;
1404            mAppThread = thread;
1405        }
1406
1407        @Override
1408        public void binderDied() {
1409            if (DEBUG_ALL) Slog.v(
1410                TAG, "Death received in " + this
1411                + " for thread " + mAppThread.asBinder());
1412            synchronized(ActivityManagerService.this) {
1413                appDiedLocked(mApp, mPid, mAppThread, true);
1414            }
1415        }
1416    }
1417
1418    static final int SHOW_ERROR_UI_MSG = 1;
1419    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1420    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1421    static final int UPDATE_CONFIGURATION_MSG = 4;
1422    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1423    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1424    static final int SERVICE_TIMEOUT_MSG = 12;
1425    static final int UPDATE_TIME_ZONE = 13;
1426    static final int SHOW_UID_ERROR_UI_MSG = 14;
1427    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1428    static final int PROC_START_TIMEOUT_MSG = 20;
1429    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1430    static final int KILL_APPLICATION_MSG = 22;
1431    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1432    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1433    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1434    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1435    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1436    static final int CLEAR_DNS_CACHE_MSG = 28;
1437    static final int UPDATE_HTTP_PROXY_MSG = 29;
1438    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1439    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1440    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1441    static final int REPORT_MEM_USAGE_MSG = 33;
1442    static final int REPORT_USER_SWITCH_MSG = 34;
1443    static final int CONTINUE_USER_SWITCH_MSG = 35;
1444    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1445    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1446    static final int PERSIST_URI_GRANTS_MSG = 38;
1447    static final int REQUEST_ALL_PSS_MSG = 39;
1448    static final int START_PROFILES_MSG = 40;
1449    static final int UPDATE_TIME = 41;
1450    static final int SYSTEM_USER_START_MSG = 42;
1451    static final int SYSTEM_USER_CURRENT_MSG = 43;
1452    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1453    static final int FINISH_BOOTING_MSG = 45;
1454    static final int START_USER_SWITCH_UI_MSG = 46;
1455    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1456    static final int DISMISS_DIALOG_UI_MSG = 48;
1457    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1458    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1459    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1460    static final int DELETE_DUMPHEAP_MSG = 52;
1461    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1462    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1463    static final int REPORT_TIME_TRACKER_MSG = 55;
1464    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1465    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1466    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1467    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1468    static final int IDLE_UIDS_MSG = 60;
1469    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1470    static final int LOG_STACK_STATE = 62;
1471    static final int VR_MODE_CHANGE_MSG = 63;
1472    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1473    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1474    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1475    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1476    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1477    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1478
1479    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1480    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1481    static final int FIRST_COMPAT_MODE_MSG = 300;
1482    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1483
1484    static ServiceThread sKillThread = null;
1485    static KillHandler sKillHandler = null;
1486
1487    CompatModeDialog mCompatModeDialog;
1488    long mLastMemUsageReportTime = 0;
1489
1490    /**
1491     * Flag whether the current user is a "monkey", i.e. whether
1492     * the UI is driven by a UI automation tool.
1493     */
1494    private boolean mUserIsMonkey;
1495
1496    /** Flag whether the device has a Recents UI */
1497    boolean mHasRecents;
1498
1499    /** The dimensions of the thumbnails in the Recents UI. */
1500    int mThumbnailWidth;
1501    int mThumbnailHeight;
1502    float mFullscreenThumbnailScale;
1503
1504    final ServiceThread mHandlerThread;
1505    final MainHandler mHandler;
1506    final UiHandler mUiHandler;
1507
1508    PackageManagerInternal mPackageManagerInt;
1509
1510    final class KillHandler extends Handler {
1511        static final int KILL_PROCESS_GROUP_MSG = 4000;
1512
1513        public KillHandler(Looper looper) {
1514            super(looper, null, true);
1515        }
1516
1517        @Override
1518        public void handleMessage(Message msg) {
1519            switch (msg.what) {
1520                case KILL_PROCESS_GROUP_MSG:
1521                {
1522                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1523                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1524                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1525                }
1526                break;
1527
1528                default:
1529                    super.handleMessage(msg);
1530            }
1531        }
1532    }
1533
1534    final class UiHandler extends Handler {
1535        public UiHandler() {
1536            super(com.android.server.UiThread.get().getLooper(), null, true);
1537        }
1538
1539        @Override
1540        public void handleMessage(Message msg) {
1541            switch (msg.what) {
1542            case SHOW_ERROR_UI_MSG: {
1543                mAppErrors.handleShowAppErrorUi(msg);
1544                ensureBootCompleted();
1545            } break;
1546            case SHOW_NOT_RESPONDING_UI_MSG: {
1547                mAppErrors.handleShowAnrUi(msg);
1548                ensureBootCompleted();
1549            } break;
1550            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1551                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1552                synchronized (ActivityManagerService.this) {
1553                    ProcessRecord proc = (ProcessRecord) data.get("app");
1554                    if (proc == null) {
1555                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1556                        break;
1557                    }
1558                    if (proc.crashDialog != null) {
1559                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1560                        return;
1561                    }
1562                    AppErrorResult res = (AppErrorResult) data.get("result");
1563                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1564                        Dialog d = new StrictModeViolationDialog(mContext,
1565                                ActivityManagerService.this, res, proc);
1566                        d.show();
1567                        proc.crashDialog = d;
1568                    } else {
1569                        // The device is asleep, so just pretend that the user
1570                        // saw a crash dialog and hit "force quit".
1571                        res.set(0);
1572                    }
1573                }
1574                ensureBootCompleted();
1575            } break;
1576            case SHOW_FACTORY_ERROR_UI_MSG: {
1577                Dialog d = new FactoryErrorDialog(
1578                    mContext, msg.getData().getCharSequence("msg"));
1579                d.show();
1580                ensureBootCompleted();
1581            } break;
1582            case WAIT_FOR_DEBUGGER_UI_MSG: {
1583                synchronized (ActivityManagerService.this) {
1584                    ProcessRecord app = (ProcessRecord)msg.obj;
1585                    if (msg.arg1 != 0) {
1586                        if (!app.waitedForDebugger) {
1587                            Dialog d = new AppWaitingForDebuggerDialog(
1588                                    ActivityManagerService.this,
1589                                    mContext, app);
1590                            app.waitDialog = d;
1591                            app.waitedForDebugger = true;
1592                            d.show();
1593                        }
1594                    } else {
1595                        if (app.waitDialog != null) {
1596                            app.waitDialog.dismiss();
1597                            app.waitDialog = null;
1598                        }
1599                    }
1600                }
1601            } break;
1602            case SHOW_UID_ERROR_UI_MSG: {
1603                if (mShowDialogs) {
1604                    AlertDialog d = new BaseErrorDialog(mContext);
1605                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1606                    d.setCancelable(false);
1607                    d.setTitle(mContext.getText(R.string.android_system_label));
1608                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1609                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1610                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1611                    d.show();
1612                }
1613            } break;
1614            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1615                if (mShowDialogs) {
1616                    AlertDialog d = new BaseErrorDialog(mContext);
1617                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1618                    d.setCancelable(false);
1619                    d.setTitle(mContext.getText(R.string.android_system_label));
1620                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1621                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1622                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1623                    d.show();
1624                }
1625            } break;
1626            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ActivityRecord ar = (ActivityRecord) msg.obj;
1629                    if (mCompatModeDialog != null) {
1630                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1631                                ar.info.applicationInfo.packageName)) {
1632                            return;
1633                        }
1634                        mCompatModeDialog.dismiss();
1635                        mCompatModeDialog = null;
1636                    }
1637                    if (ar != null && false) {
1638                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1639                                ar.packageName)) {
1640                            int mode = mCompatModePackages.computeCompatModeLocked(
1641                                    ar.info.applicationInfo);
1642                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1643                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1644                                mCompatModeDialog = new CompatModeDialog(
1645                                        ActivityManagerService.this, mContext,
1646                                        ar.info.applicationInfo);
1647                                mCompatModeDialog.show();
1648                            }
1649                        }
1650                    }
1651                }
1652                break;
1653            }
1654            case START_USER_SWITCH_UI_MSG: {
1655                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1656                break;
1657            }
1658            case DISMISS_DIALOG_UI_MSG: {
1659                final Dialog d = (Dialog) msg.obj;
1660                d.dismiss();
1661                break;
1662            }
1663            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1664                dispatchProcessesChanged();
1665                break;
1666            }
1667            case DISPATCH_PROCESS_DIED_UI_MSG: {
1668                final int pid = msg.arg1;
1669                final int uid = msg.arg2;
1670                dispatchProcessDied(pid, uid);
1671                break;
1672            }
1673            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1674                dispatchUidsChanged();
1675            } break;
1676            }
1677        }
1678    }
1679
1680    final class MainHandler extends Handler {
1681        public MainHandler(Looper looper) {
1682            super(looper, null, true);
1683        }
1684
1685        @Override
1686        public void handleMessage(Message msg) {
1687            switch (msg.what) {
1688            case UPDATE_CONFIGURATION_MSG: {
1689                final ContentResolver resolver = mContext.getContentResolver();
1690                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1691                        msg.arg1);
1692            } break;
1693            case GC_BACKGROUND_PROCESSES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    performAppGcsIfAppropriateLocked();
1696                }
1697            } break;
1698            case SERVICE_TIMEOUT_MSG: {
1699                if (mDidDexOpt) {
1700                    mDidDexOpt = false;
1701                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1702                    nmsg.obj = msg.obj;
1703                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1704                    return;
1705                }
1706                mServices.serviceTimeout((ProcessRecord)msg.obj);
1707            } break;
1708            case UPDATE_TIME_ZONE: {
1709                synchronized (ActivityManagerService.this) {
1710                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1711                        ProcessRecord r = mLruProcesses.get(i);
1712                        if (r.thread != null) {
1713                            try {
1714                                r.thread.updateTimeZone();
1715                            } catch (RemoteException ex) {
1716                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1717                            }
1718                        }
1719                    }
1720                }
1721            } break;
1722            case CLEAR_DNS_CACHE_MSG: {
1723                synchronized (ActivityManagerService.this) {
1724                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1725                        ProcessRecord r = mLruProcesses.get(i);
1726                        if (r.thread != null) {
1727                            try {
1728                                r.thread.clearDnsCache();
1729                            } catch (RemoteException ex) {
1730                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1731                            }
1732                        }
1733                    }
1734                }
1735            } break;
1736            case UPDATE_HTTP_PROXY_MSG: {
1737                ProxyInfo proxy = (ProxyInfo)msg.obj;
1738                String host = "";
1739                String port = "";
1740                String exclList = "";
1741                Uri pacFileUrl = Uri.EMPTY;
1742                if (proxy != null) {
1743                    host = proxy.getHost();
1744                    port = Integer.toString(proxy.getPort());
1745                    exclList = proxy.getExclusionListAsString();
1746                    pacFileUrl = proxy.getPacFileUrl();
1747                }
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update http proxy for: " +
1756                                        r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761            } break;
1762            case PROC_START_TIMEOUT_MSG: {
1763                if (mDidDexOpt) {
1764                    mDidDexOpt = false;
1765                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1766                    nmsg.obj = msg.obj;
1767                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1768                    return;
1769                }
1770                ProcessRecord app = (ProcessRecord)msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    processStartTimedOutLocked(app);
1773                }
1774            } break;
1775            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1776                ProcessRecord app = (ProcessRecord)msg.obj;
1777                synchronized (ActivityManagerService.this) {
1778                    processContentProviderPublishTimedOutLocked(app);
1779                }
1780            } break;
1781            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1784                }
1785            } break;
1786            case KILL_APPLICATION_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    int appid = msg.arg1;
1789                    boolean restart = (msg.arg2 == 1);
1790                    Bundle bundle = (Bundle)msg.obj;
1791                    String pkg = bundle.getString("pkg");
1792                    String reason = bundle.getString("reason");
1793                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1794                            false, UserHandle.USER_ALL, reason);
1795                }
1796            } break;
1797            case FINALIZE_PENDING_INTENT_MSG: {
1798                ((PendingIntentRecord)msg.obj).completeFinalize();
1799            } break;
1800            case POST_HEAVY_NOTIFICATION_MSG: {
1801                INotificationManager inm = NotificationManager.getService();
1802                if (inm == null) {
1803                    return;
1804                }
1805
1806                ActivityRecord root = (ActivityRecord)msg.obj;
1807                ProcessRecord process = root.app;
1808                if (process == null) {
1809                    return;
1810                }
1811
1812                try {
1813                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1814                    String text = mContext.getString(R.string.heavy_weight_notification,
1815                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1816                    Notification notification = new Notification.Builder(context)
1817                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1818                            .setWhen(0)
1819                            .setOngoing(true)
1820                            .setTicker(text)
1821                            .setColor(mContext.getColor(
1822                                    com.android.internal.R.color.system_notification_accent_color))
1823                            .setContentTitle(text)
1824                            .setContentText(
1825                                    mContext.getText(R.string.heavy_weight_notification_detail))
1826                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1827                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1828                                    new UserHandle(root.userId)))
1829                            .build();
1830                    try {
1831                        int[] outId = new int[1];
1832                        inm.enqueueNotificationWithTag("android", "android", null,
1833                                R.string.heavy_weight_notification,
1834                                notification, outId, root.userId);
1835                    } catch (RuntimeException e) {
1836                        Slog.w(ActivityManagerService.TAG,
1837                                "Error showing notification for heavy-weight app", e);
1838                    } catch (RemoteException e) {
1839                    }
1840                } catch (NameNotFoundException e) {
1841                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1842                }
1843            } break;
1844            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1845                INotificationManager inm = NotificationManager.getService();
1846                if (inm == null) {
1847                    return;
1848                }
1849                try {
1850                    inm.cancelNotificationWithTag("android", null,
1851                            R.string.heavy_weight_notification,  msg.arg1);
1852                } catch (RuntimeException e) {
1853                    Slog.w(ActivityManagerService.TAG,
1854                            "Error canceling notification for service", e);
1855                } catch (RemoteException e) {
1856                }
1857            } break;
1858            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    checkExcessivePowerUsageLocked(true);
1861                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1863                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1864                }
1865            } break;
1866            case REPORT_MEM_USAGE_MSG: {
1867                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1868                Thread thread = new Thread() {
1869                    @Override public void run() {
1870                        reportMemUsage(memInfos);
1871                    }
1872                };
1873                thread.start();
1874                break;
1875            }
1876            case REPORT_USER_SWITCH_MSG: {
1877                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1878                break;
1879            }
1880            case CONTINUE_USER_SWITCH_MSG: {
1881                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1882                break;
1883            }
1884            case USER_SWITCH_TIMEOUT_MSG: {
1885                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1886                break;
1887            }
1888            case IMMERSIVE_MODE_LOCK_MSG: {
1889                final boolean nextState = (msg.arg1 != 0);
1890                if (mUpdateLock.isHeld() != nextState) {
1891                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1892                            "Applying new update lock state '" + nextState
1893                            + "' for " + (ActivityRecord)msg.obj);
1894                    if (nextState) {
1895                        mUpdateLock.acquire();
1896                    } else {
1897                        mUpdateLock.release();
1898                    }
1899                }
1900                break;
1901            }
1902            case PERSIST_URI_GRANTS_MSG: {
1903                writeGrantedUriPermissions();
1904                break;
1905            }
1906            case REQUEST_ALL_PSS_MSG: {
1907                synchronized (ActivityManagerService.this) {
1908                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1909                }
1910                break;
1911            }
1912            case START_PROFILES_MSG: {
1913                synchronized (ActivityManagerService.this) {
1914                    mUserController.startProfilesLocked();
1915                }
1916                break;
1917            }
1918            case UPDATE_TIME: {
1919                synchronized (ActivityManagerService.this) {
1920                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1921                        ProcessRecord r = mLruProcesses.get(i);
1922                        if (r.thread != null) {
1923                            try {
1924                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1925                            } catch (RemoteException ex) {
1926                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1927                            }
1928                        }
1929                    }
1930                }
1931                break;
1932            }
1933            case SYSTEM_USER_START_MSG: {
1934                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1935                        Integer.toString(msg.arg1), msg.arg1);
1936                mSystemServiceManager.startUser(msg.arg1);
1937                break;
1938            }
1939            case SYSTEM_USER_UNLOCK_MSG: {
1940                final int userId = msg.arg1;
1941                mSystemServiceManager.unlockUser(userId);
1942                synchronized (ActivityManagerService.this) {
1943                    mRecentTasks.loadUserRecentsLocked(userId);
1944                }
1945                if (userId == UserHandle.USER_SYSTEM) {
1946                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1947                }
1948                installEncryptionUnawareProviders(userId);
1949                if (msg.obj instanceof ProgressReporter) {
1950                    ((ProgressReporter) msg.obj).finish();
1951                }
1952                break;
1953            }
1954            case SYSTEM_USER_CURRENT_MSG: {
1955                mBatteryStatsService.noteEvent(
1956                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1957                        Integer.toString(msg.arg2), msg.arg2);
1958                mBatteryStatsService.noteEvent(
1959                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1960                        Integer.toString(msg.arg1), msg.arg1);
1961                mSystemServiceManager.switchUser(msg.arg1);
1962                break;
1963            }
1964            case ENTER_ANIMATION_COMPLETE_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1967                    if (r != null && r.app != null && r.app.thread != null) {
1968                        try {
1969                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1970                        } catch (RemoteException e) {
1971                        }
1972                    }
1973                }
1974                break;
1975            }
1976            case FINISH_BOOTING_MSG: {
1977                if (msg.arg1 != 0) {
1978                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1979                    finishBooting();
1980                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1981                }
1982                if (msg.arg2 != 0) {
1983                    enableScreenAfterBoot();
1984                }
1985                break;
1986            }
1987            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1988                try {
1989                    Locale l = (Locale) msg.obj;
1990                    IBinder service = ServiceManager.getService("mount");
1991                    IMountService mountService = IMountService.Stub.asInterface(service);
1992                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1993                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1994                } catch (RemoteException e) {
1995                    Log.e(TAG, "Error storing locale for decryption UI", e);
1996                }
1997                break;
1998            }
1999            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2002                        try {
2003                            // Make a one-way callback to the listener
2004                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2005                        } catch (RemoteException e){
2006                            // Handled by the RemoteCallbackList
2007                        }
2008                    }
2009                    mTaskStackListeners.finishBroadcast();
2010                }
2011                break;
2012            }
2013            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2014                synchronized (ActivityManagerService.this) {
2015                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2016                        try {
2017                            // Make a one-way callback to the listener
2018                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2019                        } catch (RemoteException e){
2020                            // Handled by the RemoteCallbackList
2021                        }
2022                    }
2023                    mTaskStackListeners.finishBroadcast();
2024                }
2025                break;
2026            }
2027            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2028                synchronized (ActivityManagerService.this) {
2029                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2030                        try {
2031                            // Make a one-way callback to the listener
2032                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2033                        } catch (RemoteException e){
2034                            // Handled by the RemoteCallbackList
2035                        }
2036                    }
2037                    mTaskStackListeners.finishBroadcast();
2038                }
2039                break;
2040            }
2041            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2042                synchronized (ActivityManagerService.this) {
2043                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2044                        try {
2045                            // Make a one-way callback to the listener
2046                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2047                        } catch (RemoteException e){
2048                            // Handled by the RemoteCallbackList
2049                        }
2050                    }
2051                    mTaskStackListeners.finishBroadcast();
2052                }
2053                break;
2054            }
2055            case NOTIFY_FORCED_RESIZABLE_MSG: {
2056                synchronized (ActivityManagerService.this) {
2057                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2058                        try {
2059                            // Make a one-way callback to the listener
2060                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2061                                    (String) msg.obj, msg.arg1);
2062                        } catch (RemoteException e){
2063                            // Handled by the RemoteCallbackList
2064                        }
2065                    }
2066                    mTaskStackListeners.finishBroadcast();
2067                }
2068                break;
2069            }
2070                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2071                    synchronized (ActivityManagerService.this) {
2072                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2073                            try {
2074                                // Make a one-way callback to the listener
2075                                mTaskStackListeners.getBroadcastItem(i)
2076                                        .onActivityDismissingDockedStack();
2077                            } catch (RemoteException e){
2078                                // Handled by the RemoteCallbackList
2079                            }
2080                        }
2081                        mTaskStackListeners.finishBroadcast();
2082                    }
2083                    break;
2084                }
2085            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2086                final int uid = msg.arg1;
2087                final byte[] firstPacket = (byte[]) msg.obj;
2088
2089                synchronized (mPidsSelfLocked) {
2090                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2091                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2092                        if (p.uid == uid) {
2093                            try {
2094                                p.thread.notifyCleartextNetwork(firstPacket);
2095                            } catch (RemoteException ignored) {
2096                            }
2097                        }
2098                    }
2099                }
2100                break;
2101            }
2102            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2103                final String procName;
2104                final int uid;
2105                final long memLimit;
2106                final String reportPackage;
2107                synchronized (ActivityManagerService.this) {
2108                    procName = mMemWatchDumpProcName;
2109                    uid = mMemWatchDumpUid;
2110                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2111                    if (val == null) {
2112                        val = mMemWatchProcesses.get(procName, 0);
2113                    }
2114                    if (val != null) {
2115                        memLimit = val.first;
2116                        reportPackage = val.second;
2117                    } else {
2118                        memLimit = 0;
2119                        reportPackage = null;
2120                    }
2121                }
2122                if (procName == null) {
2123                    return;
2124                }
2125
2126                if (DEBUG_PSS) Slog.d(TAG_PSS,
2127                        "Showing dump heap notification from " + procName + "/" + uid);
2128
2129                INotificationManager inm = NotificationManager.getService();
2130                if (inm == null) {
2131                    return;
2132                }
2133
2134                String text = mContext.getString(R.string.dump_heap_notification, procName);
2135
2136
2137                Intent deleteIntent = new Intent();
2138                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2139                Intent intent = new Intent();
2140                intent.setClassName("android", DumpHeapActivity.class.getName());
2141                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2142                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2143                if (reportPackage != null) {
2144                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2145                }
2146                int userId = UserHandle.getUserId(uid);
2147                Notification notification = new Notification.Builder(mContext)
2148                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2149                        .setWhen(0)
2150                        .setOngoing(true)
2151                        .setAutoCancel(true)
2152                        .setTicker(text)
2153                        .setColor(mContext.getColor(
2154                                com.android.internal.R.color.system_notification_accent_color))
2155                        .setContentTitle(text)
2156                        .setContentText(
2157                                mContext.getText(R.string.dump_heap_notification_detail))
2158                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2159                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2160                                new UserHandle(userId)))
2161                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2162                                deleteIntent, 0, UserHandle.SYSTEM))
2163                        .build();
2164
2165                try {
2166                    int[] outId = new int[1];
2167                    inm.enqueueNotificationWithTag("android", "android", null,
2168                            R.string.dump_heap_notification,
2169                            notification, outId, userId);
2170                } catch (RuntimeException e) {
2171                    Slog.w(ActivityManagerService.TAG,
2172                            "Error showing notification for dump heap", e);
2173                } catch (RemoteException e) {
2174                }
2175            } break;
2176            case DELETE_DUMPHEAP_MSG: {
2177                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2178                        DumpHeapActivity.JAVA_URI,
2179                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2180                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2181                        UserHandle.myUserId());
2182                synchronized (ActivityManagerService.this) {
2183                    mMemWatchDumpFile = null;
2184                    mMemWatchDumpProcName = null;
2185                    mMemWatchDumpPid = -1;
2186                    mMemWatchDumpUid = -1;
2187                }
2188            } break;
2189            case FOREGROUND_PROFILE_CHANGED_MSG: {
2190                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2191            } break;
2192            case REPORT_TIME_TRACKER_MSG: {
2193                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2194                tracker.deliverResult(mContext);
2195            } break;
2196            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2197                mUserController.dispatchUserSwitchComplete(msg.arg1);
2198            } break;
2199            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2200                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2201                try {
2202                    connection.shutdown();
2203                } catch (RemoteException e) {
2204                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2205                }
2206                // Only a UiAutomation can set this flag and now that
2207                // it is finished we make sure it is reset to its default.
2208                mUserIsMonkey = false;
2209            } break;
2210            case APP_BOOST_DEACTIVATE_MSG: {
2211                synchronized(ActivityManagerService.this) {
2212                    if (mIsBoosted) {
2213                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2214                            nativeMigrateFromBoost();
2215                            mIsBoosted = false;
2216                            mBoostStartTime = 0;
2217                        } else {
2218                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2219                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2220                        }
2221                    }
2222                }
2223            } break;
2224            case IDLE_UIDS_MSG: {
2225                idleUids();
2226            } break;
2227            case LOG_STACK_STATE: {
2228                synchronized (ActivityManagerService.this) {
2229                    mStackSupervisor.logStackState();
2230                }
2231            } break;
2232            case VR_MODE_CHANGE_MSG: {
2233                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2234                final ActivityRecord r = (ActivityRecord) msg.obj;
2235                boolean vrMode;
2236                ComponentName requestedPackage;
2237                ComponentName callingPackage;
2238                int userId;
2239                synchronized (ActivityManagerService.this) {
2240                    vrMode = r.requestedVrComponent != null;
2241                    requestedPackage = r.requestedVrComponent;
2242                    userId = r.userId;
2243                    callingPackage = r.info.getComponentName();
2244                    if (mInVrMode != vrMode) {
2245                        mInVrMode = vrMode;
2246                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2247                    }
2248                }
2249                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2250            } break;
2251            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2252                final ActivityRecord r = (ActivityRecord) msg.obj;
2253                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2254                if (needsVrMode) {
2255                    VrManagerInternal vrService =
2256                            LocalServices.getService(VrManagerInternal.class);
2257                    boolean enable = msg.arg1 == 1;
2258                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2259                            r.info.getComponentName());
2260                }
2261            } break;
2262            }
2263        }
2264    };
2265
2266    static final int COLLECT_PSS_BG_MSG = 1;
2267
2268    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2269        @Override
2270        public void handleMessage(Message msg) {
2271            switch (msg.what) {
2272            case COLLECT_PSS_BG_MSG: {
2273                long start = SystemClock.uptimeMillis();
2274                MemInfoReader memInfo = null;
2275                synchronized (ActivityManagerService.this) {
2276                    if (mFullPssPending) {
2277                        mFullPssPending = false;
2278                        memInfo = new MemInfoReader();
2279                    }
2280                }
2281                if (memInfo != null) {
2282                    updateCpuStatsNow();
2283                    long nativeTotalPss = 0;
2284                    synchronized (mProcessCpuTracker) {
2285                        final int N = mProcessCpuTracker.countStats();
2286                        for (int j=0; j<N; j++) {
2287                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2288                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2289                                // This is definitely an application process; skip it.
2290                                continue;
2291                            }
2292                            synchronized (mPidsSelfLocked) {
2293                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2294                                    // This is one of our own processes; skip it.
2295                                    continue;
2296                                }
2297                            }
2298                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2299                        }
2300                    }
2301                    memInfo.readMemInfo();
2302                    synchronized (ActivityManagerService.this) {
2303                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2304                                + (SystemClock.uptimeMillis()-start) + "ms");
2305                        final long cachedKb = memInfo.getCachedSizeKb();
2306                        final long freeKb = memInfo.getFreeSizeKb();
2307                        final long zramKb = memInfo.getZramTotalSizeKb();
2308                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2309                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2310                                kernelKb*1024, nativeTotalPss*1024);
2311                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2312                                nativeTotalPss);
2313                    }
2314                }
2315
2316                int num = 0;
2317                long[] tmp = new long[2];
2318                do {
2319                    ProcessRecord proc;
2320                    int procState;
2321                    int pid;
2322                    long lastPssTime;
2323                    synchronized (ActivityManagerService.this) {
2324                        if (mPendingPssProcesses.size() <= 0) {
2325                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2326                                    "Collected PSS of " + num + " processes in "
2327                                    + (SystemClock.uptimeMillis() - start) + "ms");
2328                            mPendingPssProcesses.clear();
2329                            return;
2330                        }
2331                        proc = mPendingPssProcesses.remove(0);
2332                        procState = proc.pssProcState;
2333                        lastPssTime = proc.lastPssTime;
2334                        if (proc.thread != null && procState == proc.setProcState
2335                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2336                                        < SystemClock.uptimeMillis()) {
2337                            pid = proc.pid;
2338                        } else {
2339                            proc = null;
2340                            pid = 0;
2341                        }
2342                    }
2343                    if (proc != null) {
2344                        long pss = Debug.getPss(pid, tmp, null);
2345                        synchronized (ActivityManagerService.this) {
2346                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2347                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2348                                num++;
2349                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2350                                        SystemClock.uptimeMillis());
2351                            }
2352                        }
2353                    }
2354                } while (true);
2355            }
2356            }
2357        }
2358    };
2359
2360    public void setSystemProcess() {
2361        try {
2362            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2363            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2364            ServiceManager.addService("meminfo", new MemBinder(this));
2365            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2366            ServiceManager.addService("dbinfo", new DbBinder(this));
2367            if (MONITOR_CPU_USAGE) {
2368                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2369            }
2370            ServiceManager.addService("permission", new PermissionController(this));
2371            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2372
2373            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2374                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2375            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2376
2377            synchronized (this) {
2378                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2379                app.persistent = true;
2380                app.pid = MY_PID;
2381                app.maxAdj = ProcessList.SYSTEM_ADJ;
2382                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2383                synchronized (mPidsSelfLocked) {
2384                    mPidsSelfLocked.put(app.pid, app);
2385                }
2386                updateLruProcessLocked(app, false, null);
2387                updateOomAdjLocked();
2388            }
2389        } catch (PackageManager.NameNotFoundException e) {
2390            throw new RuntimeException(
2391                    "Unable to find android system package", e);
2392        }
2393    }
2394
2395    public void setWindowManager(WindowManagerService wm) {
2396        mWindowManager = wm;
2397        mStackSupervisor.setWindowManager(wm);
2398        mActivityStarter.setWindowManager(wm);
2399    }
2400
2401    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2402        mUsageStatsService = usageStatsManager;
2403    }
2404
2405    public void startObservingNativeCrashes() {
2406        final NativeCrashListener ncl = new NativeCrashListener(this);
2407        ncl.start();
2408    }
2409
2410    public IAppOpsService getAppOpsService() {
2411        return mAppOpsService;
2412    }
2413
2414    static class MemBinder extends Binder {
2415        ActivityManagerService mActivityManagerService;
2416        MemBinder(ActivityManagerService activityManagerService) {
2417            mActivityManagerService = activityManagerService;
2418        }
2419
2420        @Override
2421        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2422            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2423                    != PackageManager.PERMISSION_GRANTED) {
2424                pw.println("Permission Denial: can't dump meminfo from from pid="
2425                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2426                        + " without permission " + android.Manifest.permission.DUMP);
2427                return;
2428            }
2429
2430            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2431        }
2432    }
2433
2434    static class GraphicsBinder extends Binder {
2435        ActivityManagerService mActivityManagerService;
2436        GraphicsBinder(ActivityManagerService activityManagerService) {
2437            mActivityManagerService = activityManagerService;
2438        }
2439
2440        @Override
2441        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2442            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2443                    != PackageManager.PERMISSION_GRANTED) {
2444                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2445                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2446                        + " without permission " + android.Manifest.permission.DUMP);
2447                return;
2448            }
2449
2450            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2451        }
2452    }
2453
2454    static class DbBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        DbBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump dbinfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpDbInfo(fd, pw, args);
2471        }
2472    }
2473
2474    static class CpuBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        CpuBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            synchronized (mActivityManagerService.mProcessCpuTracker) {
2491                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2492                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2493                        SystemClock.uptimeMillis()));
2494            }
2495        }
2496    }
2497
2498    public static final class Lifecycle extends SystemService {
2499        private final ActivityManagerService mService;
2500
2501        public Lifecycle(Context context) {
2502            super(context);
2503            mService = new ActivityManagerService(context);
2504        }
2505
2506        @Override
2507        public void onStart() {
2508            mService.start();
2509        }
2510
2511        public ActivityManagerService getService() {
2512            return mService;
2513        }
2514    }
2515
2516    // Note: This method is invoked on the main thread but may need to attach various
2517    // handlers to other threads.  So take care to be explicit about the looper.
2518    public ActivityManagerService(Context systemContext) {
2519        mContext = systemContext;
2520        mFactoryTest = FactoryTest.getMode();
2521        mSystemThread = ActivityThread.currentActivityThread();
2522
2523        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2524
2525        mHandlerThread = new ServiceThread(TAG,
2526                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2527        mHandlerThread.start();
2528        mHandler = new MainHandler(mHandlerThread.getLooper());
2529        mUiHandler = new UiHandler();
2530
2531        /* static; one-time init here */
2532        if (sKillHandler == null) {
2533            sKillThread = new ServiceThread(TAG + ":kill",
2534                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2535            sKillThread.start();
2536            sKillHandler = new KillHandler(sKillThread.getLooper());
2537        }
2538
2539        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2540                "foreground", BROADCAST_FG_TIMEOUT, false);
2541        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2542                "background", BROADCAST_BG_TIMEOUT, true);
2543        mBroadcastQueues[0] = mFgBroadcastQueue;
2544        mBroadcastQueues[1] = mBgBroadcastQueue;
2545
2546        mServices = new ActiveServices(this);
2547        mProviderMap = new ProviderMap(this);
2548        mAppErrors = new AppErrors(mContext, this);
2549
2550        // TODO: Move creation of battery stats service outside of activity manager service.
2551        File dataDir = Environment.getDataDirectory();
2552        File systemDir = new File(dataDir, "system");
2553        systemDir.mkdirs();
2554        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2555        mBatteryStatsService.getActiveStatistics().readLocked();
2556        mBatteryStatsService.scheduleWriteToDisk();
2557        mOnBattery = DEBUG_POWER ? true
2558                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2559        mBatteryStatsService.getActiveStatistics().setCallback(this);
2560
2561        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2562
2563        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2564        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2565                new IAppOpsCallback.Stub() {
2566                    @Override public void opChanged(int op, int uid, String packageName) {
2567                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2568                            if (mAppOpsService.checkOperation(op, uid, packageName)
2569                                    != AppOpsManager.MODE_ALLOWED) {
2570                                runInBackgroundDisabled(uid);
2571                            }
2572                        }
2573                    }
2574                });
2575
2576        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2577
2578        mUserController = new UserController(this);
2579
2580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2582
2583        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2584
2585        mConfiguration.setToDefaults();
2586        mConfiguration.setLocales(LocaleList.getDefault());
2587
2588        mConfigurationSeq = mConfiguration.seq = 1;
2589        mProcessCpuTracker.init();
2590
2591        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2592        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2593        mStackSupervisor = new ActivityStackSupervisor(this);
2594        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2595        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2596
2597        mProcessCpuThread = new Thread("CpuTracker") {
2598            @Override
2599            public void run() {
2600                while (true) {
2601                    try {
2602                        try {
2603                            synchronized(this) {
2604                                final long now = SystemClock.uptimeMillis();
2605                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2606                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2607                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2608                                //        + ", write delay=" + nextWriteDelay);
2609                                if (nextWriteDelay < nextCpuDelay) {
2610                                    nextCpuDelay = nextWriteDelay;
2611                                }
2612                                if (nextCpuDelay > 0) {
2613                                    mProcessCpuMutexFree.set(true);
2614                                    this.wait(nextCpuDelay);
2615                                }
2616                            }
2617                        } catch (InterruptedException e) {
2618                        }
2619                        updateCpuStatsNow();
2620                    } catch (Exception e) {
2621                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2622                    }
2623                }
2624            }
2625        };
2626
2627        Watchdog.getInstance().addMonitor(this);
2628        Watchdog.getInstance().addThread(mHandler);
2629    }
2630
2631    public void setSystemServiceManager(SystemServiceManager mgr) {
2632        mSystemServiceManager = mgr;
2633    }
2634
2635    public void setInstaller(Installer installer) {
2636        mInstaller = installer;
2637    }
2638
2639    private void start() {
2640        Process.removeAllProcessGroups();
2641        mProcessCpuThread.start();
2642
2643        mBatteryStatsService.publish(mContext);
2644        mAppOpsService.publish(mContext);
2645        Slog.d("AppOps", "AppOpsService published");
2646        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2647    }
2648
2649    void onUserStoppedLocked(int userId) {
2650        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2651    }
2652
2653    public void initPowerManagement() {
2654        mStackSupervisor.initPowerManagement();
2655        mBatteryStatsService.initPowerManagement();
2656        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2657        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2658        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2659        mVoiceWakeLock.setReferenceCounted(false);
2660    }
2661
2662    @Override
2663    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2664            throws RemoteException {
2665        if (code == SYSPROPS_TRANSACTION) {
2666            // We need to tell all apps about the system property change.
2667            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2668            synchronized(this) {
2669                final int NP = mProcessNames.getMap().size();
2670                for (int ip=0; ip<NP; ip++) {
2671                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2672                    final int NA = apps.size();
2673                    for (int ia=0; ia<NA; ia++) {
2674                        ProcessRecord app = apps.valueAt(ia);
2675                        if (app.thread != null) {
2676                            procs.add(app.thread.asBinder());
2677                        }
2678                    }
2679                }
2680            }
2681
2682            int N = procs.size();
2683            for (int i=0; i<N; i++) {
2684                Parcel data2 = Parcel.obtain();
2685                try {
2686                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2687                } catch (RemoteException e) {
2688                }
2689                data2.recycle();
2690            }
2691        }
2692        try {
2693            return super.onTransact(code, data, reply, flags);
2694        } catch (RuntimeException e) {
2695            // The activity manager only throws security exceptions, so let's
2696            // log all others.
2697            if (!(e instanceof SecurityException)) {
2698                Slog.wtf(TAG, "Activity Manager Crash", e);
2699            }
2700            throw e;
2701        }
2702    }
2703
2704    void updateCpuStats() {
2705        final long now = SystemClock.uptimeMillis();
2706        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2707            return;
2708        }
2709        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2710            synchronized (mProcessCpuThread) {
2711                mProcessCpuThread.notify();
2712            }
2713        }
2714    }
2715
2716    void updateCpuStatsNow() {
2717        synchronized (mProcessCpuTracker) {
2718            mProcessCpuMutexFree.set(false);
2719            final long now = SystemClock.uptimeMillis();
2720            boolean haveNewCpuStats = false;
2721
2722            if (MONITOR_CPU_USAGE &&
2723                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2724                mLastCpuTime.set(now);
2725                mProcessCpuTracker.update();
2726                if (mProcessCpuTracker.hasGoodLastStats()) {
2727                    haveNewCpuStats = true;
2728                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2729                    //Slog.i(TAG, "Total CPU usage: "
2730                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2731
2732                    // Slog the cpu usage if the property is set.
2733                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2734                        int user = mProcessCpuTracker.getLastUserTime();
2735                        int system = mProcessCpuTracker.getLastSystemTime();
2736                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2737                        int irq = mProcessCpuTracker.getLastIrqTime();
2738                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2739                        int idle = mProcessCpuTracker.getLastIdleTime();
2740
2741                        int total = user + system + iowait + irq + softIrq + idle;
2742                        if (total == 0) total = 1;
2743
2744                        EventLog.writeEvent(EventLogTags.CPU,
2745                                ((user+system+iowait+irq+softIrq) * 100) / total,
2746                                (user * 100) / total,
2747                                (system * 100) / total,
2748                                (iowait * 100) / total,
2749                                (irq * 100) / total,
2750                                (softIrq * 100) / total);
2751                    }
2752                }
2753            }
2754
2755            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2756            synchronized(bstats) {
2757                synchronized(mPidsSelfLocked) {
2758                    if (haveNewCpuStats) {
2759                        if (bstats.startAddingCpuLocked()) {
2760                            int totalUTime = 0;
2761                            int totalSTime = 0;
2762                            final int N = mProcessCpuTracker.countStats();
2763                            for (int i=0; i<N; i++) {
2764                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2765                                if (!st.working) {
2766                                    continue;
2767                                }
2768                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2769                                totalUTime += st.rel_utime;
2770                                totalSTime += st.rel_stime;
2771                                if (pr != null) {
2772                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2773                                    if (ps == null || !ps.isActive()) {
2774                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2775                                                pr.info.uid, pr.processName);
2776                                    }
2777                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2778                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2779                                } else {
2780                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2781                                    if (ps == null || !ps.isActive()) {
2782                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2783                                                bstats.mapUid(st.uid), st.name);
2784                                    }
2785                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2786                                }
2787                            }
2788                            final int userTime = mProcessCpuTracker.getLastUserTime();
2789                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2790                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2791                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2792                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2793                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2794                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2795                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2796                        }
2797                    }
2798                }
2799
2800                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2801                    mLastWriteTime = now;
2802                    mBatteryStatsService.scheduleWriteToDisk();
2803                }
2804            }
2805        }
2806    }
2807
2808    @Override
2809    public void batteryNeedsCpuUpdate() {
2810        updateCpuStatsNow();
2811    }
2812
2813    @Override
2814    public void batteryPowerChanged(boolean onBattery) {
2815        // When plugging in, update the CPU stats first before changing
2816        // the plug state.
2817        updateCpuStatsNow();
2818        synchronized (this) {
2819            synchronized(mPidsSelfLocked) {
2820                mOnBattery = DEBUG_POWER ? true : onBattery;
2821            }
2822        }
2823    }
2824
2825    @Override
2826    public void batterySendBroadcast(Intent intent) {
2827        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2828                AppOpsManager.OP_NONE, null, false, false,
2829                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2830    }
2831
2832    /**
2833     * Initialize the application bind args. These are passed to each
2834     * process when the bindApplication() IPC is sent to the process. They're
2835     * lazily setup to make sure the services are running when they're asked for.
2836     */
2837    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2838        if (mAppBindArgs == null) {
2839            mAppBindArgs = new HashMap<>();
2840
2841            // Isolated processes won't get this optimization, so that we don't
2842            // violate the rules about which services they have access to.
2843            if (!isolated) {
2844                // Setup the application init args
2845                mAppBindArgs.put("package", ServiceManager.getService("package"));
2846                mAppBindArgs.put("window", ServiceManager.getService("window"));
2847                mAppBindArgs.put(Context.ALARM_SERVICE,
2848                        ServiceManager.getService(Context.ALARM_SERVICE));
2849            }
2850        }
2851        return mAppBindArgs;
2852    }
2853
2854    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2855        if (r == null || mFocusedActivity == r) {
2856            return false;
2857        }
2858
2859        if (!r.isFocusable()) {
2860            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2861            return false;
2862        }
2863
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2865
2866        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2867        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2868                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2869        mDoingSetFocusedActivity = true;
2870
2871        final ActivityRecord last = mFocusedActivity;
2872        mFocusedActivity = r;
2873        if (r.task.isApplicationTask()) {
2874            if (mCurAppTimeTracker != r.appTimeTracker) {
2875                // We are switching app tracking.  Complete the current one.
2876                if (mCurAppTimeTracker != null) {
2877                    mCurAppTimeTracker.stop();
2878                    mHandler.obtainMessage(
2879                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2880                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2881                    mCurAppTimeTracker = null;
2882                }
2883                if (r.appTimeTracker != null) {
2884                    mCurAppTimeTracker = r.appTimeTracker;
2885                    startTimeTrackingFocusedActivityLocked();
2886                }
2887            } else {
2888                startTimeTrackingFocusedActivityLocked();
2889            }
2890        } else {
2891            r.appTimeTracker = null;
2892        }
2893        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2894        // TODO: Probably not, because we don't want to resume voice on switching
2895        // back to this activity
2896        if (r.task.voiceInteractor != null) {
2897            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2898        } else {
2899            finishRunningVoiceLocked();
2900            IVoiceInteractionSession session;
2901            if (last != null && ((session = last.task.voiceSession) != null
2902                    || (session = last.voiceSession) != null)) {
2903                // We had been in a voice interaction session, but now focused has
2904                // move to something different.  Just finish the session, we can't
2905                // return to it and retain the proper state and synchronization with
2906                // the voice interaction service.
2907                finishVoiceTask(session);
2908            }
2909        }
2910        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2911            mWindowManager.setFocusedApp(r.appToken, true);
2912        }
2913        applyUpdateLockStateLocked(r);
2914        applyUpdateVrModeLocked(r);
2915        if (mFocusedActivity.userId != mLastFocusedUserId) {
2916            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2917            mHandler.obtainMessage(
2918                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2919            mLastFocusedUserId = mFocusedActivity.userId;
2920        }
2921
2922        // Log a warning if the focused app is changed during the process. This could
2923        // indicate a problem of the focus setting logic!
2924        if (mFocusedActivity != r) Slog.w(TAG,
2925                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2926        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2927
2928        EventLogTags.writeAmFocusedActivity(
2929                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2930                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2931                reason);
2932        return true;
2933    }
2934
2935    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2936        if (mFocusedActivity != goingAway) {
2937            return;
2938        }
2939
2940        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2941        if (focusedStack != null) {
2942            final ActivityRecord top = focusedStack.topActivity();
2943            if (top != null && top.userId != mLastFocusedUserId) {
2944                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2945                mHandler.sendMessage(
2946                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2947                mLastFocusedUserId = top.userId;
2948            }
2949        }
2950
2951        // Try to move focus to another activity if possible.
2952        if (setFocusedActivityLocked(
2953                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2954            return;
2955        }
2956
2957        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2958                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2959        mFocusedActivity = null;
2960        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2961    }
2962
2963    @Override
2964    public void setFocusedStack(int stackId) {
2965        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2967        final long callingId = Binder.clearCallingIdentity();
2968        try {
2969            synchronized (this) {
2970                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2971                if (stack == null) {
2972                    return;
2973                }
2974                final ActivityRecord r = stack.topRunningActivityLocked();
2975                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2976                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2977                }
2978            }
2979        } finally {
2980            Binder.restoreCallingIdentity(callingId);
2981        }
2982    }
2983
2984    @Override
2985    public void setFocusedTask(int taskId) {
2986        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2987        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2988        final long callingId = Binder.clearCallingIdentity();
2989        try {
2990            synchronized (this) {
2991                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2992                if (task == null) {
2993                    return;
2994                }
2995                final ActivityRecord r = task.topRunningActivityLocked();
2996                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2997                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2998                }
2999            }
3000        } finally {
3001            Binder.restoreCallingIdentity(callingId);
3002        }
3003    }
3004
3005    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3006    @Override
3007    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3009        synchronized (this) {
3010            if (listener != null) {
3011                mTaskStackListeners.register(listener);
3012            }
3013        }
3014    }
3015
3016    @Override
3017    public void notifyActivityDrawn(IBinder token) {
3018        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3019        synchronized (this) {
3020            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3021            if (r != null) {
3022                r.task.stack.notifyActivityDrawnLocked(r);
3023            }
3024        }
3025    }
3026
3027    final void applyUpdateLockStateLocked(ActivityRecord r) {
3028        // Modifications to the UpdateLock state are done on our handler, outside
3029        // the activity manager's locks.  The new state is determined based on the
3030        // state *now* of the relevant activity record.  The object is passed to
3031        // the handler solely for logging detail, not to be consulted/modified.
3032        final boolean nextState = r != null && r.immersive;
3033        mHandler.sendMessage(
3034                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3035    }
3036
3037    final void applyUpdateVrModeLocked(ActivityRecord r) {
3038        mHandler.sendMessage(
3039                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3040    }
3041
3042    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3043        mHandler.sendMessage(
3044                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3045    }
3046
3047    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3048        Message msg = Message.obtain();
3049        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3050        msg.obj = r.task.askedCompatMode ? null : r;
3051        mUiHandler.sendMessage(msg);
3052    }
3053
3054    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3055            String what, Object obj, ProcessRecord srcApp) {
3056        app.lastActivityTime = now;
3057
3058        if (app.activities.size() > 0) {
3059            // Don't want to touch dependent processes that are hosting activities.
3060            return index;
3061        }
3062
3063        int lrui = mLruProcesses.lastIndexOf(app);
3064        if (lrui < 0) {
3065            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3066                    + what + " " + obj + " from " + srcApp);
3067            return index;
3068        }
3069
3070        if (lrui >= index) {
3071            // Don't want to cause this to move dependent processes *back* in the
3072            // list as if they were less frequently used.
3073            return index;
3074        }
3075
3076        if (lrui >= mLruProcessActivityStart) {
3077            // Don't want to touch dependent processes that are hosting activities.
3078            return index;
3079        }
3080
3081        mLruProcesses.remove(lrui);
3082        if (index > 0) {
3083            index--;
3084        }
3085        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3086                + " in LRU list: " + app);
3087        mLruProcesses.add(index, app);
3088        return index;
3089    }
3090
3091    static void killProcessGroup(int uid, int pid) {
3092        if (sKillHandler != null) {
3093            sKillHandler.sendMessage(
3094                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3095        } else {
3096            Slog.w(TAG, "Asked to kill process group before system bringup!");
3097            Process.killProcessGroup(uid, pid);
3098        }
3099    }
3100
3101    final void removeLruProcessLocked(ProcessRecord app) {
3102        int lrui = mLruProcesses.lastIndexOf(app);
3103        if (lrui >= 0) {
3104            if (!app.killed) {
3105                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3106                Process.killProcessQuiet(app.pid);
3107                killProcessGroup(app.uid, app.pid);
3108            }
3109            if (lrui <= mLruProcessActivityStart) {
3110                mLruProcessActivityStart--;
3111            }
3112            if (lrui <= mLruProcessServiceStart) {
3113                mLruProcessServiceStart--;
3114            }
3115            mLruProcesses.remove(lrui);
3116        }
3117    }
3118
3119    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3120            ProcessRecord client) {
3121        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3122                || app.treatLikeActivity;
3123        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3124        if (!activityChange && hasActivity) {
3125            // The process has activities, so we are only allowing activity-based adjustments
3126            // to move it.  It should be kept in the front of the list with other
3127            // processes that have activities, and we don't want those to change their
3128            // order except due to activity operations.
3129            return;
3130        }
3131
3132        mLruSeq++;
3133        final long now = SystemClock.uptimeMillis();
3134        app.lastActivityTime = now;
3135
3136        // First a quick reject: if the app is already at the position we will
3137        // put it, then there is nothing to do.
3138        if (hasActivity) {
3139            final int N = mLruProcesses.size();
3140            if (N > 0 && mLruProcesses.get(N-1) == app) {
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3142                return;
3143            }
3144        } else {
3145            if (mLruProcessServiceStart > 0
3146                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3147                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3148                return;
3149            }
3150        }
3151
3152        int lrui = mLruProcesses.lastIndexOf(app);
3153
3154        if (app.persistent && lrui >= 0) {
3155            // We don't care about the position of persistent processes, as long as
3156            // they are in the list.
3157            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3158            return;
3159        }
3160
3161        /* In progress: compute new position first, so we can avoid doing work
3162           if the process is not actually going to move.  Not yet working.
3163        int addIndex;
3164        int nextIndex;
3165        boolean inActivity = false, inService = false;
3166        if (hasActivity) {
3167            // Process has activities, put it at the very tipsy-top.
3168            addIndex = mLruProcesses.size();
3169            nextIndex = mLruProcessServiceStart;
3170            inActivity = true;
3171        } else if (hasService) {
3172            // Process has services, put it at the top of the service list.
3173            addIndex = mLruProcessActivityStart;
3174            nextIndex = mLruProcessServiceStart;
3175            inActivity = true;
3176            inService = true;
3177        } else  {
3178            // Process not otherwise of interest, it goes to the top of the non-service area.
3179            addIndex = mLruProcessServiceStart;
3180            if (client != null) {
3181                int clientIndex = mLruProcesses.lastIndexOf(client);
3182                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3183                        + app);
3184                if (clientIndex >= 0 && addIndex > clientIndex) {
3185                    addIndex = clientIndex;
3186                }
3187            }
3188            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3189        }
3190
3191        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3192                + mLruProcessActivityStart + "): " + app);
3193        */
3194
3195        if (lrui >= 0) {
3196            if (lrui < mLruProcessActivityStart) {
3197                mLruProcessActivityStart--;
3198            }
3199            if (lrui < mLruProcessServiceStart) {
3200                mLruProcessServiceStart--;
3201            }
3202            /*
3203            if (addIndex > lrui) {
3204                addIndex--;
3205            }
3206            if (nextIndex > lrui) {
3207                nextIndex--;
3208            }
3209            */
3210            mLruProcesses.remove(lrui);
3211        }
3212
3213        /*
3214        mLruProcesses.add(addIndex, app);
3215        if (inActivity) {
3216            mLruProcessActivityStart++;
3217        }
3218        if (inService) {
3219            mLruProcessActivityStart++;
3220        }
3221        */
3222
3223        int nextIndex;
3224        if (hasActivity) {
3225            final int N = mLruProcesses.size();
3226            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3227                // Process doesn't have activities, but has clients with
3228                // activities...  move it up, but one below the top (the top
3229                // should always have a real activity).
3230                if (DEBUG_LRU) Slog.d(TAG_LRU,
3231                        "Adding to second-top of LRU activity list: " + app);
3232                mLruProcesses.add(N - 1, app);
3233                // To keep it from spamming the LRU list (by making a bunch of clients),
3234                // we will push down any other entries owned by the app.
3235                final int uid = app.info.uid;
3236                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3237                    ProcessRecord subProc = mLruProcesses.get(i);
3238                    if (subProc.info.uid == uid) {
3239                        // We want to push this one down the list.  If the process after
3240                        // it is for the same uid, however, don't do so, because we don't
3241                        // want them internally to be re-ordered.
3242                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3243                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3244                                    "Pushing uid " + uid + " swapping at " + i + ": "
3245                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3246                            ProcessRecord tmp = mLruProcesses.get(i);
3247                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3248                            mLruProcesses.set(i - 1, tmp);
3249                            i--;
3250                        }
3251                    } else {
3252                        // A gap, we can stop here.
3253                        break;
3254                    }
3255                }
3256            } else {
3257                // Process has activities, put it at the very tipsy-top.
3258                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3259                mLruProcesses.add(app);
3260            }
3261            nextIndex = mLruProcessServiceStart;
3262        } else if (hasService) {
3263            // Process has services, put it at the top of the service list.
3264            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3265            mLruProcesses.add(mLruProcessActivityStart, app);
3266            nextIndex = mLruProcessServiceStart;
3267            mLruProcessActivityStart++;
3268        } else  {
3269            // Process not otherwise of interest, it goes to the top of the non-service area.
3270            int index = mLruProcessServiceStart;
3271            if (client != null) {
3272                // If there is a client, don't allow the process to be moved up higher
3273                // in the list than that client.
3274                int clientIndex = mLruProcesses.lastIndexOf(client);
3275                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3276                        + " when updating " + app);
3277                if (clientIndex <= lrui) {
3278                    // Don't allow the client index restriction to push it down farther in the
3279                    // list than it already is.
3280                    clientIndex = lrui;
3281                }
3282                if (clientIndex >= 0 && index > clientIndex) {
3283                    index = clientIndex;
3284                }
3285            }
3286            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3287            mLruProcesses.add(index, app);
3288            nextIndex = index-1;
3289            mLruProcessActivityStart++;
3290            mLruProcessServiceStart++;
3291        }
3292
3293        // If the app is currently using a content provider or service,
3294        // bump those processes as well.
3295        for (int j=app.connections.size()-1; j>=0; j--) {
3296            ConnectionRecord cr = app.connections.valueAt(j);
3297            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3298                    && cr.binding.service.app != null
3299                    && cr.binding.service.app.lruSeq != mLruSeq
3300                    && !cr.binding.service.app.persistent) {
3301                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3302                        "service connection", cr, app);
3303            }
3304        }
3305        for (int j=app.conProviders.size()-1; j>=0; j--) {
3306            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3307            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3308                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3309                        "provider reference", cpr, app);
3310            }
3311        }
3312    }
3313
3314    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3315        if (uid == Process.SYSTEM_UID) {
3316            // The system gets to run in any process.  If there are multiple
3317            // processes with the same uid, just pick the first (this
3318            // should never happen).
3319            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3320            if (procs == null) return null;
3321            final int procCount = procs.size();
3322            for (int i = 0; i < procCount; i++) {
3323                final int procUid = procs.keyAt(i);
3324                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3325                    // Don't use an app process or different user process for system component.
3326                    continue;
3327                }
3328                return procs.valueAt(i);
3329            }
3330        }
3331        ProcessRecord proc = mProcessNames.get(processName, uid);
3332        if (false && proc != null && !keepIfLarge
3333                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3334                && proc.lastCachedPss >= 4000) {
3335            // Turn this condition on to cause killing to happen regularly, for testing.
3336            if (proc.baseProcessTracker != null) {
3337                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3338            }
3339            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3340        } else if (proc != null && !keepIfLarge
3341                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3343            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3344            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3345                if (proc.baseProcessTracker != null) {
3346                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347                }
3348                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349            }
3350        }
3351        return proc;
3352    }
3353
3354    void notifyPackageUse(String packageName, int reason) {
3355        IPackageManager pm = AppGlobals.getPackageManager();
3356        try {
3357            pm.notifyPackageUse(packageName, reason);
3358        } catch (RemoteException e) {
3359        }
3360    }
3361
3362    boolean isNextTransitionForward() {
3363        int transit = mWindowManager.getPendingAppTransition();
3364        return transit == TRANSIT_ACTIVITY_OPEN
3365                || transit == TRANSIT_TASK_OPEN
3366                || transit == TRANSIT_TASK_TO_FRONT;
3367    }
3368
3369    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3370            String processName, String abiOverride, int uid, Runnable crashHandler) {
3371        synchronized(this) {
3372            ApplicationInfo info = new ApplicationInfo();
3373            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3374            // For isolated processes, the former contains the parent's uid and the latter the
3375            // actual uid of the isolated process.
3376            // In the special case introduced by this method (which is, starting an isolated
3377            // process directly from the SystemServer without an actual parent app process) the
3378            // closest thing to a parent's uid is SYSTEM_UID.
3379            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3380            // the |isolated| logic in the ProcessRecord constructor.
3381            info.uid = Process.SYSTEM_UID;
3382            info.processName = processName;
3383            info.className = entryPoint;
3384            info.packageName = "android";
3385            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3386                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3387                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3388                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3389                    crashHandler);
3390            return proc != null ? proc.pid : 0;
3391        }
3392    }
3393
3394    final ProcessRecord startProcessLocked(String processName,
3395            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3396            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3397            boolean isolated, boolean keepIfLarge) {
3398        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3399                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3400                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3401                null /* crashHandler */);
3402    }
3403
3404    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3405            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3406            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3407            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3408        long startTime = SystemClock.elapsedRealtime();
3409        ProcessRecord app;
3410        if (!isolated) {
3411            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3412            checkTime(startTime, "startProcess: after getProcessRecord");
3413
3414            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3415                // If we are in the background, then check to see if this process
3416                // is bad.  If so, we will just silently fail.
3417                if (mAppErrors.isBadProcessLocked(info)) {
3418                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3419                            + "/" + info.processName);
3420                    return null;
3421                }
3422            } else {
3423                // When the user is explicitly starting a process, then clear its
3424                // crash count so that we won't make it bad until they see at
3425                // least one crash dialog again, and make the process good again
3426                // if it had been bad.
3427                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3428                        + "/" + info.processName);
3429                mAppErrors.resetProcessCrashTimeLocked(info);
3430                if (mAppErrors.isBadProcessLocked(info)) {
3431                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3432                            UserHandle.getUserId(info.uid), info.uid,
3433                            info.processName);
3434                    mAppErrors.clearBadProcessLocked(info);
3435                    if (app != null) {
3436                        app.bad = false;
3437                    }
3438                }
3439            }
3440        } else {
3441            // If this is an isolated process, it can't re-use an existing process.
3442            app = null;
3443        }
3444
3445        // app launch boost for big.little configurations
3446        // use cpusets to migrate freshly launched tasks to big cores
3447        synchronized(ActivityManagerService.this) {
3448            nativeMigrateToBoost();
3449            mIsBoosted = true;
3450            mBoostStartTime = SystemClock.uptimeMillis();
3451            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3452            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3453        }
3454
3455        // We don't have to do anything more if:
3456        // (1) There is an existing application record; and
3457        // (2) The caller doesn't think it is dead, OR there is no thread
3458        //     object attached to it so we know it couldn't have crashed; and
3459        // (3) There is a pid assigned to it, so it is either starting or
3460        //     already running.
3461        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3462                + " app=" + app + " knownToBeDead=" + knownToBeDead
3463                + " thread=" + (app != null ? app.thread : null)
3464                + " pid=" + (app != null ? app.pid : -1));
3465        if (app != null && app.pid > 0) {
3466            if (!knownToBeDead || app.thread == null) {
3467                // We already have the app running, or are waiting for it to
3468                // come up (we have a pid but not yet its thread), so keep it.
3469                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3470                // If this is a new package in the process, add the package to the list
3471                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3472                checkTime(startTime, "startProcess: done, added package to proc");
3473                return app;
3474            }
3475
3476            // An application record is attached to a previous process,
3477            // clean it up now.
3478            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3479            checkTime(startTime, "startProcess: bad proc running, killing");
3480            killProcessGroup(app.uid, app.pid);
3481            handleAppDiedLocked(app, true, true);
3482            checkTime(startTime, "startProcess: done killing old proc");
3483        }
3484
3485        String hostingNameStr = hostingName != null
3486                ? hostingName.flattenToShortString() : null;
3487
3488        if (app == null) {
3489            checkTime(startTime, "startProcess: creating new process record");
3490            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3491            if (app == null) {
3492                Slog.w(TAG, "Failed making new process record for "
3493                        + processName + "/" + info.uid + " isolated=" + isolated);
3494                return null;
3495            }
3496            app.crashHandler = crashHandler;
3497            checkTime(startTime, "startProcess: done creating new process record");
3498        } else {
3499            // If this is a new package in the process, add the package to the list
3500            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3501            checkTime(startTime, "startProcess: added package to existing proc");
3502        }
3503
3504        // If the system is not ready yet, then hold off on starting this
3505        // process until it is.
3506        if (!mProcessesReady
3507                && !isAllowedWhileBooting(info)
3508                && !allowWhileBooting) {
3509            if (!mProcessesOnHold.contains(app)) {
3510                mProcessesOnHold.add(app);
3511            }
3512            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3513                    "System not ready, putting on hold: " + app);
3514            checkTime(startTime, "startProcess: returning with proc on hold");
3515            return app;
3516        }
3517
3518        checkTime(startTime, "startProcess: stepping in to startProcess");
3519        startProcessLocked(
3520                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3521        checkTime(startTime, "startProcess: done starting proc!");
3522        return (app.pid != 0) ? app : null;
3523    }
3524
3525    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3526        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3527    }
3528
3529    private final void startProcessLocked(ProcessRecord app,
3530            String hostingType, String hostingNameStr) {
3531        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3532                null /* entryPoint */, null /* entryPointArgs */);
3533    }
3534
3535    private final void startProcessLocked(ProcessRecord app, String hostingType,
3536            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3537        long startTime = SystemClock.elapsedRealtime();
3538        if (app.pid > 0 && app.pid != MY_PID) {
3539            checkTime(startTime, "startProcess: removing from pids map");
3540            synchronized (mPidsSelfLocked) {
3541                mPidsSelfLocked.remove(app.pid);
3542                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3543            }
3544            checkTime(startTime, "startProcess: done removing from pids map");
3545            app.setPid(0);
3546        }
3547
3548        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3549                "startProcessLocked removing on hold: " + app);
3550        mProcessesOnHold.remove(app);
3551
3552        checkTime(startTime, "startProcess: starting to update cpu stats");
3553        updateCpuStats();
3554        checkTime(startTime, "startProcess: done updating cpu stats");
3555
3556        try {
3557            try {
3558                final int userId = UserHandle.getUserId(app.uid);
3559                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3560            } catch (RemoteException e) {
3561                throw e.rethrowAsRuntimeException();
3562            }
3563
3564            int uid = app.uid;
3565            int[] gids = null;
3566            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3567            if (!app.isolated) {
3568                int[] permGids = null;
3569                try {
3570                    checkTime(startTime, "startProcess: getting gids from package manager");
3571                    final IPackageManager pm = AppGlobals.getPackageManager();
3572                    permGids = pm.getPackageGids(app.info.packageName,
3573                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3574                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3575                            MountServiceInternal.class);
3576                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3577                            app.info.packageName);
3578                } catch (RemoteException e) {
3579                    throw e.rethrowAsRuntimeException();
3580                }
3581
3582                /*
3583                 * Add shared application and profile GIDs so applications can share some
3584                 * resources like shared libraries and access user-wide resources
3585                 */
3586                if (ArrayUtils.isEmpty(permGids)) {
3587                    gids = new int[2];
3588                } else {
3589                    gids = new int[permGids.length + 2];
3590                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3591                }
3592                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3593                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3594            }
3595            checkTime(startTime, "startProcess: building args");
3596            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3597                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3598                        && mTopComponent != null
3599                        && app.processName.equals(mTopComponent.getPackageName())) {
3600                    uid = 0;
3601                }
3602                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3603                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3604                    uid = 0;
3605                }
3606            }
3607            int debugFlags = 0;
3608            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3609                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3610                // Also turn on CheckJNI for debuggable apps. It's quite
3611                // awkward to turn on otherwise.
3612                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3613            }
3614            // Run the app in safe mode if its manifest requests so or the
3615            // system is booted in safe mode.
3616            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3617                mSafeMode == true) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3619            }
3620            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3624            if ("true".equals(genDebugInfoProperty)) {
3625                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3626            }
3627            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3628                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3629            }
3630            if ("1".equals(SystemProperties.get("debug.assert"))) {
3631                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3632            }
3633            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3634                // Enable all debug flags required by the native debugger.
3635                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3636                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3637                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3638                mNativeDebuggingApp = null;
3639            }
3640
3641            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3642            if (requiredAbi == null) {
3643                requiredAbi = Build.SUPPORTED_ABIS[0];
3644            }
3645
3646            String instructionSet = null;
3647            if (app.info.primaryCpuAbi != null) {
3648                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3649            }
3650
3651            app.gids = gids;
3652            app.requiredAbi = requiredAbi;
3653            app.instructionSet = instructionSet;
3654
3655            // Start the process.  It will either succeed and return a result containing
3656            // the PID of the new process, or else throw a RuntimeException.
3657            boolean isActivityProcess = (entryPoint == null);
3658            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3659            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3660                    app.processName);
3661            checkTime(startTime, "startProcess: asking zygote to start proc");
3662            Process.ProcessStartResult startResult = Process.start(entryPoint,
3663                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3664                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3665                    app.info.dataDir, entryPointArgs);
3666            checkTime(startTime, "startProcess: returned from zygote!");
3667            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3668
3669            if (app.isolated) {
3670                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3671            }
3672            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3673            checkTime(startTime, "startProcess: done updating battery stats");
3674
3675            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3676                    UserHandle.getUserId(uid), startResult.pid, uid,
3677                    app.processName, hostingType,
3678                    hostingNameStr != null ? hostingNameStr : "");
3679
3680            try {
3681                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3682                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3683            } catch (RemoteException ex) {
3684                // Ignore
3685            }
3686
3687            if (app.persistent) {
3688                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3689            }
3690
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            app.setPid(startResult.pid);
3713            app.usingWrapper = startResult.usingWrapper;
3714            app.removed = false;
3715            app.killed = false;
3716            app.killedByAm = false;
3717            checkTime(startTime, "startProcess: starting to update pids map");
3718            synchronized (mPidsSelfLocked) {
3719                this.mPidsSelfLocked.put(startResult.pid, app);
3720                if (isActivityProcess) {
3721                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3722                    msg.obj = app;
3723                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3724                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3725                }
3726            }
3727            checkTime(startTime, "startProcess: done updating pids map");
3728        } catch (RuntimeException e) {
3729            // XXX do better error recovery.
3730            app.setPid(0);
3731            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3732            if (app.isolated) {
3733                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3734            }
3735            Slog.e(TAG, "Failure starting process " + app.processName, e);
3736        }
3737    }
3738
3739    void updateUsageStats(ActivityRecord component, boolean resumed) {
3740        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3741                "updateUsageStats: comp=" + component + "res=" + resumed);
3742        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3743        if (resumed) {
3744            if (mUsageStatsService != null) {
3745                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3746                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3747            }
3748            synchronized (stats) {
3749                stats.noteActivityResumedLocked(component.app.uid);
3750            }
3751        } else {
3752            if (mUsageStatsService != null) {
3753                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3754                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3755            }
3756            synchronized (stats) {
3757                stats.noteActivityPausedLocked(component.app.uid);
3758            }
3759        }
3760    }
3761
3762    Intent getHomeIntent() {
3763        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3764        intent.setComponent(mTopComponent);
3765        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3766        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3767            intent.addCategory(Intent.CATEGORY_HOME);
3768        }
3769        return intent;
3770    }
3771
3772    boolean startHomeActivityLocked(int userId, String reason) {
3773        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3774                && mTopAction == null) {
3775            // We are running in factory test mode, but unable to find
3776            // the factory test app, so just sit around displaying the
3777            // error message and don't try to start anything.
3778            return false;
3779        }
3780        Intent intent = getHomeIntent();
3781        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3782        if (aInfo != null) {
3783            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3784            // Don't do this if the home app is currently being
3785            // instrumented.
3786            aInfo = new ActivityInfo(aInfo);
3787            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3788            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3789                    aInfo.applicationInfo.uid, true);
3790            if (app == null || app.instrumentationClass == null) {
3791                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3792                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3793            }
3794        }
3795
3796        return true;
3797    }
3798
3799    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3800        ActivityInfo ai = null;
3801        ComponentName comp = intent.getComponent();
3802        try {
3803            if (comp != null) {
3804                // Factory test.
3805                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3806            } else {
3807                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3808                        intent,
3809                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3810                        flags, userId);
3811
3812                if (info != null) {
3813                    ai = info.activityInfo;
3814                }
3815            }
3816        } catch (RemoteException e) {
3817            // ignore
3818        }
3819
3820        return ai;
3821    }
3822
3823    /**
3824     * Starts the "new version setup screen" if appropriate.
3825     */
3826    void startSetupActivityLocked() {
3827        // Only do this once per boot.
3828        if (mCheckedForSetup) {
3829            return;
3830        }
3831
3832        // We will show this screen if the current one is a different
3833        // version than the last one shown, and we are not running in
3834        // low-level factory test mode.
3835        final ContentResolver resolver = mContext.getContentResolver();
3836        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3837                Settings.Global.getInt(resolver,
3838                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3839            mCheckedForSetup = true;
3840
3841            // See if we should be showing the platform update setup UI.
3842            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3843            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3844                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3845            if (!ris.isEmpty()) {
3846                final ResolveInfo ri = ris.get(0);
3847                String vers = ri.activityInfo.metaData != null
3848                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3849                        : null;
3850                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3851                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3852                            Intent.METADATA_SETUP_VERSION);
3853                }
3854                String lastVers = Settings.Secure.getString(
3855                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3856                if (vers != null && !vers.equals(lastVers)) {
3857                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3858                    intent.setComponent(new ComponentName(
3859                            ri.activityInfo.packageName, ri.activityInfo.name));
3860                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3861                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3862                            null, 0, 0, 0, null, false, false, null, null, null);
3863                }
3864            }
3865        }
3866    }
3867
3868    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3869        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3870    }
3871
3872    void enforceNotIsolatedCaller(String caller) {
3873        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3874            throw new SecurityException("Isolated process not allowed to call " + caller);
3875        }
3876    }
3877
3878    void enforceShellRestriction(String restriction, int userHandle) {
3879        if (Binder.getCallingUid() == Process.SHELL_UID) {
3880            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3881                throw new SecurityException("Shell does not have permission to access user "
3882                        + userHandle);
3883            }
3884        }
3885    }
3886
3887    @Override
3888    public int getFrontActivityScreenCompatMode() {
3889        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3890        synchronized (this) {
3891            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3892        }
3893    }
3894
3895    @Override
3896    public void setFrontActivityScreenCompatMode(int mode) {
3897        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3898                "setFrontActivityScreenCompatMode");
3899        synchronized (this) {
3900            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3901        }
3902    }
3903
3904    @Override
3905    public int getPackageScreenCompatMode(String packageName) {
3906        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3907        synchronized (this) {
3908            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3909        }
3910    }
3911
3912    @Override
3913    public void setPackageScreenCompatMode(String packageName, int mode) {
3914        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3915                "setPackageScreenCompatMode");
3916        synchronized (this) {
3917            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3918        }
3919    }
3920
3921    @Override
3922    public boolean getPackageAskScreenCompat(String packageName) {
3923        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3924        synchronized (this) {
3925            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3926        }
3927    }
3928
3929    @Override
3930    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3931        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3932                "setPackageAskScreenCompat");
3933        synchronized (this) {
3934            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3935        }
3936    }
3937
3938    private boolean hasUsageStatsPermission(String callingPackage) {
3939        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3940                Binder.getCallingUid(), callingPackage);
3941        if (mode == AppOpsManager.MODE_DEFAULT) {
3942            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3943                    == PackageManager.PERMISSION_GRANTED;
3944        }
3945        return mode == AppOpsManager.MODE_ALLOWED;
3946    }
3947
3948    @Override
3949    public int getPackageProcessState(String packageName, String callingPackage) {
3950        if (!hasUsageStatsPermission(callingPackage)) {
3951            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3952                    "getPackageProcessState");
3953        }
3954
3955        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3956        synchronized (this) {
3957            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3958                final ProcessRecord proc = mLruProcesses.get(i);
3959                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3960                        || procState > proc.setProcState) {
3961                    boolean found = false;
3962                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3963                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3964                            procState = proc.setProcState;
3965                            found = true;
3966                        }
3967                    }
3968                    if (proc.pkgDeps != null && !found) {
3969                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3970                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3971                                procState = proc.setProcState;
3972                                break;
3973                            }
3974                        }
3975                    }
3976                }
3977            }
3978        }
3979        return procState;
3980    }
3981
3982    @Override
3983    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3984        synchronized (this) {
3985            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3986            if (app == null) {
3987                return false;
3988            }
3989            if (app.trimMemoryLevel < level && app.thread != null &&
3990                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3991                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3992                try {
3993                    app.thread.scheduleTrimMemory(level);
3994                    app.trimMemoryLevel = level;
3995                    return true;
3996                } catch (RemoteException e) {
3997                    // Fallthrough to failure case.
3998                }
3999            }
4000        }
4001        return false;
4002    }
4003
4004    private void dispatchProcessesChanged() {
4005        int N;
4006        synchronized (this) {
4007            N = mPendingProcessChanges.size();
4008            if (mActiveProcessChanges.length < N) {
4009                mActiveProcessChanges = new ProcessChangeItem[N];
4010            }
4011            mPendingProcessChanges.toArray(mActiveProcessChanges);
4012            mPendingProcessChanges.clear();
4013            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4014                    "*** Delivering " + N + " process changes");
4015        }
4016
4017        int i = mProcessObservers.beginBroadcast();
4018        while (i > 0) {
4019            i--;
4020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4021            if (observer != null) {
4022                try {
4023                    for (int j=0; j<N; j++) {
4024                        ProcessChangeItem item = mActiveProcessChanges[j];
4025                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4026                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4028                                    + item.uid + ": " + item.foregroundActivities);
4029                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4030                                    item.foregroundActivities);
4031                        }
4032                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4033                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4034                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4035                                    + ": " + item.processState);
4036                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4037                        }
4038                    }
4039                } catch (RemoteException e) {
4040                }
4041            }
4042        }
4043        mProcessObservers.finishBroadcast();
4044
4045        synchronized (this) {
4046            for (int j=0; j<N; j++) {
4047                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4048            }
4049        }
4050    }
4051
4052    private void dispatchProcessDied(int pid, int uid) {
4053        int i = mProcessObservers.beginBroadcast();
4054        while (i > 0) {
4055            i--;
4056            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4057            if (observer != null) {
4058                try {
4059                    observer.onProcessDied(pid, uid);
4060                } catch (RemoteException e) {
4061                }
4062            }
4063        }
4064        mProcessObservers.finishBroadcast();
4065    }
4066
4067    private void dispatchUidsChanged() {
4068        int N;
4069        synchronized (this) {
4070            N = mPendingUidChanges.size();
4071            if (mActiveUidChanges.length < N) {
4072                mActiveUidChanges = new UidRecord.ChangeItem[N];
4073            }
4074            for (int i=0; i<N; i++) {
4075                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4076                mActiveUidChanges[i] = change;
4077                if (change.uidRecord != null) {
4078                    change.uidRecord.pendingChange = null;
4079                    change.uidRecord = null;
4080                }
4081            }
4082            mPendingUidChanges.clear();
4083            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4084                    "*** Delivering " + N + " uid changes");
4085        }
4086
4087        if (mLocalPowerManager != null) {
4088            for (int j=0; j<N; j++) {
4089                UidRecord.ChangeItem item = mActiveUidChanges[j];
4090                if (item.change == UidRecord.CHANGE_GONE
4091                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4092                    mLocalPowerManager.uidGone(item.uid);
4093                } else {
4094                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4095                }
4096            }
4097        }
4098
4099        int i = mUidObservers.beginBroadcast();
4100        while (i > 0) {
4101            i--;
4102            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4103            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4104            if (observer != null) {
4105                try {
4106                    for (int j=0; j<N; j++) {
4107                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4108                        final int change = item.change;
4109                        UidRecord validateUid = null;
4110                        if (VALIDATE_UID_STATES && i == 0) {
4111                            validateUid = mValidateUids.get(item.uid);
4112                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4113                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4114                                validateUid = new UidRecord(item.uid);
4115                                mValidateUids.put(item.uid, validateUid);
4116                            }
4117                        }
4118                        if (change == UidRecord.CHANGE_IDLE
4119                                || change == UidRecord.CHANGE_GONE_IDLE) {
4120                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4121                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4122                                        "UID idle uid=" + item.uid);
4123                                observer.onUidIdle(item.uid);
4124                            }
4125                            if (VALIDATE_UID_STATES && i == 0) {
4126                                if (validateUid != null) {
4127                                    validateUid.idle = true;
4128                                }
4129                            }
4130                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4131                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4132                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4133                                        "UID active uid=" + item.uid);
4134                                observer.onUidActive(item.uid);
4135                            }
4136                            if (VALIDATE_UID_STATES && i == 0) {
4137                                validateUid.idle = false;
4138                            }
4139                        }
4140                        if (change == UidRecord.CHANGE_GONE
4141                                || change == UidRecord.CHANGE_GONE_IDLE) {
4142                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4143                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4144                                        "UID gone uid=" + item.uid);
4145                                observer.onUidGone(item.uid);
4146                            }
4147                            if (VALIDATE_UID_STATES && i == 0) {
4148                                if (validateUid != null) {
4149                                    mValidateUids.remove(item.uid);
4150                                }
4151                            }
4152                        } else {
4153                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4154                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4155                                        "UID CHANGED uid=" + item.uid
4156                                                + ": " + item.processState);
4157                                observer.onUidStateChanged(item.uid, item.processState);
4158                            }
4159                            if (VALIDATE_UID_STATES && i == 0) {
4160                                validateUid.curProcState = validateUid.setProcState
4161                                        = item.processState;
4162                            }
4163                        }
4164                    }
4165                } catch (RemoteException e) {
4166                }
4167            }
4168        }
4169        mUidObservers.finishBroadcast();
4170
4171        synchronized (this) {
4172            for (int j=0; j<N; j++) {
4173                mAvailUidChanges.add(mActiveUidChanges[j]);
4174            }
4175        }
4176    }
4177
4178    @Override
4179    public final int startActivity(IApplicationThread caller, String callingPackage,
4180            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4181            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4182        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4183                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4184                UserHandle.getCallingUserId());
4185    }
4186
4187    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4188        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4189        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4190                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4191                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4192
4193        // TODO: Switch to user app stacks here.
4194        String mimeType = intent.getType();
4195        final Uri data = intent.getData();
4196        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4197            mimeType = getProviderMimeType(data, userId);
4198        }
4199        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4200
4201        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4202        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4203                null, 0, 0, null, null, null, null, false, userId, container, null);
4204    }
4205
4206    @Override
4207    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4208            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4209            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4210        enforceNotIsolatedCaller("startActivity");
4211        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4212                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4213        // TODO: Switch to user app stacks here.
4214        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4215                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4216                profilerInfo, null, null, bOptions, false, userId, null, null);
4217    }
4218
4219    @Override
4220    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4223            int userId) {
4224
4225        // This is very dangerous -- it allows you to perform a start activity (including
4226        // permission grants) as any app that may launch one of your own activities.  So
4227        // we will only allow this to be done from activities that are part of the core framework,
4228        // and then only when they are running as the system.
4229        final ActivityRecord sourceRecord;
4230        final int targetUid;
4231        final String targetPackage;
4232        synchronized (this) {
4233            if (resultTo == null) {
4234                throw new SecurityException("Must be called from an activity");
4235            }
4236            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4237            if (sourceRecord == null) {
4238                throw new SecurityException("Called with bad activity token: " + resultTo);
4239            }
4240            if (!sourceRecord.info.packageName.equals("android")) {
4241                throw new SecurityException(
4242                        "Must be called from an activity that is declared in the android package");
4243            }
4244            if (sourceRecord.app == null) {
4245                throw new SecurityException("Called without a process attached to activity");
4246            }
4247            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4248                // This is still okay, as long as this activity is running under the
4249                // uid of the original calling activity.
4250                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4251                    throw new SecurityException(
4252                            "Calling activity in uid " + sourceRecord.app.uid
4253                                    + " must be system uid or original calling uid "
4254                                    + sourceRecord.launchedFromUid);
4255                }
4256            }
4257            if (ignoreTargetSecurity) {
4258                if (intent.getComponent() == null) {
4259                    throw new SecurityException(
4260                            "Component must be specified with ignoreTargetSecurity");
4261                }
4262                if (intent.getSelector() != null) {
4263                    throw new SecurityException(
4264                            "Selector not allowed with ignoreTargetSecurity");
4265                }
4266            }
4267            targetUid = sourceRecord.launchedFromUid;
4268            targetPackage = sourceRecord.launchedFromPackage;
4269        }
4270
4271        if (userId == UserHandle.USER_NULL) {
4272            userId = UserHandle.getUserId(sourceRecord.app.uid);
4273        }
4274
4275        // TODO: Switch to user app stacks here.
4276        try {
4277            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4278                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4279                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4280            return ret;
4281        } catch (SecurityException e) {
4282            // XXX need to figure out how to propagate to original app.
4283            // A SecurityException here is generally actually a fault of the original
4284            // calling activity (such as a fairly granting permissions), so propagate it
4285            // back to them.
4286            /*
4287            StringBuilder msg = new StringBuilder();
4288            msg.append("While launching");
4289            msg.append(intent.toString());
4290            msg.append(": ");
4291            msg.append(e.getMessage());
4292            */
4293            throw e;
4294        }
4295    }
4296
4297    @Override
4298    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4300            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4301        enforceNotIsolatedCaller("startActivityAndWait");
4302        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4303                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4304        WaitResult res = new WaitResult();
4305        // TODO: Switch to user app stacks here.
4306        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4307                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4308                bOptions, false, userId, null, null);
4309        return res;
4310    }
4311
4312    @Override
4313    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4314            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4315            int startFlags, Configuration config, Bundle bOptions, int userId) {
4316        enforceNotIsolatedCaller("startActivityWithConfig");
4317        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4318                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4319        // TODO: Switch to user app stacks here.
4320        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4321                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4322                null, null, config, bOptions, false, userId, null, null);
4323        return ret;
4324    }
4325
4326    @Override
4327    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4328            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4329            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4330            throws TransactionTooLargeException {
4331        enforceNotIsolatedCaller("startActivityIntentSender");
4332        // Refuse possible leaked file descriptors
4333        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4334            throw new IllegalArgumentException("File descriptors passed in Intent");
4335        }
4336
4337        IIntentSender sender = intent.getTarget();
4338        if (!(sender instanceof PendingIntentRecord)) {
4339            throw new IllegalArgumentException("Bad PendingIntent object");
4340        }
4341
4342        PendingIntentRecord pir = (PendingIntentRecord)sender;
4343
4344        synchronized (this) {
4345            // If this is coming from the currently resumed activity, it is
4346            // effectively saying that app switches are allowed at this point.
4347            final ActivityStack stack = getFocusedStack();
4348            if (stack.mResumedActivity != null &&
4349                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4350                mAppSwitchesAllowedTime = 0;
4351            }
4352        }
4353        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4354                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4355        return ret;
4356    }
4357
4358    @Override
4359    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4360            Intent intent, String resolvedType, IVoiceInteractionSession session,
4361            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4362            Bundle bOptions, int userId) {
4363        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4364                != PackageManager.PERMISSION_GRANTED) {
4365            String msg = "Permission Denial: startVoiceActivity() from pid="
4366                    + Binder.getCallingPid()
4367                    + ", uid=" + Binder.getCallingUid()
4368                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4369            Slog.w(TAG, msg);
4370            throw new SecurityException(msg);
4371        }
4372        if (session == null || interactor == null) {
4373            throw new NullPointerException("null session or interactor");
4374        }
4375        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4376                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4377        // TODO: Switch to user app stacks here.
4378        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4379                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4380                null, bOptions, false, userId, null, null);
4381    }
4382
4383    @Override
4384    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4385            throws RemoteException {
4386        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4387        synchronized (this) {
4388            ActivityRecord activity = getFocusedStack().topActivity();
4389            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4390                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4391            }
4392            if (mRunningVoice != null || activity.task.voiceSession != null
4393                    || activity.voiceSession != null) {
4394                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4395                return;
4396            }
4397            if (activity.pendingVoiceInteractionStart) {
4398                Slog.w(TAG, "Pending start of voice interaction already.");
4399                return;
4400            }
4401            activity.pendingVoiceInteractionStart = true;
4402        }
4403        LocalServices.getService(VoiceInteractionManagerInternal.class)
4404                .startLocalVoiceInteraction(callingActivity, options);
4405    }
4406
4407    @Override
4408    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4409        LocalServices.getService(VoiceInteractionManagerInternal.class)
4410                .stopLocalVoiceInteraction(callingActivity);
4411    }
4412
4413    @Override
4414    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4415        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4416                .supportsLocalVoiceInteraction();
4417    }
4418
4419    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4420            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4421        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4422        if (activityToCallback == null) return;
4423        activityToCallback.setVoiceSessionLocked(voiceSession);
4424
4425        // Inform the activity
4426        try {
4427            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4428                    voiceInteractor);
4429            long token = Binder.clearCallingIdentity();
4430            try {
4431                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4432            } finally {
4433                Binder.restoreCallingIdentity(token);
4434            }
4435            // TODO: VI Should we cache the activity so that it's easier to find later
4436            // rather than scan through all the stacks and activities?
4437        } catch (RemoteException re) {
4438            activityToCallback.clearVoiceSessionLocked();
4439            // TODO: VI Should this terminate the voice session?
4440        }
4441    }
4442
4443    @Override
4444    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4445        synchronized (this) {
4446            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4447                if (keepAwake) {
4448                    mVoiceWakeLock.acquire();
4449                } else {
4450                    mVoiceWakeLock.release();
4451                }
4452            }
4453        }
4454    }
4455
4456    @Override
4457    public boolean startNextMatchingActivity(IBinder callingActivity,
4458            Intent intent, Bundle bOptions) {
4459        // Refuse possible leaked file descriptors
4460        if (intent != null && intent.hasFileDescriptors() == true) {
4461            throw new IllegalArgumentException("File descriptors passed in Intent");
4462        }
4463        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4464
4465        synchronized (this) {
4466            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4467            if (r == null) {
4468                ActivityOptions.abort(options);
4469                return false;
4470            }
4471            if (r.app == null || r.app.thread == null) {
4472                // The caller is not running...  d'oh!
4473                ActivityOptions.abort(options);
4474                return false;
4475            }
4476            intent = new Intent(intent);
4477            // The caller is not allowed to change the data.
4478            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4479            // And we are resetting to find the next component...
4480            intent.setComponent(null);
4481
4482            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4483
4484            ActivityInfo aInfo = null;
4485            try {
4486                List<ResolveInfo> resolves =
4487                    AppGlobals.getPackageManager().queryIntentActivities(
4488                            intent, r.resolvedType,
4489                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4490                            UserHandle.getCallingUserId()).getList();
4491
4492                // Look for the original activity in the list...
4493                final int N = resolves != null ? resolves.size() : 0;
4494                for (int i=0; i<N; i++) {
4495                    ResolveInfo rInfo = resolves.get(i);
4496                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4497                            && rInfo.activityInfo.name.equals(r.info.name)) {
4498                        // We found the current one...  the next matching is
4499                        // after it.
4500                        i++;
4501                        if (i<N) {
4502                            aInfo = resolves.get(i).activityInfo;
4503                        }
4504                        if (debug) {
4505                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4506                                    + "/" + r.info.name);
4507                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4508                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4509                        }
4510                        break;
4511                    }
4512                }
4513            } catch (RemoteException e) {
4514            }
4515
4516            if (aInfo == null) {
4517                // Nobody who is next!
4518                ActivityOptions.abort(options);
4519                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4520                return false;
4521            }
4522
4523            intent.setComponent(new ComponentName(
4524                    aInfo.applicationInfo.packageName, aInfo.name));
4525            intent.setFlags(intent.getFlags()&~(
4526                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4527                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4528                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4529                    Intent.FLAG_ACTIVITY_NEW_TASK));
4530
4531            // Okay now we need to start the new activity, replacing the
4532            // currently running activity.  This is a little tricky because
4533            // we want to start the new one as if the current one is finished,
4534            // but not finish the current one first so that there is no flicker.
4535            // And thus...
4536            final boolean wasFinishing = r.finishing;
4537            r.finishing = true;
4538
4539            // Propagate reply information over to the new activity.
4540            final ActivityRecord resultTo = r.resultTo;
4541            final String resultWho = r.resultWho;
4542            final int requestCode = r.requestCode;
4543            r.resultTo = null;
4544            if (resultTo != null) {
4545                resultTo.removeResultsLocked(r, resultWho, requestCode);
4546            }
4547
4548            final long origId = Binder.clearCallingIdentity();
4549            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4550                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4551                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4552                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4553                    false, false, null, null, null);
4554            Binder.restoreCallingIdentity(origId);
4555
4556            r.finishing = wasFinishing;
4557            if (res != ActivityManager.START_SUCCESS) {
4558                return false;
4559            }
4560            return true;
4561        }
4562    }
4563
4564    @Override
4565    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4566        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4567            String msg = "Permission Denial: startActivityFromRecents called without " +
4568                    START_TASKS_FROM_RECENTS;
4569            Slog.w(TAG, msg);
4570            throw new SecurityException(msg);
4571        }
4572        final long origId = Binder.clearCallingIdentity();
4573        try {
4574            synchronized (this) {
4575                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4576            }
4577        } finally {
4578            Binder.restoreCallingIdentity(origId);
4579        }
4580    }
4581
4582    final int startActivityInPackage(int uid, String callingPackage,
4583            Intent intent, String resolvedType, IBinder resultTo,
4584            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4585            IActivityContainer container, TaskRecord inTask) {
4586
4587        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4589
4590        // TODO: Switch to user app stacks here.
4591        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4592                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4593                null, null, null, bOptions, false, userId, container, inTask);
4594        return ret;
4595    }
4596
4597    @Override
4598    public final int startActivities(IApplicationThread caller, String callingPackage,
4599            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4600            int userId) {
4601        enforceNotIsolatedCaller("startActivities");
4602        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4606                resolvedTypes, resultTo, bOptions, userId);
4607        return ret;
4608    }
4609
4610    final int startActivitiesInPackage(int uid, String callingPackage,
4611            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4612            Bundle bOptions, int userId) {
4613
4614        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4615                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4616        // TODO: Switch to user app stacks here.
4617        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4618                resultTo, bOptions, userId);
4619        return ret;
4620    }
4621
4622    @Override
4623    public void reportActivityFullyDrawn(IBinder token) {
4624        synchronized (this) {
4625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4626            if (r == null) {
4627                return;
4628            }
4629            r.reportFullyDrawnLocked();
4630        }
4631    }
4632
4633    @Override
4634    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4635        synchronized (this) {
4636            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4637            if (r == null) {
4638                return;
4639            }
4640            TaskRecord task = r.task;
4641            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4642                // Fixed screen orientation isn't supported when activities aren't in full screen
4643                // mode.
4644                return;
4645            }
4646            final long origId = Binder.clearCallingIdentity();
4647            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4648            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4649                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4650            if (config != null) {
4651                r.frozenBeforeDestroy = true;
4652                if (!updateConfigurationLocked(config, r, false)) {
4653                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4654                }
4655            }
4656            Binder.restoreCallingIdentity(origId);
4657        }
4658    }
4659
4660    @Override
4661    public int getRequestedOrientation(IBinder token) {
4662        synchronized (this) {
4663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4664            if (r == null) {
4665                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4666            }
4667            return mWindowManager.getAppOrientation(r.appToken);
4668        }
4669    }
4670
4671    /**
4672     * This is the internal entry point for handling Activity.finish().
4673     *
4674     * @param token The Binder token referencing the Activity we want to finish.
4675     * @param resultCode Result code, if any, from this Activity.
4676     * @param resultData Result data (Intent), if any, from this Activity.
4677     * @param finishTask Whether to finish the task associated with this Activity.
4678     *
4679     * @return Returns true if the activity successfully finished, or false if it is still running.
4680     */
4681    @Override
4682    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4683            int finishTask) {
4684        // Refuse possible leaked file descriptors
4685        if (resultData != null && resultData.hasFileDescriptors() == true) {
4686            throw new IllegalArgumentException("File descriptors passed in Intent");
4687        }
4688
4689        synchronized(this) {
4690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4691            if (r == null) {
4692                return true;
4693            }
4694            // Keep track of the root activity of the task before we finish it
4695            TaskRecord tr = r.task;
4696            ActivityRecord rootR = tr.getRootActivity();
4697            if (rootR == null) {
4698                Slog.w(TAG, "Finishing task with all activities already finished");
4699            }
4700            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4701            // finish.
4702            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4703                    mStackSupervisor.isLastLockedTask(tr)) {
4704                Slog.i(TAG, "Not finishing task in lock task mode");
4705                mStackSupervisor.showLockTaskToast();
4706                return false;
4707            }
4708            if (mController != null) {
4709                // Find the first activity that is not finishing.
4710                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4711                if (next != null) {
4712                    // ask watcher if this is allowed
4713                    boolean resumeOK = true;
4714                    try {
4715                        resumeOK = mController.activityResuming(next.packageName);
4716                    } catch (RemoteException e) {
4717                        mController = null;
4718                        Watchdog.getInstance().setActivityController(null);
4719                    }
4720
4721                    if (!resumeOK) {
4722                        Slog.i(TAG, "Not finishing activity because controller resumed");
4723                        return false;
4724                    }
4725                }
4726            }
4727            final long origId = Binder.clearCallingIdentity();
4728            try {
4729                boolean res;
4730                final boolean finishWithRootActivity =
4731                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4732                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4733                        || (finishWithRootActivity && r == rootR)) {
4734                    // If requested, remove the task that is associated to this activity only if it
4735                    // was the root activity in the task. The result code and data is ignored
4736                    // because we don't support returning them across task boundaries. Also, to
4737                    // keep backwards compatibility we remove the task from recents when finishing
4738                    // task with root activity.
4739                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4740                    if (!res) {
4741                        Slog.i(TAG, "Removing task failed to finish activity");
4742                    }
4743                } else {
4744                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4745                            resultData, "app-request", true);
4746                    if (!res) {
4747                        Slog.i(TAG, "Failed to finish by app-request");
4748                    }
4749                }
4750                return res;
4751            } finally {
4752                Binder.restoreCallingIdentity(origId);
4753            }
4754        }
4755    }
4756
4757    @Override
4758    public final void finishHeavyWeightApp() {
4759        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4760                != PackageManager.PERMISSION_GRANTED) {
4761            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4762                    + Binder.getCallingPid()
4763                    + ", uid=" + Binder.getCallingUid()
4764                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4765            Slog.w(TAG, msg);
4766            throw new SecurityException(msg);
4767        }
4768
4769        synchronized(this) {
4770            if (mHeavyWeightProcess == null) {
4771                return;
4772            }
4773
4774            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4775            for (int i = 0; i < activities.size(); i++) {
4776                ActivityRecord r = activities.get(i);
4777                if (!r.finishing && r.isInStackLocked()) {
4778                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4779                            null, "finish-heavy", true);
4780                }
4781            }
4782
4783            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4784                    mHeavyWeightProcess.userId, 0));
4785            mHeavyWeightProcess = null;
4786        }
4787    }
4788
4789    @Override
4790    public void crashApplication(int uid, int initialPid, String packageName,
4791            String message) {
4792        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4793                != PackageManager.PERMISSION_GRANTED) {
4794            String msg = "Permission Denial: crashApplication() from pid="
4795                    + Binder.getCallingPid()
4796                    + ", uid=" + Binder.getCallingUid()
4797                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4798            Slog.w(TAG, msg);
4799            throw new SecurityException(msg);
4800        }
4801
4802        synchronized(this) {
4803            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4804        }
4805    }
4806
4807    @Override
4808    public final void finishSubActivity(IBinder token, String resultWho,
4809            int requestCode) {
4810        synchronized(this) {
4811            final long origId = Binder.clearCallingIdentity();
4812            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4813            if (r != null) {
4814                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4815            }
4816            Binder.restoreCallingIdentity(origId);
4817        }
4818    }
4819
4820    @Override
4821    public boolean finishActivityAffinity(IBinder token) {
4822        synchronized(this) {
4823            final long origId = Binder.clearCallingIdentity();
4824            try {
4825                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4826                if (r == null) {
4827                    return false;
4828                }
4829
4830                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4831                // can finish.
4832                final TaskRecord task = r.task;
4833                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4834                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4835                    mStackSupervisor.showLockTaskToast();
4836                    return false;
4837                }
4838                return task.stack.finishActivityAffinityLocked(r);
4839            } finally {
4840                Binder.restoreCallingIdentity(origId);
4841            }
4842        }
4843    }
4844
4845    @Override
4846    public void finishVoiceTask(IVoiceInteractionSession session) {
4847        synchronized (this) {
4848            final long origId = Binder.clearCallingIdentity();
4849            try {
4850                // TODO: VI Consider treating local voice interactions and voice tasks
4851                // differently here
4852                mStackSupervisor.finishVoiceTask(session);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857
4858    }
4859
4860    @Override
4861    public boolean releaseActivityInstance(IBinder token) {
4862        synchronized(this) {
4863            final long origId = Binder.clearCallingIdentity();
4864            try {
4865                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866                if (r == null) {
4867                    return false;
4868                }
4869                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4870            } finally {
4871                Binder.restoreCallingIdentity(origId);
4872            }
4873        }
4874    }
4875
4876    @Override
4877    public void releaseSomeActivities(IApplicationThread appInt) {
4878        synchronized(this) {
4879            final long origId = Binder.clearCallingIdentity();
4880            try {
4881                ProcessRecord app = getRecordForAppLocked(appInt);
4882                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public boolean willActivityBeVisible(IBinder token) {
4891        synchronized(this) {
4892            ActivityStack stack = ActivityRecord.getStackLocked(token);
4893            if (stack != null) {
4894                return stack.willActivityBeVisibleLocked(token);
4895            }
4896            return false;
4897        }
4898    }
4899
4900    @Override
4901    public void overridePendingTransition(IBinder token, String packageName,
4902            int enterAnim, int exitAnim) {
4903        synchronized(this) {
4904            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4905            if (self == null) {
4906                return;
4907            }
4908
4909            final long origId = Binder.clearCallingIdentity();
4910
4911            if (self.state == ActivityState.RESUMED
4912                    || self.state == ActivityState.PAUSING) {
4913                mWindowManager.overridePendingAppTransition(packageName,
4914                        enterAnim, exitAnim, null);
4915            }
4916
4917            Binder.restoreCallingIdentity(origId);
4918        }
4919    }
4920
4921    /**
4922     * Main function for removing an existing process from the activity manager
4923     * as a result of that process going away.  Clears out all connections
4924     * to the process.
4925     */
4926    private final void handleAppDiedLocked(ProcessRecord app,
4927            boolean restarting, boolean allowRestart) {
4928        int pid = app.pid;
4929        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4930        if (!kept && !restarting) {
4931            removeLruProcessLocked(app);
4932            if (pid > 0) {
4933                ProcessList.remove(pid);
4934            }
4935        }
4936
4937        if (mProfileProc == app) {
4938            clearProfilerLocked();
4939        }
4940
4941        // Remove this application's activities from active lists.
4942        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4943
4944        app.activities.clear();
4945
4946        if (app.instrumentationClass != null) {
4947            Slog.w(TAG, "Crash of app " + app.processName
4948                  + " running instrumentation " + app.instrumentationClass);
4949            Bundle info = new Bundle();
4950            info.putString("shortMsg", "Process crashed.");
4951            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4952        }
4953
4954        if (!restarting && hasVisibleActivities
4955                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4956            // If there was nothing to resume, and we are not already restarting this process, but
4957            // there is a visible activity that is hosted by the process...  then make sure all
4958            // visible activities are running, taking care of restarting this process.
4959            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4960        }
4961    }
4962
4963    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4964        IBinder threadBinder = thread.asBinder();
4965        // Find the application record.
4966        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967            ProcessRecord rec = mLruProcesses.get(i);
4968            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4969                return i;
4970            }
4971        }
4972        return -1;
4973    }
4974
4975    final ProcessRecord getRecordForAppLocked(
4976            IApplicationThread thread) {
4977        if (thread == null) {
4978            return null;
4979        }
4980
4981        int appIndex = getLRURecordIndexForAppLocked(thread);
4982        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4983    }
4984
4985    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4986        // If there are no longer any background processes running,
4987        // and the app that died was not running instrumentation,
4988        // then tell everyone we are now low on memory.
4989        boolean haveBg = false;
4990        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4991            ProcessRecord rec = mLruProcesses.get(i);
4992            if (rec.thread != null
4993                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4994                haveBg = true;
4995                break;
4996            }
4997        }
4998
4999        if (!haveBg) {
5000            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5001            if (doReport) {
5002                long now = SystemClock.uptimeMillis();
5003                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5004                    doReport = false;
5005                } else {
5006                    mLastMemUsageReportTime = now;
5007                }
5008            }
5009            final ArrayList<ProcessMemInfo> memInfos
5010                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5011            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5012            long now = SystemClock.uptimeMillis();
5013            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5014                ProcessRecord rec = mLruProcesses.get(i);
5015                if (rec == dyingProc || rec.thread == null) {
5016                    continue;
5017                }
5018                if (doReport) {
5019                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5020                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5021                }
5022                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5023                    // The low memory report is overriding any current
5024                    // state for a GC request.  Make sure to do
5025                    // heavy/important/visible/foreground processes first.
5026                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5027                        rec.lastRequestedGc = 0;
5028                    } else {
5029                        rec.lastRequestedGc = rec.lastLowMemory;
5030                    }
5031                    rec.reportLowMemory = true;
5032                    rec.lastLowMemory = now;
5033                    mProcessesToGc.remove(rec);
5034                    addProcessToGcListLocked(rec);
5035                }
5036            }
5037            if (doReport) {
5038                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5039                mHandler.sendMessage(msg);
5040            }
5041            scheduleAppGcsLocked();
5042        }
5043    }
5044
5045    final void appDiedLocked(ProcessRecord app) {
5046       appDiedLocked(app, app.pid, app.thread, false);
5047    }
5048
5049    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5050            boolean fromBinderDied) {
5051        // First check if this ProcessRecord is actually active for the pid.
5052        synchronized (mPidsSelfLocked) {
5053            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5054            if (curProc != app) {
5055                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5056                return;
5057            }
5058        }
5059
5060        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5061        synchronized (stats) {
5062            stats.noteProcessDiedLocked(app.info.uid, pid);
5063        }
5064
5065        if (!app.killed) {
5066            if (!fromBinderDied) {
5067                Process.killProcessQuiet(pid);
5068            }
5069            killProcessGroup(app.uid, pid);
5070            app.killed = true;
5071        }
5072
5073        // Clean up already done if the process has been re-started.
5074        if (app.pid == pid && app.thread != null &&
5075                app.thread.asBinder() == thread.asBinder()) {
5076            boolean doLowMem = app.instrumentationClass == null;
5077            boolean doOomAdj = doLowMem;
5078            if (!app.killedByAm) {
5079                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5080                        + ") has died");
5081                mAllowLowerMemLevel = true;
5082            } else {
5083                // Note that we always want to do oom adj to update our state with the
5084                // new number of procs.
5085                mAllowLowerMemLevel = false;
5086                doLowMem = false;
5087            }
5088            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5089            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5090                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5091            handleAppDiedLocked(app, false, true);
5092
5093            if (doOomAdj) {
5094                updateOomAdjLocked();
5095            }
5096            if (doLowMem) {
5097                doLowMemReportIfNeededLocked(app);
5098            }
5099        } else if (app.pid != pid) {
5100            // A new process has already been started.
5101            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5102                    + ") has died and restarted (pid " + app.pid + ").");
5103            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5104        } else if (DEBUG_PROCESSES) {
5105            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5106                    + thread.asBinder());
5107        }
5108    }
5109
5110    /**
5111     * If a stack trace dump file is configured, dump process stack traces.
5112     * @param clearTraces causes the dump file to be erased prior to the new
5113     *    traces being written, if true; when false, the new traces will be
5114     *    appended to any existing file content.
5115     * @param firstPids of dalvik VM processes to dump stack traces for first
5116     * @param lastPids of dalvik VM processes to dump stack traces for last
5117     * @param nativeProcs optional list of native process names to dump stack crawls
5118     * @return file containing stack traces, or null if no dump file is configured
5119     */
5120    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5121            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5122        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5123        if (tracesPath == null || tracesPath.length() == 0) {
5124            return null;
5125        }
5126
5127        File tracesFile = new File(tracesPath);
5128        try {
5129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5130            tracesFile.createNewFile();
5131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5132        } catch (IOException e) {
5133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5134            return null;
5135        }
5136
5137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5138        return tracesFile;
5139    }
5140
5141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5143        // Use a FileObserver to detect when traces finish writing.
5144        // The order of traces is considered important to maintain for legibility.
5145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5146            @Override
5147            public synchronized void onEvent(int event, String path) { notify(); }
5148        };
5149
5150        try {
5151            observer.startWatching();
5152
5153            // First collect all of the stacks of the most important pids.
5154            if (firstPids != null) {
5155                try {
5156                    int num = firstPids.size();
5157                    for (int i = 0; i < num; i++) {
5158                        synchronized (observer) {
5159                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5160                                    + firstPids.get(i));
5161                            final long sime = SystemClock.elapsedRealtime();
5162                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5163                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5164                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5165                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5166                        }
5167                    }
5168                } catch (InterruptedException e) {
5169                    Slog.wtf(TAG, e);
5170                }
5171            }
5172
5173            // Next collect the stacks of the native pids
5174            if (nativeProcs != null) {
5175                int[] pids = Process.getPidsForCommands(nativeProcs);
5176                if (pids != null) {
5177                    for (int pid : pids) {
5178                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5179                        final long sime = SystemClock.elapsedRealtime();
5180                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5181                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5182                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5183                    }
5184                }
5185            }
5186
5187            // Lastly, measure CPU usage.
5188            if (processCpuTracker != null) {
5189                processCpuTracker.init();
5190                System.gc();
5191                processCpuTracker.update();
5192                try {
5193                    synchronized (processCpuTracker) {
5194                        processCpuTracker.wait(500); // measure over 1/2 second.
5195                    }
5196                } catch (InterruptedException e) {
5197                }
5198                processCpuTracker.update();
5199
5200                // We'll take the stack crawls of just the top apps using CPU.
5201                final int N = processCpuTracker.countWorkingStats();
5202                int numProcs = 0;
5203                for (int i=0; i<N && numProcs<5; i++) {
5204                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5205                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5206                        numProcs++;
5207                        try {
5208                            synchronized (observer) {
5209                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5210                                        + stats.pid);
5211                                final long stime = SystemClock.elapsedRealtime();
5212                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5213                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5214                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5215                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5216                            }
5217                        } catch (InterruptedException e) {
5218                            Slog.wtf(TAG, e);
5219                        }
5220                    } else if (DEBUG_ANR) {
5221                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5222                                + stats.pid);
5223                    }
5224                }
5225            }
5226        } finally {
5227            observer.stopWatching();
5228        }
5229    }
5230
5231    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5232        if (true || IS_USER_BUILD) {
5233            return;
5234        }
5235        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5236        if (tracesPath == null || tracesPath.length() == 0) {
5237            return;
5238        }
5239
5240        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5241        StrictMode.allowThreadDiskWrites();
5242        try {
5243            final File tracesFile = new File(tracesPath);
5244            final File tracesDir = tracesFile.getParentFile();
5245            final File tracesTmp = new File(tracesDir, "__tmp__");
5246            try {
5247                if (tracesFile.exists()) {
5248                    tracesTmp.delete();
5249                    tracesFile.renameTo(tracesTmp);
5250                }
5251                StringBuilder sb = new StringBuilder();
5252                Time tobj = new Time();
5253                tobj.set(System.currentTimeMillis());
5254                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5255                sb.append(": ");
5256                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5257                sb.append(" since ");
5258                sb.append(msg);
5259                FileOutputStream fos = new FileOutputStream(tracesFile);
5260                fos.write(sb.toString().getBytes());
5261                if (app == null) {
5262                    fos.write("\n*** No application process!".getBytes());
5263                }
5264                fos.close();
5265                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5266            } catch (IOException e) {
5267                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5268                return;
5269            }
5270
5271            if (app != null) {
5272                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5273                firstPids.add(app.pid);
5274                dumpStackTraces(tracesPath, firstPids, null, null, null);
5275            }
5276
5277            File lastTracesFile = null;
5278            File curTracesFile = null;
5279            for (int i=9; i>=0; i--) {
5280                String name = String.format(Locale.US, "slow%02d.txt", i);
5281                curTracesFile = new File(tracesDir, name);
5282                if (curTracesFile.exists()) {
5283                    if (lastTracesFile != null) {
5284                        curTracesFile.renameTo(lastTracesFile);
5285                    } else {
5286                        curTracesFile.delete();
5287                    }
5288                }
5289                lastTracesFile = curTracesFile;
5290            }
5291            tracesFile.renameTo(curTracesFile);
5292            if (tracesTmp.exists()) {
5293                tracesTmp.renameTo(tracesFile);
5294            }
5295        } finally {
5296            StrictMode.setThreadPolicy(oldPolicy);
5297        }
5298    }
5299
5300    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5301        if (!mLaunchWarningShown) {
5302            mLaunchWarningShown = true;
5303            mUiHandler.post(new Runnable() {
5304                @Override
5305                public void run() {
5306                    synchronized (ActivityManagerService.this) {
5307                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5308                        d.show();
5309                        mUiHandler.postDelayed(new Runnable() {
5310                            @Override
5311                            public void run() {
5312                                synchronized (ActivityManagerService.this) {
5313                                    d.dismiss();
5314                                    mLaunchWarningShown = false;
5315                                }
5316                            }
5317                        }, 4000);
5318                    }
5319                }
5320            });
5321        }
5322    }
5323
5324    @Override
5325    public boolean clearApplicationUserData(final String packageName,
5326            final IPackageDataObserver observer, int userId) {
5327        enforceNotIsolatedCaller("clearApplicationUserData");
5328        int uid = Binder.getCallingUid();
5329        int pid = Binder.getCallingPid();
5330        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5331                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5332
5333        final DevicePolicyManagerInternal dpmi = LocalServices
5334                .getService(DevicePolicyManagerInternal.class);
5335        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5336            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5337        }
5338
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            int pkgUid = -1;
5343            synchronized(this) {
5344                try {
5345                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5346                } catch (RemoteException e) {
5347                }
5348                if (pkgUid == -1) {
5349                    Slog.w(TAG, "Invalid packageName: " + packageName);
5350                    if (observer != null) {
5351                        try {
5352                            observer.onRemoveCompleted(packageName, false);
5353                        } catch (RemoteException e) {
5354                            Slog.i(TAG, "Observer no longer exists.");
5355                        }
5356                    }
5357                    return false;
5358                }
5359                if (uid == pkgUid || checkComponentPermission(
5360                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5361                        pid, uid, -1, true)
5362                        == PackageManager.PERMISSION_GRANTED) {
5363                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5364                } else {
5365                    throw new SecurityException("PID " + pid + " does not have permission "
5366                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5367                                    + " of package " + packageName);
5368                }
5369
5370                // Remove all tasks match the cleared application package and user
5371                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5372                    final TaskRecord tr = mRecentTasks.get(i);
5373                    final String taskPackageName =
5374                            tr.getBaseIntent().getComponent().getPackageName();
5375                    if (tr.userId != userId) continue;
5376                    if (!taskPackageName.equals(packageName)) continue;
5377                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5378                }
5379            }
5380
5381            try {
5382                // Clear application user data
5383                pm.clearApplicationUserData(packageName, observer, userId);
5384
5385                synchronized(this) {
5386                    // Remove all permissions granted from/to this package
5387                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5388                }
5389
5390                // Remove all zen rules created by this package; revoke it's zen access.
5391                INotificationManager inm = NotificationManager.getService();
5392                inm.removeAutomaticZenRules(packageName);
5393                inm.setNotificationPolicyAccessGranted(packageName, false);
5394
5395                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5396                        Uri.fromParts("package", packageName, null));
5397                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5398                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5399                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5400                        null, null, 0, null, null, null, null, false, false, userId);
5401            } catch (RemoteException e) {
5402            }
5403        } finally {
5404            Binder.restoreCallingIdentity(callingId);
5405        }
5406        return true;
5407    }
5408
5409    @Override
5410    public void killBackgroundProcesses(final String packageName, int userId) {
5411        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5412                != PackageManager.PERMISSION_GRANTED &&
5413                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5414                        != PackageManager.PERMISSION_GRANTED) {
5415            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5416                    + Binder.getCallingPid()
5417                    + ", uid=" + Binder.getCallingUid()
5418                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5419            Slog.w(TAG, msg);
5420            throw new SecurityException(msg);
5421        }
5422
5423        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5424                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5425        long callingId = Binder.clearCallingIdentity();
5426        try {
5427            IPackageManager pm = AppGlobals.getPackageManager();
5428            synchronized(this) {
5429                int appId = -1;
5430                try {
5431                    appId = UserHandle.getAppId(
5432                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5433                } catch (RemoteException e) {
5434                }
5435                if (appId == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    return;
5438                }
5439                killPackageProcessesLocked(packageName, appId, userId,
5440                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5441            }
5442        } finally {
5443            Binder.restoreCallingIdentity(callingId);
5444        }
5445    }
5446
5447    @Override
5448    public void killAllBackgroundProcesses() {
5449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5450                != PackageManager.PERMISSION_GRANTED) {
5451            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5452                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5453                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5454            Slog.w(TAG, msg);
5455            throw new SecurityException(msg);
5456        }
5457
5458        final long callingId = Binder.clearCallingIdentity();
5459        try {
5460            synchronized (this) {
5461                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5462                final int NP = mProcessNames.getMap().size();
5463                for (int ip = 0; ip < NP; ip++) {
5464                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5465                    final int NA = apps.size();
5466                    for (int ia = 0; ia < NA; ia++) {
5467                        final ProcessRecord app = apps.valueAt(ia);
5468                        if (app.persistent) {
5469                            // We don't kill persistent processes.
5470                            continue;
5471                        }
5472                        if (app.removed) {
5473                            procs.add(app);
5474                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5475                            app.removed = true;
5476                            procs.add(app);
5477                        }
5478                    }
5479                }
5480
5481                final int N = procs.size();
5482                for (int i = 0; i < N; i++) {
5483                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5484                }
5485
5486                mAllowLowerMemLevel = true;
5487
5488                updateOomAdjLocked();
5489                doLowMemReportIfNeededLocked(null);
5490            }
5491        } finally {
5492            Binder.restoreCallingIdentity(callingId);
5493        }
5494    }
5495
5496    /**
5497     * Kills all background processes, except those matching any of the
5498     * specified properties.
5499     *
5500     * @param minTargetSdk the target SDK version at or above which to preserve
5501     *                     processes, or {@code -1} to ignore the target SDK
5502     * @param maxProcState the process state at or below which to preserve
5503     *                     processes, or {@code -1} to ignore the process state
5504     */
5505    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5506        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5507                != PackageManager.PERMISSION_GRANTED) {
5508            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5509                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5510                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5511            Slog.w(TAG, msg);
5512            throw new SecurityException(msg);
5513        }
5514
5515        final long callingId = Binder.clearCallingIdentity();
5516        try {
5517            synchronized (this) {
5518                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5519                final int NP = mProcessNames.getMap().size();
5520                for (int ip = 0; ip < NP; ip++) {
5521                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5522                    final int NA = apps.size();
5523                    for (int ia = 0; ia < NA; ia++) {
5524                        final ProcessRecord app = apps.valueAt(ia);
5525                        if (app.removed) {
5526                            procs.add(app);
5527                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5528                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5529                            app.removed = true;
5530                            procs.add(app);
5531                        }
5532                    }
5533                }
5534
5535                final int N = procs.size();
5536                for (int i = 0; i < N; i++) {
5537                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5538                }
5539            }
5540        } finally {
5541            Binder.restoreCallingIdentity(callingId);
5542        }
5543    }
5544
5545    @Override
5546    public void forceStopPackage(final String packageName, int userId) {
5547        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5548                != PackageManager.PERMISSION_GRANTED) {
5549            String msg = "Permission Denial: forceStopPackage() from pid="
5550                    + Binder.getCallingPid()
5551                    + ", uid=" + Binder.getCallingUid()
5552                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5553            Slog.w(TAG, msg);
5554            throw new SecurityException(msg);
5555        }
5556        final int callingPid = Binder.getCallingPid();
5557        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5558                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5559        long callingId = Binder.clearCallingIdentity();
5560        try {
5561            IPackageManager pm = AppGlobals.getPackageManager();
5562            synchronized(this) {
5563                int[] users = userId == UserHandle.USER_ALL
5564                        ? mUserController.getUsers() : new int[] { userId };
5565                for (int user : users) {
5566                    int pkgUid = -1;
5567                    try {
5568                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5569                                user);
5570                    } catch (RemoteException e) {
5571                    }
5572                    if (pkgUid == -1) {
5573                        Slog.w(TAG, "Invalid packageName: " + packageName);
5574                        continue;
5575                    }
5576                    try {
5577                        pm.setPackageStoppedState(packageName, true, user);
5578                    } catch (RemoteException e) {
5579                    } catch (IllegalArgumentException e) {
5580                        Slog.w(TAG, "Failed trying to unstop package "
5581                                + packageName + ": " + e);
5582                    }
5583                    if (mUserController.isUserRunningLocked(user, 0)) {
5584                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5585                    }
5586                }
5587            }
5588        } finally {
5589            Binder.restoreCallingIdentity(callingId);
5590        }
5591    }
5592
5593    @Override
5594    public void addPackageDependency(String packageName) {
5595        synchronized (this) {
5596            int callingPid = Binder.getCallingPid();
5597            if (callingPid == Process.myPid()) {
5598                //  Yeah, um, no.
5599                return;
5600            }
5601            ProcessRecord proc;
5602            synchronized (mPidsSelfLocked) {
5603                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5604            }
5605            if (proc != null) {
5606                if (proc.pkgDeps == null) {
5607                    proc.pkgDeps = new ArraySet<String>(1);
5608                }
5609                proc.pkgDeps.add(packageName);
5610            }
5611        }
5612    }
5613
5614    /*
5615     * The pkg name and app id have to be specified.
5616     */
5617    @Override
5618    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5619        if (pkg == null) {
5620            return;
5621        }
5622        // Make sure the uid is valid.
5623        if (appid < 0) {
5624            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5625            return;
5626        }
5627        int callerUid = Binder.getCallingUid();
5628        // Only the system server can kill an application
5629        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5630            // Post an aysnc message to kill the application
5631            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5632            msg.arg1 = appid;
5633            msg.arg2 = 0;
5634            Bundle bundle = new Bundle();
5635            bundle.putString("pkg", pkg);
5636            bundle.putString("reason", reason);
5637            msg.obj = bundle;
5638            mHandler.sendMessage(msg);
5639        } else {
5640            throw new SecurityException(callerUid + " cannot kill pkg: " +
5641                    pkg);
5642        }
5643    }
5644
5645    @Override
5646    public void closeSystemDialogs(String reason) {
5647        enforceNotIsolatedCaller("closeSystemDialogs");
5648
5649        final int pid = Binder.getCallingPid();
5650        final int uid = Binder.getCallingUid();
5651        final long origId = Binder.clearCallingIdentity();
5652        try {
5653            synchronized (this) {
5654                // Only allow this from foreground processes, so that background
5655                // applications can't abuse it to prevent system UI from being shown.
5656                if (uid >= Process.FIRST_APPLICATION_UID) {
5657                    ProcessRecord proc;
5658                    synchronized (mPidsSelfLocked) {
5659                        proc = mPidsSelfLocked.get(pid);
5660                    }
5661                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5662                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5663                                + " from background process " + proc);
5664                        return;
5665                    }
5666                }
5667                closeSystemDialogsLocked(reason);
5668            }
5669        } finally {
5670            Binder.restoreCallingIdentity(origId);
5671        }
5672    }
5673
5674    void closeSystemDialogsLocked(String reason) {
5675        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5676        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5677                | Intent.FLAG_RECEIVER_FOREGROUND);
5678        if (reason != null) {
5679            intent.putExtra("reason", reason);
5680        }
5681        mWindowManager.closeSystemDialogs(reason);
5682
5683        mStackSupervisor.closeSystemDialogsLocked();
5684
5685        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5686                AppOpsManager.OP_NONE, null, false, false,
5687                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5688    }
5689
5690    @Override
5691    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5692        enforceNotIsolatedCaller("getProcessMemoryInfo");
5693        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5694        for (int i=pids.length-1; i>=0; i--) {
5695            ProcessRecord proc;
5696            int oomAdj;
5697            synchronized (this) {
5698                synchronized (mPidsSelfLocked) {
5699                    proc = mPidsSelfLocked.get(pids[i]);
5700                    oomAdj = proc != null ? proc.setAdj : 0;
5701                }
5702            }
5703            infos[i] = new Debug.MemoryInfo();
5704            Debug.getMemoryInfo(pids[i], infos[i]);
5705            if (proc != null) {
5706                synchronized (this) {
5707                    if (proc.thread != null && proc.setAdj == oomAdj) {
5708                        // Record this for posterity if the process has been stable.
5709                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5710                                infos[i].getTotalUss(), false, proc.pkgList);
5711                    }
5712                }
5713            }
5714        }
5715        return infos;
5716    }
5717
5718    @Override
5719    public long[] getProcessPss(int[] pids) {
5720        enforceNotIsolatedCaller("getProcessPss");
5721        long[] pss = new long[pids.length];
5722        for (int i=pids.length-1; i>=0; i--) {
5723            ProcessRecord proc;
5724            int oomAdj;
5725            synchronized (this) {
5726                synchronized (mPidsSelfLocked) {
5727                    proc = mPidsSelfLocked.get(pids[i]);
5728                    oomAdj = proc != null ? proc.setAdj : 0;
5729                }
5730            }
5731            long[] tmpUss = new long[1];
5732            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5733            if (proc != null) {
5734                synchronized (this) {
5735                    if (proc.thread != null && proc.setAdj == oomAdj) {
5736                        // Record this for posterity if the process has been stable.
5737                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5738                    }
5739                }
5740            }
5741        }
5742        return pss;
5743    }
5744
5745    @Override
5746    public void killApplicationProcess(String processName, int uid) {
5747        if (processName == null) {
5748            return;
5749        }
5750
5751        int callerUid = Binder.getCallingUid();
5752        // Only the system server can kill an application
5753        if (callerUid == Process.SYSTEM_UID) {
5754            synchronized (this) {
5755                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5756                if (app != null && app.thread != null) {
5757                    try {
5758                        app.thread.scheduleSuicide();
5759                    } catch (RemoteException e) {
5760                        // If the other end already died, then our work here is done.
5761                    }
5762                } else {
5763                    Slog.w(TAG, "Process/uid not found attempting kill of "
5764                            + processName + " / " + uid);
5765                }
5766            }
5767        } else {
5768            throw new SecurityException(callerUid + " cannot kill app process: " +
5769                    processName);
5770        }
5771    }
5772
5773    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5774        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5775                false, true, false, false, UserHandle.getUserId(uid), reason);
5776        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5777                Uri.fromParts("package", packageName, null));
5778        if (!mProcessesReady) {
5779            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5780                    | Intent.FLAG_RECEIVER_FOREGROUND);
5781        }
5782        intent.putExtra(Intent.EXTRA_UID, uid);
5783        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5784        broadcastIntentLocked(null, null, intent,
5785                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5786                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5787    }
5788
5789
5790    private final boolean killPackageProcessesLocked(String packageName, int appId,
5791            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5792            boolean doit, boolean evenPersistent, String reason) {
5793        ArrayList<ProcessRecord> procs = new ArrayList<>();
5794
5795        // Remove all processes this package may have touched: all with the
5796        // same UID (except for the system or root user), and all whose name
5797        // matches the package name.
5798        final int NP = mProcessNames.getMap().size();
5799        for (int ip=0; ip<NP; ip++) {
5800            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5801            final int NA = apps.size();
5802            for (int ia=0; ia<NA; ia++) {
5803                ProcessRecord app = apps.valueAt(ia);
5804                if (app.persistent && !evenPersistent) {
5805                    // we don't kill persistent processes
5806                    continue;
5807                }
5808                if (app.removed) {
5809                    if (doit) {
5810                        procs.add(app);
5811                    }
5812                    continue;
5813                }
5814
5815                // Skip process if it doesn't meet our oom adj requirement.
5816                if (app.setAdj < minOomAdj) {
5817                    continue;
5818                }
5819
5820                // If no package is specified, we call all processes under the
5821                // give user id.
5822                if (packageName == null) {
5823                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5824                        continue;
5825                    }
5826                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5827                        continue;
5828                    }
5829                // Package has been specified, we want to hit all processes
5830                // that match it.  We need to qualify this by the processes
5831                // that are running under the specified app and user ID.
5832                } else {
5833                    final boolean isDep = app.pkgDeps != null
5834                            && app.pkgDeps.contains(packageName);
5835                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5836                        continue;
5837                    }
5838                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5839                        continue;
5840                    }
5841                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5842                        continue;
5843                    }
5844                }
5845
5846                // Process has passed all conditions, kill it!
5847                if (!doit) {
5848                    return true;
5849                }
5850                app.removed = true;
5851                procs.add(app);
5852            }
5853        }
5854
5855        int N = procs.size();
5856        for (int i=0; i<N; i++) {
5857            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5858        }
5859        updateOomAdjLocked();
5860        return N > 0;
5861    }
5862
5863    private void cleanupDisabledPackageComponentsLocked(
5864            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5865
5866        Set<String> disabledClasses = null;
5867        boolean packageDisabled = false;
5868        IPackageManager pm = AppGlobals.getPackageManager();
5869
5870        if (changedClasses == null) {
5871            // Nothing changed...
5872            return;
5873        }
5874
5875        // Determine enable/disable state of the package and its components.
5876        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5877        for (int i = changedClasses.length - 1; i >= 0; i--) {
5878            final String changedClass = changedClasses[i];
5879
5880            if (changedClass.equals(packageName)) {
5881                try {
5882                    // Entire package setting changed
5883                    enabled = pm.getApplicationEnabledSetting(packageName,
5884                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5885                } catch (Exception e) {
5886                    // No such package/component; probably racing with uninstall.  In any
5887                    // event it means we have nothing further to do here.
5888                    return;
5889                }
5890                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5891                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5892                if (packageDisabled) {
5893                    // Entire package is disabled.
5894                    // No need to continue to check component states.
5895                    disabledClasses = null;
5896                    break;
5897                }
5898            } else {
5899                try {
5900                    enabled = pm.getComponentEnabledSetting(
5901                            new ComponentName(packageName, changedClass),
5902                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5903                } catch (Exception e) {
5904                    // As above, probably racing with uninstall.
5905                    return;
5906                }
5907                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5908                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5909                    if (disabledClasses == null) {
5910                        disabledClasses = new ArraySet<>(changedClasses.length);
5911                    }
5912                    disabledClasses.add(changedClass);
5913                }
5914            }
5915        }
5916
5917        if (!packageDisabled && disabledClasses == null) {
5918            // Nothing to do here...
5919            return;
5920        }
5921
5922        // Clean-up disabled activities.
5923        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5924                packageName, disabledClasses, true, false, userId) && mBooted) {
5925            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5926            mStackSupervisor.scheduleIdleLocked();
5927        }
5928
5929        // Clean-up disabled tasks
5930        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5931
5932        // Clean-up disabled services.
5933        mServices.bringDownDisabledPackageServicesLocked(
5934                packageName, disabledClasses, userId, false, killProcess, true);
5935
5936        // Clean-up disabled providers.
5937        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5938        mProviderMap.collectPackageProvidersLocked(
5939                packageName, disabledClasses, true, false, userId, providers);
5940        for (int i = providers.size() - 1; i >= 0; i--) {
5941            removeDyingProviderLocked(null, providers.get(i), true);
5942        }
5943
5944        // Clean-up disabled broadcast receivers.
5945        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5946            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5947                    packageName, disabledClasses, userId, true);
5948        }
5949
5950    }
5951
5952    final boolean forceStopPackageLocked(String packageName, int appId,
5953            boolean callerWillRestart, boolean purgeCache, boolean doit,
5954            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5955        int i;
5956
5957        if (userId == UserHandle.USER_ALL && packageName == null) {
5958            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5959        }
5960
5961        if (appId < 0 && packageName != null) {
5962            try {
5963                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5964                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5965            } catch (RemoteException e) {
5966            }
5967        }
5968
5969        if (doit) {
5970            if (packageName != null) {
5971                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5972                        + " user=" + userId + ": " + reason);
5973            } else {
5974                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5975            }
5976
5977            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5978        }
5979
5980        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5981                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5982                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5983
5984        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5985                packageName, null, doit, evenPersistent, userId)) {
5986            if (!doit) {
5987                return true;
5988            }
5989            didSomething = true;
5990        }
5991
5992        if (mServices.bringDownDisabledPackageServicesLocked(
5993                packageName, null, userId, evenPersistent, true, doit)) {
5994            if (!doit) {
5995                return true;
5996            }
5997            didSomething = true;
5998        }
5999
6000        if (packageName == null) {
6001            // Remove all sticky broadcasts from this user.
6002            mStickyBroadcasts.remove(userId);
6003        }
6004
6005        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6006        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6007                userId, providers)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013        for (i = providers.size() - 1; i >= 0; i--) {
6014            removeDyingProviderLocked(null, providers.get(i), true);
6015        }
6016
6017        // Remove transient permissions granted from/to this package/user
6018        removeUriPermissionsForPackageLocked(packageName, userId, false);
6019
6020        if (doit) {
6021            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6022                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6023                        packageName, null, userId, doit);
6024            }
6025        }
6026
6027        if (packageName == null || uninstalling) {
6028            // Remove pending intents.  For now we only do this when force
6029            // stopping users, because we have some problems when doing this
6030            // for packages -- app widgets are not currently cleaned up for
6031            // such packages, so they can be left with bad pending intents.
6032            if (mIntentSenderRecords.size() > 0) {
6033                Iterator<WeakReference<PendingIntentRecord>> it
6034                        = mIntentSenderRecords.values().iterator();
6035                while (it.hasNext()) {
6036                    WeakReference<PendingIntentRecord> wpir = it.next();
6037                    if (wpir == null) {
6038                        it.remove();
6039                        continue;
6040                    }
6041                    PendingIntentRecord pir = wpir.get();
6042                    if (pir == null) {
6043                        it.remove();
6044                        continue;
6045                    }
6046                    if (packageName == null) {
6047                        // Stopping user, remove all objects for the user.
6048                        if (pir.key.userId != userId) {
6049                            // Not the same user, skip it.
6050                            continue;
6051                        }
6052                    } else {
6053                        if (UserHandle.getAppId(pir.uid) != appId) {
6054                            // Different app id, skip it.
6055                            continue;
6056                        }
6057                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6058                            // Different user, skip it.
6059                            continue;
6060                        }
6061                        if (!pir.key.packageName.equals(packageName)) {
6062                            // Different package, skip it.
6063                            continue;
6064                        }
6065                    }
6066                    if (!doit) {
6067                        return true;
6068                    }
6069                    didSomething = true;
6070                    it.remove();
6071                    pir.canceled = true;
6072                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6073                        pir.key.activity.pendingResults.remove(pir.ref);
6074                    }
6075                }
6076            }
6077        }
6078
6079        if (doit) {
6080            if (purgeCache && packageName != null) {
6081                AttributeCache ac = AttributeCache.instance();
6082                if (ac != null) {
6083                    ac.removePackage(packageName);
6084                }
6085            }
6086            if (mBooted) {
6087                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6088                mStackSupervisor.scheduleIdleLocked();
6089            }
6090        }
6091
6092        return didSomething;
6093    }
6094
6095    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6096        ProcessRecord old = mProcessNames.remove(name, uid);
6097        if (old != null) {
6098            old.uidRecord.numProcs--;
6099            if (old.uidRecord.numProcs == 0) {
6100                // No more processes using this uid, tell clients it is gone.
6101                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6102                        "No more processes in " + old.uidRecord);
6103                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6104                mActiveUids.remove(uid);
6105                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6106            }
6107            old.uidRecord = null;
6108        }
6109        mIsolatedProcesses.remove(uid);
6110        return old;
6111    }
6112
6113    private final void addProcessNameLocked(ProcessRecord proc) {
6114        // We shouldn't already have a process under this name, but just in case we
6115        // need to clean up whatever may be there now.
6116        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6117        if (old == proc && proc.persistent) {
6118            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6119            Slog.w(TAG, "Re-adding persistent process " + proc);
6120        } else if (old != null) {
6121            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6122        }
6123        UidRecord uidRec = mActiveUids.get(proc.uid);
6124        if (uidRec == null) {
6125            uidRec = new UidRecord(proc.uid);
6126            // This is the first appearance of the uid, report it now!
6127            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6128                    "Creating new process uid: " + uidRec);
6129            mActiveUids.put(proc.uid, uidRec);
6130            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6131            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6132        }
6133        proc.uidRecord = uidRec;
6134        uidRec.numProcs++;
6135        mProcessNames.put(proc.processName, proc.uid, proc);
6136        if (proc.isolated) {
6137            mIsolatedProcesses.put(proc.uid, proc);
6138        }
6139    }
6140
6141    boolean removeProcessLocked(ProcessRecord app,
6142            boolean callerWillRestart, boolean allowRestart, String reason) {
6143        final String name = app.processName;
6144        final int uid = app.uid;
6145        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6146            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6147
6148        removeProcessNameLocked(name, uid);
6149        if (mHeavyWeightProcess == app) {
6150            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6151                    mHeavyWeightProcess.userId, 0));
6152            mHeavyWeightProcess = null;
6153        }
6154        boolean needRestart = false;
6155        if (app.pid > 0 && app.pid != MY_PID) {
6156            int pid = app.pid;
6157            synchronized (mPidsSelfLocked) {
6158                mPidsSelfLocked.remove(pid);
6159                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6160            }
6161            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6162            if (app.isolated) {
6163                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6164            }
6165            boolean willRestart = false;
6166            if (app.persistent && !app.isolated) {
6167                if (!callerWillRestart) {
6168                    willRestart = true;
6169                } else {
6170                    needRestart = true;
6171                }
6172            }
6173            app.kill(reason, true);
6174            handleAppDiedLocked(app, willRestart, allowRestart);
6175            if (willRestart) {
6176                removeLruProcessLocked(app);
6177                addAppLocked(app.info, false, null /* ABI override */);
6178            }
6179        } else {
6180            mRemovedProcesses.add(app);
6181        }
6182
6183        return needRestart;
6184    }
6185
6186    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6187        cleanupAppInLaunchingProvidersLocked(app, true);
6188        removeProcessLocked(app, false, true, "timeout publishing content providers");
6189    }
6190
6191    private final void processStartTimedOutLocked(ProcessRecord app) {
6192        final int pid = app.pid;
6193        boolean gone = false;
6194        synchronized (mPidsSelfLocked) {
6195            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6196            if (knownApp != null && knownApp.thread == null) {
6197                mPidsSelfLocked.remove(pid);
6198                gone = true;
6199            }
6200        }
6201
6202        if (gone) {
6203            Slog.w(TAG, "Process " + app + " failed to attach");
6204            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6205                    pid, app.uid, app.processName);
6206            removeProcessNameLocked(app.processName, app.uid);
6207            if (mHeavyWeightProcess == app) {
6208                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6209                        mHeavyWeightProcess.userId, 0));
6210                mHeavyWeightProcess = null;
6211            }
6212            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6213            if (app.isolated) {
6214                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6215            }
6216            // Take care of any launching providers waiting for this process.
6217            cleanupAppInLaunchingProvidersLocked(app, true);
6218            // Take care of any services that are waiting for the process.
6219            mServices.processStartTimedOutLocked(app);
6220            app.kill("start timeout", true);
6221            removeLruProcessLocked(app);
6222            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6223                Slog.w(TAG, "Unattached app died before backup, skipping");
6224                try {
6225                    IBackupManager bm = IBackupManager.Stub.asInterface(
6226                            ServiceManager.getService(Context.BACKUP_SERVICE));
6227                    bm.agentDisconnected(app.info.packageName);
6228                } catch (RemoteException e) {
6229                    // Can't happen; the backup manager is local
6230                }
6231            }
6232            if (isPendingBroadcastProcessLocked(pid)) {
6233                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6234                skipPendingBroadcastLocked(pid);
6235            }
6236        } else {
6237            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6238        }
6239    }
6240
6241    private final boolean attachApplicationLocked(IApplicationThread thread,
6242            int pid) {
6243
6244        // Find the application record that is being attached...  either via
6245        // the pid if we are running in multiple processes, or just pull the
6246        // next app record if we are emulating process with anonymous threads.
6247        ProcessRecord app;
6248        if (pid != MY_PID && pid >= 0) {
6249            synchronized (mPidsSelfLocked) {
6250                app = mPidsSelfLocked.get(pid);
6251            }
6252        } else {
6253            app = null;
6254        }
6255
6256        if (app == null) {
6257            Slog.w(TAG, "No pending application record for pid " + pid
6258                    + " (IApplicationThread " + thread + "); dropping process");
6259            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6260            if (pid > 0 && pid != MY_PID) {
6261                Process.killProcessQuiet(pid);
6262                //TODO: killProcessGroup(app.info.uid, pid);
6263            } else {
6264                try {
6265                    thread.scheduleExit();
6266                } catch (Exception e) {
6267                    // Ignore exceptions.
6268                }
6269            }
6270            return false;
6271        }
6272
6273        // If this application record is still attached to a previous
6274        // process, clean it up now.
6275        if (app.thread != null) {
6276            handleAppDiedLocked(app, true, true);
6277        }
6278
6279        // Tell the process all about itself.
6280
6281        if (DEBUG_ALL) Slog.v(
6282                TAG, "Binding process pid " + pid + " to record " + app);
6283
6284        final String processName = app.processName;
6285        try {
6286            AppDeathRecipient adr = new AppDeathRecipient(
6287                    app, pid, thread);
6288            thread.asBinder().linkToDeath(adr, 0);
6289            app.deathRecipient = adr;
6290        } catch (RemoteException e) {
6291            app.resetPackageList(mProcessStats);
6292            startProcessLocked(app, "link fail", processName);
6293            return false;
6294        }
6295
6296        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6297
6298        app.makeActive(thread, mProcessStats);
6299        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6300        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6301        app.forcingToForeground = null;
6302        updateProcessForegroundLocked(app, false, false);
6303        app.hasShownUi = false;
6304        app.debugging = false;
6305        app.cached = false;
6306        app.killedByAm = false;
6307        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6308
6309        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6310
6311        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6312        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6313
6314        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6315            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6316            msg.obj = app;
6317            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6318        }
6319
6320        if (!normalMode) {
6321            Slog.i(TAG, "Launching preboot mode app: " + app);
6322        }
6323
6324        if (DEBUG_ALL) Slog.v(
6325            TAG, "New app record " + app
6326            + " thread=" + thread.asBinder() + " pid=" + pid);
6327        try {
6328            int testMode = IApplicationThread.DEBUG_OFF;
6329            if (mDebugApp != null && mDebugApp.equals(processName)) {
6330                testMode = mWaitForDebugger
6331                    ? IApplicationThread.DEBUG_WAIT
6332                    : IApplicationThread.DEBUG_ON;
6333                app.debugging = true;
6334                if (mDebugTransient) {
6335                    mDebugApp = mOrigDebugApp;
6336                    mWaitForDebugger = mOrigWaitForDebugger;
6337                }
6338            }
6339            String profileFile = app.instrumentationProfileFile;
6340            ParcelFileDescriptor profileFd = null;
6341            int samplingInterval = 0;
6342            boolean profileAutoStop = false;
6343            if (mProfileApp != null && mProfileApp.equals(processName)) {
6344                mProfileProc = app;
6345                profileFile = mProfileFile;
6346                profileFd = mProfileFd;
6347                samplingInterval = mSamplingInterval;
6348                profileAutoStop = mAutoStopProfiler;
6349            }
6350            boolean enableTrackAllocation = false;
6351            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6352                enableTrackAllocation = true;
6353                mTrackAllocationApp = null;
6354            }
6355
6356            // If the app is being launched for restore or full backup, set it up specially
6357            boolean isRestrictedBackupMode = false;
6358            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6359                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6360                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6361                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6362                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6363            }
6364
6365            if (app.instrumentationClass != null) {
6366                notifyPackageUse(app.instrumentationClass.getPackageName(),
6367                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6368            }
6369            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6370                    + processName + " with config " + mConfiguration);
6371            ApplicationInfo appInfo = app.instrumentationInfo != null
6372                    ? app.instrumentationInfo : app.info;
6373            app.compat = compatibilityInfoForPackageLocked(appInfo);
6374            if (profileFd != null) {
6375                profileFd = profileFd.dup();
6376            }
6377            ProfilerInfo profilerInfo = profileFile == null ? null
6378                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6379            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6380                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6381                    app.instrumentationUiAutomationConnection, testMode,
6382                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6383                    isRestrictedBackupMode || !normalMode, app.persistent,
6384                    new Configuration(mConfiguration), app.compat,
6385                    getCommonServicesLocked(app.isolated),
6386                    mCoreSettingsObserver.getCoreSettingsLocked());
6387            updateLruProcessLocked(app, false, null);
6388            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6389        } catch (Exception e) {
6390            // todo: Yikes!  What should we do?  For now we will try to
6391            // start another process, but that could easily get us in
6392            // an infinite loop of restarting processes...
6393            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6394
6395            app.resetPackageList(mProcessStats);
6396            app.unlinkDeathRecipient();
6397            startProcessLocked(app, "bind fail", processName);
6398            return false;
6399        }
6400
6401        // Remove this record from the list of starting applications.
6402        mPersistentStartingProcesses.remove(app);
6403        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6404                "Attach application locked removing on hold: " + app);
6405        mProcessesOnHold.remove(app);
6406
6407        boolean badApp = false;
6408        boolean didSomething = false;
6409
6410        // See if the top visible activity is waiting to run in this process...
6411        if (normalMode) {
6412            try {
6413                if (mStackSupervisor.attachApplicationLocked(app)) {
6414                    didSomething = true;
6415                }
6416            } catch (Exception e) {
6417                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6418                badApp = true;
6419            }
6420        }
6421
6422        // Find any services that should be running in this process...
6423        if (!badApp) {
6424            try {
6425                didSomething |= mServices.attachApplicationLocked(app, processName);
6426            } catch (Exception e) {
6427                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6428                badApp = true;
6429            }
6430        }
6431
6432        // Check if a next-broadcast receiver is in this process...
6433        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6434            try {
6435                didSomething |= sendPendingBroadcastsLocked(app);
6436            } catch (Exception e) {
6437                // If the app died trying to launch the receiver we declare it 'bad'
6438                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6439                badApp = true;
6440            }
6441        }
6442
6443        // Check whether the next backup agent is in this process...
6444        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6445            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6446                    "New app is backup target, launching agent for " + app);
6447            notifyPackageUse(mBackupTarget.appInfo.packageName,
6448                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6449            try {
6450                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6451                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6452                        mBackupTarget.backupMode);
6453            } catch (Exception e) {
6454                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6455                badApp = true;
6456            }
6457        }
6458
6459        if (badApp) {
6460            app.kill("error during init", true);
6461            handleAppDiedLocked(app, false, true);
6462            return false;
6463        }
6464
6465        if (!didSomething) {
6466            updateOomAdjLocked();
6467        }
6468
6469        return true;
6470    }
6471
6472    @Override
6473    public final void attachApplication(IApplicationThread thread) {
6474        synchronized (this) {
6475            int callingPid = Binder.getCallingPid();
6476            final long origId = Binder.clearCallingIdentity();
6477            attachApplicationLocked(thread, callingPid);
6478            Binder.restoreCallingIdentity(origId);
6479        }
6480    }
6481
6482    @Override
6483    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6484        final long origId = Binder.clearCallingIdentity();
6485        synchronized (this) {
6486            ActivityStack stack = ActivityRecord.getStackLocked(token);
6487            if (stack != null) {
6488                ActivityRecord r =
6489                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6490                if (stopProfiling) {
6491                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6492                        try {
6493                            mProfileFd.close();
6494                        } catch (IOException e) {
6495                        }
6496                        clearProfilerLocked();
6497                    }
6498                }
6499            }
6500        }
6501        Binder.restoreCallingIdentity(origId);
6502    }
6503
6504    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6505        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6506                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6507    }
6508
6509    void enableScreenAfterBoot() {
6510        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6511                SystemClock.uptimeMillis());
6512        mWindowManager.enableScreenAfterBoot();
6513
6514        synchronized (this) {
6515            updateEventDispatchingLocked();
6516        }
6517    }
6518
6519    @Override
6520    public void showBootMessage(final CharSequence msg, final boolean always) {
6521        if (Binder.getCallingUid() != Process.myUid()) {
6522            // These days only the core system can call this, so apps can't get in
6523            // the way of what we show about running them.
6524        }
6525        mWindowManager.showBootMessage(msg, always);
6526    }
6527
6528    @Override
6529    public void keyguardWaitingForActivityDrawn() {
6530        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6531        final long token = Binder.clearCallingIdentity();
6532        try {
6533            synchronized (this) {
6534                if (DEBUG_LOCKSCREEN) logLockScreen("");
6535                mWindowManager.keyguardWaitingForActivityDrawn();
6536                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6537                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6538                    updateSleepIfNeededLocked();
6539                }
6540            }
6541        } finally {
6542            Binder.restoreCallingIdentity(token);
6543        }
6544    }
6545
6546    @Override
6547    public void keyguardGoingAway(int flags) {
6548        enforceNotIsolatedCaller("keyguardGoingAway");
6549        final long token = Binder.clearCallingIdentity();
6550        try {
6551            synchronized (this) {
6552                if (DEBUG_LOCKSCREEN) logLockScreen("");
6553                mWindowManager.keyguardGoingAway(flags);
6554                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6555                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6556                    updateSleepIfNeededLocked();
6557
6558                    // Some stack visibility might change (e.g. docked stack)
6559                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6560                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6561                }
6562            }
6563        } finally {
6564            Binder.restoreCallingIdentity(token);
6565        }
6566    }
6567
6568    final void finishBooting() {
6569        synchronized (this) {
6570            if (!mBootAnimationComplete) {
6571                mCallFinishBooting = true;
6572                return;
6573            }
6574            mCallFinishBooting = false;
6575        }
6576
6577        ArraySet<String> completedIsas = new ArraySet<String>();
6578        for (String abi : Build.SUPPORTED_ABIS) {
6579            Process.establishZygoteConnectionForAbi(abi);
6580            final String instructionSet = VMRuntime.getInstructionSet(abi);
6581            if (!completedIsas.contains(instructionSet)) {
6582                try {
6583                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6584                } catch (InstallerException e) {
6585                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6586                }
6587                completedIsas.add(instructionSet);
6588            }
6589        }
6590
6591        IntentFilter pkgFilter = new IntentFilter();
6592        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6593        pkgFilter.addDataScheme("package");
6594        mContext.registerReceiver(new BroadcastReceiver() {
6595            @Override
6596            public void onReceive(Context context, Intent intent) {
6597                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6598                if (pkgs != null) {
6599                    for (String pkg : pkgs) {
6600                        synchronized (ActivityManagerService.this) {
6601                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6602                                    0, "query restart")) {
6603                                setResultCode(Activity.RESULT_OK);
6604                                return;
6605                            }
6606                        }
6607                    }
6608                }
6609            }
6610        }, pkgFilter);
6611
6612        IntentFilter dumpheapFilter = new IntentFilter();
6613        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6614        mContext.registerReceiver(new BroadcastReceiver() {
6615            @Override
6616            public void onReceive(Context context, Intent intent) {
6617                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6618                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6619                } else {
6620                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6621                }
6622            }
6623        }, dumpheapFilter);
6624
6625        // Let system services know.
6626        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6627
6628        synchronized (this) {
6629            // Ensure that any processes we had put on hold are now started
6630            // up.
6631            final int NP = mProcessesOnHold.size();
6632            if (NP > 0) {
6633                ArrayList<ProcessRecord> procs =
6634                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6635                for (int ip=0; ip<NP; ip++) {
6636                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6637                            + procs.get(ip));
6638                    startProcessLocked(procs.get(ip), "on-hold", null);
6639                }
6640            }
6641
6642            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6643                // Start looking for apps that are abusing wake locks.
6644                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6645                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6646                // Tell anyone interested that we are done booting!
6647                SystemProperties.set("sys.boot_completed", "1");
6648
6649                // And trigger dev.bootcomplete if we are not showing encryption progress
6650                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6651                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6652                    SystemProperties.set("dev.bootcomplete", "1");
6653                }
6654                mUserController.sendBootCompletedLocked(
6655                        new IIntentReceiver.Stub() {
6656                            @Override
6657                            public void performReceive(Intent intent, int resultCode,
6658                                    String data, Bundle extras, boolean ordered,
6659                                    boolean sticky, int sendingUser) {
6660                                synchronized (ActivityManagerService.this) {
6661                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6662                                            true, false);
6663                                }
6664                            }
6665                        });
6666                scheduleStartProfilesLocked();
6667            }
6668        }
6669    }
6670
6671    @Override
6672    public void bootAnimationComplete() {
6673        final boolean callFinishBooting;
6674        synchronized (this) {
6675            callFinishBooting = mCallFinishBooting;
6676            mBootAnimationComplete = true;
6677        }
6678        if (callFinishBooting) {
6679            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6680            finishBooting();
6681            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6682        }
6683    }
6684
6685    final void ensureBootCompleted() {
6686        boolean booting;
6687        boolean enableScreen;
6688        synchronized (this) {
6689            booting = mBooting;
6690            mBooting = false;
6691            enableScreen = !mBooted;
6692            mBooted = true;
6693        }
6694
6695        if (booting) {
6696            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6697            finishBooting();
6698            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6699        }
6700
6701        if (enableScreen) {
6702            enableScreenAfterBoot();
6703        }
6704    }
6705
6706    @Override
6707    public final void activityResumed(IBinder token) {
6708        final long origId = Binder.clearCallingIdentity();
6709        synchronized(this) {
6710            ActivityStack stack = ActivityRecord.getStackLocked(token);
6711            if (stack != null) {
6712                stack.activityResumedLocked(token);
6713            }
6714        }
6715        Binder.restoreCallingIdentity(origId);
6716    }
6717
6718    @Override
6719    public final void activityPaused(IBinder token) {
6720        final long origId = Binder.clearCallingIdentity();
6721        synchronized(this) {
6722            ActivityStack stack = ActivityRecord.getStackLocked(token);
6723            if (stack != null) {
6724                stack.activityPausedLocked(token, false);
6725            }
6726        }
6727        Binder.restoreCallingIdentity(origId);
6728    }
6729
6730    @Override
6731    public final void activityStopped(IBinder token, Bundle icicle,
6732            PersistableBundle persistentState, CharSequence description) {
6733        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6734
6735        // Refuse possible leaked file descriptors
6736        if (icicle != null && icicle.hasFileDescriptors()) {
6737            throw new IllegalArgumentException("File descriptors passed in Bundle");
6738        }
6739
6740        final long origId = Binder.clearCallingIdentity();
6741
6742        synchronized (this) {
6743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6744            if (r != null) {
6745                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6746            }
6747        }
6748
6749        trimApplications();
6750
6751        Binder.restoreCallingIdentity(origId);
6752    }
6753
6754    @Override
6755    public final void activityDestroyed(IBinder token) {
6756        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6757        synchronized (this) {
6758            ActivityStack stack = ActivityRecord.getStackLocked(token);
6759            if (stack != null) {
6760                stack.activityDestroyedLocked(token, "activityDestroyed");
6761            }
6762        }
6763    }
6764
6765    @Override
6766    public final void activityRelaunched(IBinder token) {
6767        final long origId = Binder.clearCallingIdentity();
6768        synchronized (this) {
6769            mStackSupervisor.activityRelaunchedLocked(token);
6770        }
6771        Binder.restoreCallingIdentity(origId);
6772    }
6773
6774    @Override
6775    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6776            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6777        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6778                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6779        synchronized (this) {
6780            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6781            if (record == null) {
6782                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6783                        + "found for: " + token);
6784            }
6785            record.setSizeConfigurations(horizontalSizeConfiguration,
6786                    verticalSizeConfigurations, smallestSizeConfigurations);
6787        }
6788    }
6789
6790    @Override
6791    public final void backgroundResourcesReleased(IBinder token) {
6792        final long origId = Binder.clearCallingIdentity();
6793        try {
6794            synchronized (this) {
6795                ActivityStack stack = ActivityRecord.getStackLocked(token);
6796                if (stack != null) {
6797                    stack.backgroundResourcesReleased();
6798                }
6799            }
6800        } finally {
6801            Binder.restoreCallingIdentity(origId);
6802        }
6803    }
6804
6805    @Override
6806    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6807        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6808    }
6809
6810    @Override
6811    public final void notifyEnterAnimationComplete(IBinder token) {
6812        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6813    }
6814
6815    @Override
6816    public String getCallingPackage(IBinder token) {
6817        synchronized (this) {
6818            ActivityRecord r = getCallingRecordLocked(token);
6819            return r != null ? r.info.packageName : null;
6820        }
6821    }
6822
6823    @Override
6824    public ComponentName getCallingActivity(IBinder token) {
6825        synchronized (this) {
6826            ActivityRecord r = getCallingRecordLocked(token);
6827            return r != null ? r.intent.getComponent() : null;
6828        }
6829    }
6830
6831    private ActivityRecord getCallingRecordLocked(IBinder token) {
6832        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6833        if (r == null) {
6834            return null;
6835        }
6836        return r.resultTo;
6837    }
6838
6839    @Override
6840    public ComponentName getActivityClassForToken(IBinder token) {
6841        synchronized(this) {
6842            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6843            if (r == null) {
6844                return null;
6845            }
6846            return r.intent.getComponent();
6847        }
6848    }
6849
6850    @Override
6851    public String getPackageForToken(IBinder token) {
6852        synchronized(this) {
6853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6854            if (r == null) {
6855                return null;
6856            }
6857            return r.packageName;
6858        }
6859    }
6860
6861    @Override
6862    public boolean isRootVoiceInteraction(IBinder token) {
6863        synchronized(this) {
6864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6865            if (r == null) {
6866                return false;
6867            }
6868            return r.rootVoiceInteraction;
6869        }
6870    }
6871
6872    @Override
6873    public IIntentSender getIntentSender(int type,
6874            String packageName, IBinder token, String resultWho,
6875            int requestCode, Intent[] intents, String[] resolvedTypes,
6876            int flags, Bundle bOptions, int userId) {
6877        enforceNotIsolatedCaller("getIntentSender");
6878        // Refuse possible leaked file descriptors
6879        if (intents != null) {
6880            if (intents.length < 1) {
6881                throw new IllegalArgumentException("Intents array length must be >= 1");
6882            }
6883            for (int i=0; i<intents.length; i++) {
6884                Intent intent = intents[i];
6885                if (intent != null) {
6886                    if (intent.hasFileDescriptors()) {
6887                        throw new IllegalArgumentException("File descriptors passed in Intent");
6888                    }
6889                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6890                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6891                        throw new IllegalArgumentException(
6892                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6893                    }
6894                    intents[i] = new Intent(intent);
6895                }
6896            }
6897            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6898                throw new IllegalArgumentException(
6899                        "Intent array length does not match resolvedTypes length");
6900            }
6901        }
6902        if (bOptions != null) {
6903            if (bOptions.hasFileDescriptors()) {
6904                throw new IllegalArgumentException("File descriptors passed in options");
6905            }
6906        }
6907
6908        synchronized(this) {
6909            int callingUid = Binder.getCallingUid();
6910            int origUserId = userId;
6911            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6912                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6913                    ALLOW_NON_FULL, "getIntentSender", null);
6914            if (origUserId == UserHandle.USER_CURRENT) {
6915                // We don't want to evaluate this until the pending intent is
6916                // actually executed.  However, we do want to always do the
6917                // security checking for it above.
6918                userId = UserHandle.USER_CURRENT;
6919            }
6920            try {
6921                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6922                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6923                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6924                    if (!UserHandle.isSameApp(callingUid, uid)) {
6925                        String msg = "Permission Denial: getIntentSender() from pid="
6926                            + Binder.getCallingPid()
6927                            + ", uid=" + Binder.getCallingUid()
6928                            + ", (need uid=" + uid + ")"
6929                            + " is not allowed to send as package " + packageName;
6930                        Slog.w(TAG, msg);
6931                        throw new SecurityException(msg);
6932                    }
6933                }
6934
6935                return getIntentSenderLocked(type, packageName, callingUid, userId,
6936                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6937
6938            } catch (RemoteException e) {
6939                throw new SecurityException(e);
6940            }
6941        }
6942    }
6943
6944    IIntentSender getIntentSenderLocked(int type, String packageName,
6945            int callingUid, int userId, IBinder token, String resultWho,
6946            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6947            Bundle bOptions) {
6948        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6949        ActivityRecord activity = null;
6950        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6951            activity = ActivityRecord.isInStackLocked(token);
6952            if (activity == null) {
6953                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6954                return null;
6955            }
6956            if (activity.finishing) {
6957                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6958                return null;
6959            }
6960        }
6961
6962        // We're going to be splicing together extras before sending, so we're
6963        // okay poking into any contained extras.
6964        if (intents != null) {
6965            for (int i = 0; i < intents.length; i++) {
6966                intents[i].setDefusable(true);
6967            }
6968        }
6969        Bundle.setDefusable(bOptions, true);
6970
6971        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6972        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6973        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6974        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6975                |PendingIntent.FLAG_UPDATE_CURRENT);
6976
6977        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6978                type, packageName, activity, resultWho,
6979                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6980        WeakReference<PendingIntentRecord> ref;
6981        ref = mIntentSenderRecords.get(key);
6982        PendingIntentRecord rec = ref != null ? ref.get() : null;
6983        if (rec != null) {
6984            if (!cancelCurrent) {
6985                if (updateCurrent) {
6986                    if (rec.key.requestIntent != null) {
6987                        rec.key.requestIntent.replaceExtras(intents != null ?
6988                                intents[intents.length - 1] : null);
6989                    }
6990                    if (intents != null) {
6991                        intents[intents.length-1] = rec.key.requestIntent;
6992                        rec.key.allIntents = intents;
6993                        rec.key.allResolvedTypes = resolvedTypes;
6994                    } else {
6995                        rec.key.allIntents = null;
6996                        rec.key.allResolvedTypes = null;
6997                    }
6998                }
6999                return rec;
7000            }
7001            rec.canceled = true;
7002            mIntentSenderRecords.remove(key);
7003        }
7004        if (noCreate) {
7005            return rec;
7006        }
7007        rec = new PendingIntentRecord(this, key, callingUid);
7008        mIntentSenderRecords.put(key, rec.ref);
7009        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7010            if (activity.pendingResults == null) {
7011                activity.pendingResults
7012                        = new HashSet<WeakReference<PendingIntentRecord>>();
7013            }
7014            activity.pendingResults.add(rec.ref);
7015        }
7016        return rec;
7017    }
7018
7019    @Override
7020    public void cancelIntentSender(IIntentSender sender) {
7021        if (!(sender instanceof PendingIntentRecord)) {
7022            return;
7023        }
7024        synchronized(this) {
7025            PendingIntentRecord rec = (PendingIntentRecord)sender;
7026            try {
7027                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7028                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7029                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7030                    String msg = "Permission Denial: cancelIntentSender() from pid="
7031                        + Binder.getCallingPid()
7032                        + ", uid=" + Binder.getCallingUid()
7033                        + " is not allowed to cancel packges "
7034                        + rec.key.packageName;
7035                    Slog.w(TAG, msg);
7036                    throw new SecurityException(msg);
7037                }
7038            } catch (RemoteException e) {
7039                throw new SecurityException(e);
7040            }
7041            cancelIntentSenderLocked(rec, true);
7042        }
7043    }
7044
7045    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7046        rec.canceled = true;
7047        mIntentSenderRecords.remove(rec.key);
7048        if (cleanActivity && rec.key.activity != null) {
7049            rec.key.activity.pendingResults.remove(rec.ref);
7050        }
7051    }
7052
7053    @Override
7054    public String getPackageForIntentSender(IIntentSender pendingResult) {
7055        if (!(pendingResult instanceof PendingIntentRecord)) {
7056            return null;
7057        }
7058        try {
7059            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7060            return res.key.packageName;
7061        } catch (ClassCastException e) {
7062        }
7063        return null;
7064    }
7065
7066    @Override
7067    public int getUidForIntentSender(IIntentSender sender) {
7068        if (sender instanceof PendingIntentRecord) {
7069            try {
7070                PendingIntentRecord res = (PendingIntentRecord)sender;
7071                return res.uid;
7072            } catch (ClassCastException e) {
7073            }
7074        }
7075        return -1;
7076    }
7077
7078    @Override
7079    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7080        if (!(pendingResult instanceof PendingIntentRecord)) {
7081            return false;
7082        }
7083        try {
7084            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7085            if (res.key.allIntents == null) {
7086                return false;
7087            }
7088            for (int i=0; i<res.key.allIntents.length; i++) {
7089                Intent intent = res.key.allIntents[i];
7090                if (intent.getPackage() != null && intent.getComponent() != null) {
7091                    return false;
7092                }
7093            }
7094            return true;
7095        } catch (ClassCastException e) {
7096        }
7097        return false;
7098    }
7099
7100    @Override
7101    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7102        if (!(pendingResult instanceof PendingIntentRecord)) {
7103            return false;
7104        }
7105        try {
7106            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7107            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7108                return true;
7109            }
7110            return false;
7111        } catch (ClassCastException e) {
7112        }
7113        return false;
7114    }
7115
7116    @Override
7117    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7118        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7119                "getIntentForIntentSender()");
7120        if (!(pendingResult instanceof PendingIntentRecord)) {
7121            return null;
7122        }
7123        try {
7124            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7125            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7126        } catch (ClassCastException e) {
7127        }
7128        return null;
7129    }
7130
7131    @Override
7132    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7133        if (!(pendingResult instanceof PendingIntentRecord)) {
7134            return null;
7135        }
7136        try {
7137            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7138            synchronized (this) {
7139                return getTagForIntentSenderLocked(res, prefix);
7140            }
7141        } catch (ClassCastException e) {
7142        }
7143        return null;
7144    }
7145
7146    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7147        final Intent intent = res.key.requestIntent;
7148        if (intent != null) {
7149            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7150                    || res.lastTagPrefix.equals(prefix))) {
7151                return res.lastTag;
7152            }
7153            res.lastTagPrefix = prefix;
7154            final StringBuilder sb = new StringBuilder(128);
7155            if (prefix != null) {
7156                sb.append(prefix);
7157            }
7158            if (intent.getAction() != null) {
7159                sb.append(intent.getAction());
7160            } else if (intent.getComponent() != null) {
7161                intent.getComponent().appendShortString(sb);
7162            } else {
7163                sb.append("?");
7164            }
7165            return res.lastTag = sb.toString();
7166        }
7167        return null;
7168    }
7169
7170    @Override
7171    public void setProcessLimit(int max) {
7172        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7173                "setProcessLimit()");
7174        synchronized (this) {
7175            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7176            mProcessLimitOverride = max;
7177        }
7178        trimApplications();
7179    }
7180
7181    @Override
7182    public int getProcessLimit() {
7183        synchronized (this) {
7184            return mProcessLimitOverride;
7185        }
7186    }
7187
7188    void foregroundTokenDied(ForegroundToken token) {
7189        synchronized (ActivityManagerService.this) {
7190            synchronized (mPidsSelfLocked) {
7191                ForegroundToken cur
7192                    = mForegroundProcesses.get(token.pid);
7193                if (cur != token) {
7194                    return;
7195                }
7196                mForegroundProcesses.remove(token.pid);
7197                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7198                if (pr == null) {
7199                    return;
7200                }
7201                pr.forcingToForeground = null;
7202                updateProcessForegroundLocked(pr, false, false);
7203            }
7204            updateOomAdjLocked();
7205        }
7206    }
7207
7208    @Override
7209    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7210        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7211                "setProcessForeground()");
7212        synchronized(this) {
7213            boolean changed = false;
7214
7215            synchronized (mPidsSelfLocked) {
7216                ProcessRecord pr = mPidsSelfLocked.get(pid);
7217                if (pr == null && isForeground) {
7218                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7219                    return;
7220                }
7221                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7222                if (oldToken != null) {
7223                    oldToken.token.unlinkToDeath(oldToken, 0);
7224                    mForegroundProcesses.remove(pid);
7225                    if (pr != null) {
7226                        pr.forcingToForeground = null;
7227                    }
7228                    changed = true;
7229                }
7230                if (isForeground && token != null) {
7231                    ForegroundToken newToken = new ForegroundToken() {
7232                        @Override
7233                        public void binderDied() {
7234                            foregroundTokenDied(this);
7235                        }
7236                    };
7237                    newToken.pid = pid;
7238                    newToken.token = token;
7239                    try {
7240                        token.linkToDeath(newToken, 0);
7241                        mForegroundProcesses.put(pid, newToken);
7242                        pr.forcingToForeground = token;
7243                        changed = true;
7244                    } catch (RemoteException e) {
7245                        // If the process died while doing this, we will later
7246                        // do the cleanup with the process death link.
7247                    }
7248                }
7249            }
7250
7251            if (changed) {
7252                updateOomAdjLocked();
7253            }
7254        }
7255    }
7256
7257    @Override
7258    public boolean isAppForeground(int uid) throws RemoteException {
7259        synchronized (this) {
7260            UidRecord uidRec = mActiveUids.get(uid);
7261            if (uidRec == null || uidRec.idle) {
7262                return false;
7263            }
7264            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7265        }
7266    }
7267
7268    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7269    // be guarded by permission checking.
7270    int getUidState(int uid) {
7271        synchronized (this) {
7272            UidRecord uidRec = mActiveUids.get(uid);
7273            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7274        }
7275    }
7276
7277    @Override
7278    public boolean isInMultiWindowMode(IBinder token) {
7279        final long origId = Binder.clearCallingIdentity();
7280        try {
7281            synchronized(this) {
7282                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7283                if (r == null) {
7284                    return false;
7285                }
7286                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7287                return !r.task.mFullscreen;
7288            }
7289        } finally {
7290            Binder.restoreCallingIdentity(origId);
7291        }
7292    }
7293
7294    @Override
7295    public boolean isInPictureInPictureMode(IBinder token) {
7296        final long origId = Binder.clearCallingIdentity();
7297        try {
7298            synchronized(this) {
7299                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7300                if (stack == null) {
7301                    return false;
7302                }
7303                return stack.mStackId == PINNED_STACK_ID;
7304            }
7305        } finally {
7306            Binder.restoreCallingIdentity(origId);
7307        }
7308    }
7309
7310    @Override
7311    public void enterPictureInPictureMode(IBinder token) {
7312        final long origId = Binder.clearCallingIdentity();
7313        try {
7314            synchronized(this) {
7315                if (!mSupportsPictureInPicture) {
7316                    throw new IllegalStateException("enterPictureInPictureMode: "
7317                            + "Device doesn't support picture-in-picture mode.");
7318                }
7319
7320                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7321
7322                if (r == null) {
7323                    throw new IllegalStateException("enterPictureInPictureMode: "
7324                            + "Can't find activity for token=" + token);
7325                }
7326
7327                if (!r.supportsPictureInPicture()) {
7328                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7329                            + "Picture-In-Picture not supported for r=" + r);
7330                }
7331
7332                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7333                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7334                        ? mDefaultPinnedStackBounds : null;
7335
7336                mStackSupervisor.moveActivityToPinnedStackLocked(
7337                        r, "enterPictureInPictureMode", bounds);
7338            }
7339        } finally {
7340            Binder.restoreCallingIdentity(origId);
7341        }
7342    }
7343
7344    // =========================================================
7345    // PROCESS INFO
7346    // =========================================================
7347
7348    static class ProcessInfoService extends IProcessInfoService.Stub {
7349        final ActivityManagerService mActivityManagerService;
7350        ProcessInfoService(ActivityManagerService activityManagerService) {
7351            mActivityManagerService = activityManagerService;
7352        }
7353
7354        @Override
7355        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7356            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7357                    /*in*/ pids, /*out*/ states, null);
7358        }
7359
7360        @Override
7361        public void getProcessStatesAndOomScoresFromPids(
7362                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7363            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7364                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7365        }
7366    }
7367
7368    /**
7369     * For each PID in the given input array, write the current process state
7370     * for that process into the states array, or -1 to indicate that no
7371     * process with the given PID exists. If scores array is provided, write
7372     * the oom score for the process into the scores array, with INVALID_ADJ
7373     * indicating the PID doesn't exist.
7374     */
7375    public void getProcessStatesAndOomScoresForPIDs(
7376            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7377        if (scores != null) {
7378            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7379                    "getProcessStatesAndOomScoresForPIDs()");
7380        }
7381
7382        if (pids == null) {
7383            throw new NullPointerException("pids");
7384        } else if (states == null) {
7385            throw new NullPointerException("states");
7386        } else if (pids.length != states.length) {
7387            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7388        } else if (scores != null && pids.length != scores.length) {
7389            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7390        }
7391
7392        synchronized (mPidsSelfLocked) {
7393            for (int i = 0; i < pids.length; i++) {
7394                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7395                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7396                        pr.curProcState;
7397                if (scores != null) {
7398                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7399                }
7400            }
7401        }
7402    }
7403
7404    // =========================================================
7405    // PERMISSIONS
7406    // =========================================================
7407
7408    static class PermissionController extends IPermissionController.Stub {
7409        ActivityManagerService mActivityManagerService;
7410        PermissionController(ActivityManagerService activityManagerService) {
7411            mActivityManagerService = activityManagerService;
7412        }
7413
7414        @Override
7415        public boolean checkPermission(String permission, int pid, int uid) {
7416            return mActivityManagerService.checkPermission(permission, pid,
7417                    uid) == PackageManager.PERMISSION_GRANTED;
7418        }
7419
7420        @Override
7421        public String[] getPackagesForUid(int uid) {
7422            return mActivityManagerService.mContext.getPackageManager()
7423                    .getPackagesForUid(uid);
7424        }
7425
7426        @Override
7427        public boolean isRuntimePermission(String permission) {
7428            try {
7429                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7430                        .getPermissionInfo(permission, 0);
7431                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7432            } catch (NameNotFoundException nnfe) {
7433                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7434            }
7435            return false;
7436        }
7437    }
7438
7439    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7440        @Override
7441        public int checkComponentPermission(String permission, int pid, int uid,
7442                int owningUid, boolean exported) {
7443            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7444                    owningUid, exported);
7445        }
7446
7447        @Override
7448        public Object getAMSLock() {
7449            return ActivityManagerService.this;
7450        }
7451    }
7452
7453    /**
7454     * This can be called with or without the global lock held.
7455     */
7456    int checkComponentPermission(String permission, int pid, int uid,
7457            int owningUid, boolean exported) {
7458        if (pid == MY_PID) {
7459            return PackageManager.PERMISSION_GRANTED;
7460        }
7461        return ActivityManager.checkComponentPermission(permission, uid,
7462                owningUid, exported);
7463    }
7464
7465    /**
7466     * As the only public entry point for permissions checking, this method
7467     * can enforce the semantic that requesting a check on a null global
7468     * permission is automatically denied.  (Internally a null permission
7469     * string is used when calling {@link #checkComponentPermission} in cases
7470     * when only uid-based security is needed.)
7471     *
7472     * This can be called with or without the global lock held.
7473     */
7474    @Override
7475    public int checkPermission(String permission, int pid, int uid) {
7476        if (permission == null) {
7477            return PackageManager.PERMISSION_DENIED;
7478        }
7479        return checkComponentPermission(permission, pid, uid, -1, true);
7480    }
7481
7482    @Override
7483    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7484        if (permission == null) {
7485            return PackageManager.PERMISSION_DENIED;
7486        }
7487
7488        // We might be performing an operation on behalf of an indirect binder
7489        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7490        // client identity accordingly before proceeding.
7491        Identity tlsIdentity = sCallerIdentity.get();
7492        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7493            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7494                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7495            uid = tlsIdentity.uid;
7496            pid = tlsIdentity.pid;
7497        }
7498
7499        return checkComponentPermission(permission, pid, uid, -1, true);
7500    }
7501
7502    /**
7503     * Binder IPC calls go through the public entry point.
7504     * This can be called with or without the global lock held.
7505     */
7506    int checkCallingPermission(String permission) {
7507        return checkPermission(permission,
7508                Binder.getCallingPid(),
7509                UserHandle.getAppId(Binder.getCallingUid()));
7510    }
7511
7512    /**
7513     * This can be called with or without the global lock held.
7514     */
7515    void enforceCallingPermission(String permission, String func) {
7516        if (checkCallingPermission(permission)
7517                == PackageManager.PERMISSION_GRANTED) {
7518            return;
7519        }
7520
7521        String msg = "Permission Denial: " + func + " from pid="
7522                + Binder.getCallingPid()
7523                + ", uid=" + Binder.getCallingUid()
7524                + " requires " + permission;
7525        Slog.w(TAG, msg);
7526        throw new SecurityException(msg);
7527    }
7528
7529    /**
7530     * Determine if UID is holding permissions required to access {@link Uri} in
7531     * the given {@link ProviderInfo}. Final permission checking is always done
7532     * in {@link ContentProvider}.
7533     */
7534    private final boolean checkHoldingPermissionsLocked(
7535            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7536        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7537                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7538        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7539            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7540                    != PERMISSION_GRANTED) {
7541                return false;
7542            }
7543        }
7544        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7545    }
7546
7547    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7548            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7549        if (pi.applicationInfo.uid == uid) {
7550            return true;
7551        } else if (!pi.exported) {
7552            return false;
7553        }
7554
7555        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7556        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7557        try {
7558            // check if target holds top-level <provider> permissions
7559            if (!readMet && pi.readPermission != null && considerUidPermissions
7560                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7561                readMet = true;
7562            }
7563            if (!writeMet && pi.writePermission != null && considerUidPermissions
7564                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7565                writeMet = true;
7566            }
7567
7568            // track if unprotected read/write is allowed; any denied
7569            // <path-permission> below removes this ability
7570            boolean allowDefaultRead = pi.readPermission == null;
7571            boolean allowDefaultWrite = pi.writePermission == null;
7572
7573            // check if target holds any <path-permission> that match uri
7574            final PathPermission[] pps = pi.pathPermissions;
7575            if (pps != null) {
7576                final String path = grantUri.uri.getPath();
7577                int i = pps.length;
7578                while (i > 0 && (!readMet || !writeMet)) {
7579                    i--;
7580                    PathPermission pp = pps[i];
7581                    if (pp.match(path)) {
7582                        if (!readMet) {
7583                            final String pprperm = pp.getReadPermission();
7584                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7585                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7586                                    + ": match=" + pp.match(path)
7587                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7588                            if (pprperm != null) {
7589                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7590                                        == PERMISSION_GRANTED) {
7591                                    readMet = true;
7592                                } else {
7593                                    allowDefaultRead = false;
7594                                }
7595                            }
7596                        }
7597                        if (!writeMet) {
7598                            final String ppwperm = pp.getWritePermission();
7599                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7600                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7601                                    + ": match=" + pp.match(path)
7602                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7603                            if (ppwperm != null) {
7604                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7605                                        == PERMISSION_GRANTED) {
7606                                    writeMet = true;
7607                                } else {
7608                                    allowDefaultWrite = false;
7609                                }
7610                            }
7611                        }
7612                    }
7613                }
7614            }
7615
7616            // grant unprotected <provider> read/write, if not blocked by
7617            // <path-permission> above
7618            if (allowDefaultRead) readMet = true;
7619            if (allowDefaultWrite) writeMet = true;
7620
7621        } catch (RemoteException e) {
7622            return false;
7623        }
7624
7625        return readMet && writeMet;
7626    }
7627
7628    public int getAppStartMode(int uid, String packageName) {
7629        synchronized (this) {
7630            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7631        }
7632    }
7633
7634    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7635            boolean allowWhenForeground) {
7636        UidRecord uidRec = mActiveUids.get(uid);
7637        if (!mLenientBackgroundCheck) {
7638            if (!allowWhenForeground || uidRec == null
7639                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7640                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7641                        packageName) != AppOpsManager.MODE_ALLOWED) {
7642                    return ActivityManager.APP_START_MODE_DELAYED;
7643                }
7644            }
7645
7646        } else if (uidRec == null || uidRec.idle) {
7647            if (callingPid >= 0) {
7648                ProcessRecord proc;
7649                synchronized (mPidsSelfLocked) {
7650                    proc = mPidsSelfLocked.get(callingPid);
7651                }
7652                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7653                    // Whoever is instigating this is in the foreground, so we will allow it
7654                    // to go through.
7655                    return ActivityManager.APP_START_MODE_NORMAL;
7656                }
7657            }
7658            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7659                    != AppOpsManager.MODE_ALLOWED) {
7660                return ActivityManager.APP_START_MODE_DELAYED;
7661            }
7662        }
7663        return ActivityManager.APP_START_MODE_NORMAL;
7664    }
7665
7666    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7667        ProviderInfo pi = null;
7668        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7669        if (cpr != null) {
7670            pi = cpr.info;
7671        } else {
7672            try {
7673                pi = AppGlobals.getPackageManager().resolveContentProvider(
7674                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7675            } catch (RemoteException ex) {
7676            }
7677        }
7678        return pi;
7679    }
7680
7681    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7682        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7683        if (targetUris != null) {
7684            return targetUris.get(grantUri);
7685        }
7686        return null;
7687    }
7688
7689    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7690            String targetPkg, int targetUid, GrantUri grantUri) {
7691        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7692        if (targetUris == null) {
7693            targetUris = Maps.newArrayMap();
7694            mGrantedUriPermissions.put(targetUid, targetUris);
7695        }
7696
7697        UriPermission perm = targetUris.get(grantUri);
7698        if (perm == null) {
7699            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7700            targetUris.put(grantUri, perm);
7701        }
7702
7703        return perm;
7704    }
7705
7706    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7707            final int modeFlags) {
7708        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7709        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7710                : UriPermission.STRENGTH_OWNED;
7711
7712        // Root gets to do everything.
7713        if (uid == 0) {
7714            return true;
7715        }
7716
7717        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7718        if (perms == null) return false;
7719
7720        // First look for exact match
7721        final UriPermission exactPerm = perms.get(grantUri);
7722        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7723            return true;
7724        }
7725
7726        // No exact match, look for prefixes
7727        final int N = perms.size();
7728        for (int i = 0; i < N; i++) {
7729            final UriPermission perm = perms.valueAt(i);
7730            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7731                    && perm.getStrength(modeFlags) >= minStrength) {
7732                return true;
7733            }
7734        }
7735
7736        return false;
7737    }
7738
7739    /**
7740     * @param uri This uri must NOT contain an embedded userId.
7741     * @param userId The userId in which the uri is to be resolved.
7742     */
7743    @Override
7744    public int checkUriPermission(Uri uri, int pid, int uid,
7745            final int modeFlags, int userId, IBinder callerToken) {
7746        enforceNotIsolatedCaller("checkUriPermission");
7747
7748        // Another redirected-binder-call permissions check as in
7749        // {@link checkPermissionWithToken}.
7750        Identity tlsIdentity = sCallerIdentity.get();
7751        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7752            uid = tlsIdentity.uid;
7753            pid = tlsIdentity.pid;
7754        }
7755
7756        // Our own process gets to do everything.
7757        if (pid == MY_PID) {
7758            return PackageManager.PERMISSION_GRANTED;
7759        }
7760        synchronized (this) {
7761            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7762                    ? PackageManager.PERMISSION_GRANTED
7763                    : PackageManager.PERMISSION_DENIED;
7764        }
7765    }
7766
7767    /**
7768     * Check if the targetPkg can be granted permission to access uri by
7769     * the callingUid using the given modeFlags.  Throws a security exception
7770     * if callingUid is not allowed to do this.  Returns the uid of the target
7771     * if the URI permission grant should be performed; returns -1 if it is not
7772     * needed (for example targetPkg already has permission to access the URI).
7773     * If you already know the uid of the target, you can supply it in
7774     * lastTargetUid else set that to -1.
7775     */
7776    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7777            final int modeFlags, int lastTargetUid) {
7778        if (!Intent.isAccessUriMode(modeFlags)) {
7779            return -1;
7780        }
7781
7782        if (targetPkg != null) {
7783            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7784                    "Checking grant " + targetPkg + " permission to " + grantUri);
7785        }
7786
7787        final IPackageManager pm = AppGlobals.getPackageManager();
7788
7789        // If this is not a content: uri, we can't do anything with it.
7790        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7791            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7792                    "Can't grant URI permission for non-content URI: " + grantUri);
7793            return -1;
7794        }
7795
7796        final String authority = grantUri.uri.getAuthority();
7797        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7798        if (pi == null) {
7799            Slog.w(TAG, "No content provider found for permission check: " +
7800                    grantUri.uri.toSafeString());
7801            return -1;
7802        }
7803
7804        int targetUid = lastTargetUid;
7805        if (targetUid < 0 && targetPkg != null) {
7806            try {
7807                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7808                        UserHandle.getUserId(callingUid));
7809                if (targetUid < 0) {
7810                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7811                            "Can't grant URI permission no uid for: " + targetPkg);
7812                    return -1;
7813                }
7814            } catch (RemoteException ex) {
7815                return -1;
7816            }
7817        }
7818
7819        if (targetUid >= 0) {
7820            // First...  does the target actually need this permission?
7821            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7822                // No need to grant the target this permission.
7823                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7824                        "Target " + targetPkg + " already has full permission to " + grantUri);
7825                return -1;
7826            }
7827        } else {
7828            // First...  there is no target package, so can anyone access it?
7829            boolean allowed = pi.exported;
7830            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7831                if (pi.readPermission != null) {
7832                    allowed = false;
7833                }
7834            }
7835            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7836                if (pi.writePermission != null) {
7837                    allowed = false;
7838                }
7839            }
7840            if (allowed) {
7841                return -1;
7842            }
7843        }
7844
7845        /* There is a special cross user grant if:
7846         * - The target is on another user.
7847         * - Apps on the current user can access the uri without any uid permissions.
7848         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7849         * grant uri permissions.
7850         */
7851        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7852                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7853                modeFlags, false /*without considering the uid permissions*/);
7854
7855        // Second...  is the provider allowing granting of URI permissions?
7856        if (!specialCrossUserGrant) {
7857            if (!pi.grantUriPermissions) {
7858                throw new SecurityException("Provider " + pi.packageName
7859                        + "/" + pi.name
7860                        + " does not allow granting of Uri permissions (uri "
7861                        + grantUri + ")");
7862            }
7863            if (pi.uriPermissionPatterns != null) {
7864                final int N = pi.uriPermissionPatterns.length;
7865                boolean allowed = false;
7866                for (int i=0; i<N; i++) {
7867                    if (pi.uriPermissionPatterns[i] != null
7868                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7869                        allowed = true;
7870                        break;
7871                    }
7872                }
7873                if (!allowed) {
7874                    throw new SecurityException("Provider " + pi.packageName
7875                            + "/" + pi.name
7876                            + " does not allow granting of permission to path of Uri "
7877                            + grantUri);
7878                }
7879            }
7880        }
7881
7882        // Third...  does the caller itself have permission to access
7883        // this uri?
7884        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7885            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7886                // Require they hold a strong enough Uri permission
7887                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7888                    throw new SecurityException("Uid " + callingUid
7889                            + " does not have permission to uri " + grantUri);
7890                }
7891            }
7892        }
7893        return targetUid;
7894    }
7895
7896    /**
7897     * @param uri This uri must NOT contain an embedded userId.
7898     * @param userId The userId in which the uri is to be resolved.
7899     */
7900    @Override
7901    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7902            final int modeFlags, int userId) {
7903        enforceNotIsolatedCaller("checkGrantUriPermission");
7904        synchronized(this) {
7905            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7906                    new GrantUri(userId, uri, false), modeFlags, -1);
7907        }
7908    }
7909
7910    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7911            final int modeFlags, UriPermissionOwner owner) {
7912        if (!Intent.isAccessUriMode(modeFlags)) {
7913            return;
7914        }
7915
7916        // So here we are: the caller has the assumed permission
7917        // to the uri, and the target doesn't.  Let's now give this to
7918        // the target.
7919
7920        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7921                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7922
7923        final String authority = grantUri.uri.getAuthority();
7924        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7925        if (pi == null) {
7926            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7927            return;
7928        }
7929
7930        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7931            grantUri.prefix = true;
7932        }
7933        final UriPermission perm = findOrCreateUriPermissionLocked(
7934                pi.packageName, targetPkg, targetUid, grantUri);
7935        perm.grantModes(modeFlags, owner);
7936    }
7937
7938    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7939            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7940        if (targetPkg == null) {
7941            throw new NullPointerException("targetPkg");
7942        }
7943        int targetUid;
7944        final IPackageManager pm = AppGlobals.getPackageManager();
7945        try {
7946            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7947        } catch (RemoteException ex) {
7948            return;
7949        }
7950
7951        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7952                targetUid);
7953        if (targetUid < 0) {
7954            return;
7955        }
7956
7957        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7958                owner);
7959    }
7960
7961    static class NeededUriGrants extends ArrayList<GrantUri> {
7962        final String targetPkg;
7963        final int targetUid;
7964        final int flags;
7965
7966        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7967            this.targetPkg = targetPkg;
7968            this.targetUid = targetUid;
7969            this.flags = flags;
7970        }
7971    }
7972
7973    /**
7974     * Like checkGrantUriPermissionLocked, but takes an Intent.
7975     */
7976    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7977            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7978        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7979                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7980                + " clip=" + (intent != null ? intent.getClipData() : null)
7981                + " from " + intent + "; flags=0x"
7982                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7983
7984        if (targetPkg == null) {
7985            throw new NullPointerException("targetPkg");
7986        }
7987
7988        if (intent == null) {
7989            return null;
7990        }
7991        Uri data = intent.getData();
7992        ClipData clip = intent.getClipData();
7993        if (data == null && clip == null) {
7994            return null;
7995        }
7996        // Default userId for uris in the intent (if they don't specify it themselves)
7997        int contentUserHint = intent.getContentUserHint();
7998        if (contentUserHint == UserHandle.USER_CURRENT) {
7999            contentUserHint = UserHandle.getUserId(callingUid);
8000        }
8001        final IPackageManager pm = AppGlobals.getPackageManager();
8002        int targetUid;
8003        if (needed != null) {
8004            targetUid = needed.targetUid;
8005        } else {
8006            try {
8007                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8008                        targetUserId);
8009            } catch (RemoteException ex) {
8010                return null;
8011            }
8012            if (targetUid < 0) {
8013                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                        "Can't grant URI permission no uid for: " + targetPkg
8015                        + " on user " + targetUserId);
8016                return null;
8017            }
8018        }
8019        if (data != null) {
8020            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8021            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8022                    targetUid);
8023            if (targetUid > 0) {
8024                if (needed == null) {
8025                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8026                }
8027                needed.add(grantUri);
8028            }
8029        }
8030        if (clip != null) {
8031            for (int i=0; i<clip.getItemCount(); i++) {
8032                Uri uri = clip.getItemAt(i).getUri();
8033                if (uri != null) {
8034                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8035                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8036                            targetUid);
8037                    if (targetUid > 0) {
8038                        if (needed == null) {
8039                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8040                        }
8041                        needed.add(grantUri);
8042                    }
8043                } else {
8044                    Intent clipIntent = clip.getItemAt(i).getIntent();
8045                    if (clipIntent != null) {
8046                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8047                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8048                        if (newNeeded != null) {
8049                            needed = newNeeded;
8050                        }
8051                    }
8052                }
8053            }
8054        }
8055
8056        return needed;
8057    }
8058
8059    /**
8060     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8061     */
8062    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8063            UriPermissionOwner owner) {
8064        if (needed != null) {
8065            for (int i=0; i<needed.size(); i++) {
8066                GrantUri grantUri = needed.get(i);
8067                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8068                        grantUri, needed.flags, owner);
8069            }
8070        }
8071    }
8072
8073    void grantUriPermissionFromIntentLocked(int callingUid,
8074            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8075        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8076                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8077        if (needed == null) {
8078            return;
8079        }
8080
8081        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8082    }
8083
8084    /**
8085     * @param uri This uri must NOT contain an embedded userId.
8086     * @param userId The userId in which the uri is to be resolved.
8087     */
8088    @Override
8089    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8090            final int modeFlags, int userId) {
8091        enforceNotIsolatedCaller("grantUriPermission");
8092        GrantUri grantUri = new GrantUri(userId, uri, false);
8093        synchronized(this) {
8094            final ProcessRecord r = getRecordForAppLocked(caller);
8095            if (r == null) {
8096                throw new SecurityException("Unable to find app for caller "
8097                        + caller
8098                        + " when granting permission to uri " + grantUri);
8099            }
8100            if (targetPkg == null) {
8101                throw new IllegalArgumentException("null target");
8102            }
8103            if (grantUri == null) {
8104                throw new IllegalArgumentException("null uri");
8105            }
8106
8107            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8108                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8109                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8110                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8111
8112            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8113                    UserHandle.getUserId(r.uid));
8114        }
8115    }
8116
8117    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8118        if (perm.modeFlags == 0) {
8119            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8120                    perm.targetUid);
8121            if (perms != null) {
8122                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8123                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8124
8125                perms.remove(perm.uri);
8126                if (perms.isEmpty()) {
8127                    mGrantedUriPermissions.remove(perm.targetUid);
8128                }
8129            }
8130        }
8131    }
8132
8133    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8134        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8135                "Revoking all granted permissions to " + grantUri);
8136
8137        final IPackageManager pm = AppGlobals.getPackageManager();
8138        final String authority = grantUri.uri.getAuthority();
8139        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8140        if (pi == null) {
8141            Slog.w(TAG, "No content provider found for permission revoke: "
8142                    + grantUri.toSafeString());
8143            return;
8144        }
8145
8146        // Does the caller have this permission on the URI?
8147        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8148            // If they don't have direct access to the URI, then revoke any
8149            // ownerless URI permissions that have been granted to them.
8150            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8151            if (perms != null) {
8152                boolean persistChanged = false;
8153                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8154                    final UriPermission perm = it.next();
8155                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8156                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8157                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158                                "Revoking non-owned " + perm.targetUid
8159                                + " permission to " + perm.uri);
8160                        persistChanged |= perm.revokeModes(
8161                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8162                        if (perm.modeFlags == 0) {
8163                            it.remove();
8164                        }
8165                    }
8166                }
8167                if (perms.isEmpty()) {
8168                    mGrantedUriPermissions.remove(callingUid);
8169                }
8170                if (persistChanged) {
8171                    schedulePersistUriGrants();
8172                }
8173            }
8174            return;
8175        }
8176
8177        boolean persistChanged = false;
8178
8179        // Go through all of the permissions and remove any that match.
8180        int N = mGrantedUriPermissions.size();
8181        for (int i = 0; i < N; i++) {
8182            final int targetUid = mGrantedUriPermissions.keyAt(i);
8183            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8184
8185            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8186                final UriPermission perm = it.next();
8187                if (perm.uri.sourceUserId == grantUri.sourceUserId
8188                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8189                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8191                    persistChanged |= perm.revokeModes(
8192                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8193                    if (perm.modeFlags == 0) {
8194                        it.remove();
8195                    }
8196                }
8197            }
8198
8199            if (perms.isEmpty()) {
8200                mGrantedUriPermissions.remove(targetUid);
8201                N--;
8202                i--;
8203            }
8204        }
8205
8206        if (persistChanged) {
8207            schedulePersistUriGrants();
8208        }
8209    }
8210
8211    /**
8212     * @param uri This uri must NOT contain an embedded userId.
8213     * @param userId The userId in which the uri is to be resolved.
8214     */
8215    @Override
8216    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8217            int userId) {
8218        enforceNotIsolatedCaller("revokeUriPermission");
8219        synchronized(this) {
8220            final ProcessRecord r = getRecordForAppLocked(caller);
8221            if (r == null) {
8222                throw new SecurityException("Unable to find app for caller "
8223                        + caller
8224                        + " when revoking permission to uri " + uri);
8225            }
8226            if (uri == null) {
8227                Slog.w(TAG, "revokeUriPermission: null uri");
8228                return;
8229            }
8230
8231            if (!Intent.isAccessUriMode(modeFlags)) {
8232                return;
8233            }
8234
8235            final String authority = uri.getAuthority();
8236            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8237            if (pi == null) {
8238                Slog.w(TAG, "No content provider found for permission revoke: "
8239                        + uri.toSafeString());
8240                return;
8241            }
8242
8243            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8244        }
8245    }
8246
8247    /**
8248     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8249     * given package.
8250     *
8251     * @param packageName Package name to match, or {@code null} to apply to all
8252     *            packages.
8253     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8254     *            to all users.
8255     * @param persistable If persistable grants should be removed.
8256     */
8257    private void removeUriPermissionsForPackageLocked(
8258            String packageName, int userHandle, boolean persistable) {
8259        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8260            throw new IllegalArgumentException("Must narrow by either package or user");
8261        }
8262
8263        boolean persistChanged = false;
8264
8265        int N = mGrantedUriPermissions.size();
8266        for (int i = 0; i < N; i++) {
8267            final int targetUid = mGrantedUriPermissions.keyAt(i);
8268            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8269
8270            // Only inspect grants matching user
8271            if (userHandle == UserHandle.USER_ALL
8272                    || userHandle == UserHandle.getUserId(targetUid)) {
8273                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8274                    final UriPermission perm = it.next();
8275
8276                    // Only inspect grants matching package
8277                    if (packageName == null || perm.sourcePkg.equals(packageName)
8278                            || perm.targetPkg.equals(packageName)) {
8279                        persistChanged |= perm.revokeModes(persistable
8280                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8281
8282                        // Only remove when no modes remain; any persisted grants
8283                        // will keep this alive.
8284                        if (perm.modeFlags == 0) {
8285                            it.remove();
8286                        }
8287                    }
8288                }
8289
8290                if (perms.isEmpty()) {
8291                    mGrantedUriPermissions.remove(targetUid);
8292                    N--;
8293                    i--;
8294                }
8295            }
8296        }
8297
8298        if (persistChanged) {
8299            schedulePersistUriGrants();
8300        }
8301    }
8302
8303    @Override
8304    public IBinder newUriPermissionOwner(String name) {
8305        enforceNotIsolatedCaller("newUriPermissionOwner");
8306        synchronized(this) {
8307            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8308            return owner.getExternalTokenLocked();
8309        }
8310    }
8311
8312    @Override
8313    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8314        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8315        synchronized(this) {
8316            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8317            if (r == null) {
8318                throw new IllegalArgumentException("Activity does not exist; token="
8319                        + activityToken);
8320            }
8321            return r.getUriPermissionsLocked().getExternalTokenLocked();
8322        }
8323    }
8324    /**
8325     * @param uri This uri must NOT contain an embedded userId.
8326     * @param sourceUserId The userId in which the uri is to be resolved.
8327     * @param targetUserId The userId of the app that receives the grant.
8328     */
8329    @Override
8330    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8331            final int modeFlags, int sourceUserId, int targetUserId) {
8332        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8333                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8334                "grantUriPermissionFromOwner", null);
8335        synchronized(this) {
8336            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8337            if (owner == null) {
8338                throw new IllegalArgumentException("Unknown owner: " + token);
8339            }
8340            if (fromUid != Binder.getCallingUid()) {
8341                if (Binder.getCallingUid() != Process.myUid()) {
8342                    // Only system code can grant URI permissions on behalf
8343                    // of other users.
8344                    throw new SecurityException("nice try");
8345                }
8346            }
8347            if (targetPkg == null) {
8348                throw new IllegalArgumentException("null target");
8349            }
8350            if (uri == null) {
8351                throw new IllegalArgumentException("null uri");
8352            }
8353
8354            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8355                    modeFlags, owner, targetUserId);
8356        }
8357    }
8358
8359    /**
8360     * @param uri This uri must NOT contain an embedded userId.
8361     * @param userId The userId in which the uri is to be resolved.
8362     */
8363    @Override
8364    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8365        synchronized(this) {
8366            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8367            if (owner == null) {
8368                throw new IllegalArgumentException("Unknown owner: " + token);
8369            }
8370
8371            if (uri == null) {
8372                owner.removeUriPermissionsLocked(mode);
8373            } else {
8374                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8375            }
8376        }
8377    }
8378
8379    private void schedulePersistUriGrants() {
8380        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8381            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8382                    10 * DateUtils.SECOND_IN_MILLIS);
8383        }
8384    }
8385
8386    private void writeGrantedUriPermissions() {
8387        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8388
8389        // Snapshot permissions so we can persist without lock
8390        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8391        synchronized (this) {
8392            final int size = mGrantedUriPermissions.size();
8393            for (int i = 0; i < size; i++) {
8394                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8395                for (UriPermission perm : perms.values()) {
8396                    if (perm.persistedModeFlags != 0) {
8397                        persist.add(perm.snapshot());
8398                    }
8399                }
8400            }
8401        }
8402
8403        FileOutputStream fos = null;
8404        try {
8405            fos = mGrantFile.startWrite();
8406
8407            XmlSerializer out = new FastXmlSerializer();
8408            out.setOutput(fos, StandardCharsets.UTF_8.name());
8409            out.startDocument(null, true);
8410            out.startTag(null, TAG_URI_GRANTS);
8411            for (UriPermission.Snapshot perm : persist) {
8412                out.startTag(null, TAG_URI_GRANT);
8413                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8414                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8415                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8416                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8417                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8418                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8419                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8420                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8421                out.endTag(null, TAG_URI_GRANT);
8422            }
8423            out.endTag(null, TAG_URI_GRANTS);
8424            out.endDocument();
8425
8426            mGrantFile.finishWrite(fos);
8427        } catch (IOException e) {
8428            if (fos != null) {
8429                mGrantFile.failWrite(fos);
8430            }
8431        }
8432    }
8433
8434    private void readGrantedUriPermissionsLocked() {
8435        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8436
8437        final long now = System.currentTimeMillis();
8438
8439        FileInputStream fis = null;
8440        try {
8441            fis = mGrantFile.openRead();
8442            final XmlPullParser in = Xml.newPullParser();
8443            in.setInput(fis, StandardCharsets.UTF_8.name());
8444
8445            int type;
8446            while ((type = in.next()) != END_DOCUMENT) {
8447                final String tag = in.getName();
8448                if (type == START_TAG) {
8449                    if (TAG_URI_GRANT.equals(tag)) {
8450                        final int sourceUserId;
8451                        final int targetUserId;
8452                        final int userHandle = readIntAttribute(in,
8453                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8454                        if (userHandle != UserHandle.USER_NULL) {
8455                            // For backwards compatibility.
8456                            sourceUserId = userHandle;
8457                            targetUserId = userHandle;
8458                        } else {
8459                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8460                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8461                        }
8462                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8463                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8464                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8465                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8466                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8467                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8468
8469                        // Sanity check that provider still belongs to source package
8470                        final ProviderInfo pi = getProviderInfoLocked(
8471                                uri.getAuthority(), sourceUserId);
8472                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8473                            int targetUid = -1;
8474                            try {
8475                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8476                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8477                            } catch (RemoteException e) {
8478                            }
8479                            if (targetUid != -1) {
8480                                final UriPermission perm = findOrCreateUriPermissionLocked(
8481                                        sourcePkg, targetPkg, targetUid,
8482                                        new GrantUri(sourceUserId, uri, prefix));
8483                                perm.initPersistedModes(modeFlags, createdTime);
8484                            }
8485                        } else {
8486                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8487                                    + " but instead found " + pi);
8488                        }
8489                    }
8490                }
8491            }
8492        } catch (FileNotFoundException e) {
8493            // Missing grants is okay
8494        } catch (IOException e) {
8495            Slog.wtf(TAG, "Failed reading Uri grants", e);
8496        } catch (XmlPullParserException e) {
8497            Slog.wtf(TAG, "Failed reading Uri grants", e);
8498        } finally {
8499            IoUtils.closeQuietly(fis);
8500        }
8501    }
8502
8503    /**
8504     * @param uri This uri must NOT contain an embedded userId.
8505     * @param userId The userId in which the uri is to be resolved.
8506     */
8507    @Override
8508    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8509        enforceNotIsolatedCaller("takePersistableUriPermission");
8510
8511        Preconditions.checkFlagsArgument(modeFlags,
8512                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8513
8514        synchronized (this) {
8515            final int callingUid = Binder.getCallingUid();
8516            boolean persistChanged = false;
8517            GrantUri grantUri = new GrantUri(userId, uri, false);
8518
8519            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8520                    new GrantUri(userId, uri, false));
8521            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8522                    new GrantUri(userId, uri, true));
8523
8524            final boolean exactValid = (exactPerm != null)
8525                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8526            final boolean prefixValid = (prefixPerm != null)
8527                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8528
8529            if (!(exactValid || prefixValid)) {
8530                throw new SecurityException("No persistable permission grants found for UID "
8531                        + callingUid + " and Uri " + grantUri.toSafeString());
8532            }
8533
8534            if (exactValid) {
8535                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8536            }
8537            if (prefixValid) {
8538                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8539            }
8540
8541            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8542
8543            if (persistChanged) {
8544                schedulePersistUriGrants();
8545            }
8546        }
8547    }
8548
8549    /**
8550     * @param uri This uri must NOT contain an embedded userId.
8551     * @param userId The userId in which the uri is to be resolved.
8552     */
8553    @Override
8554    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8555        enforceNotIsolatedCaller("releasePersistableUriPermission");
8556
8557        Preconditions.checkFlagsArgument(modeFlags,
8558                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8559
8560        synchronized (this) {
8561            final int callingUid = Binder.getCallingUid();
8562            boolean persistChanged = false;
8563
8564            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8565                    new GrantUri(userId, uri, false));
8566            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8567                    new GrantUri(userId, uri, true));
8568            if (exactPerm == null && prefixPerm == null) {
8569                throw new SecurityException("No permission grants found for UID " + callingUid
8570                        + " and Uri " + uri.toSafeString());
8571            }
8572
8573            if (exactPerm != null) {
8574                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8575                removeUriPermissionIfNeededLocked(exactPerm);
8576            }
8577            if (prefixPerm != null) {
8578                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8579                removeUriPermissionIfNeededLocked(prefixPerm);
8580            }
8581
8582            if (persistChanged) {
8583                schedulePersistUriGrants();
8584            }
8585        }
8586    }
8587
8588    /**
8589     * Prune any older {@link UriPermission} for the given UID until outstanding
8590     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8591     *
8592     * @return if any mutations occured that require persisting.
8593     */
8594    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8595        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8596        if (perms == null) return false;
8597        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8598
8599        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8600        for (UriPermission perm : perms.values()) {
8601            if (perm.persistedModeFlags != 0) {
8602                persisted.add(perm);
8603            }
8604        }
8605
8606        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8607        if (trimCount <= 0) return false;
8608
8609        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8610        for (int i = 0; i < trimCount; i++) {
8611            final UriPermission perm = persisted.get(i);
8612
8613            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8614                    "Trimming grant created at " + perm.persistedCreateTime);
8615
8616            perm.releasePersistableModes(~0);
8617            removeUriPermissionIfNeededLocked(perm);
8618        }
8619
8620        return true;
8621    }
8622
8623    @Override
8624    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8625            String packageName, boolean incoming) {
8626        enforceNotIsolatedCaller("getPersistedUriPermissions");
8627        Preconditions.checkNotNull(packageName, "packageName");
8628
8629        final int callingUid = Binder.getCallingUid();
8630        final IPackageManager pm = AppGlobals.getPackageManager();
8631        try {
8632            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8633                    UserHandle.getUserId(callingUid));
8634            if (packageUid != callingUid) {
8635                throw new SecurityException(
8636                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8637            }
8638        } catch (RemoteException e) {
8639            throw new SecurityException("Failed to verify package name ownership");
8640        }
8641
8642        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8643        synchronized (this) {
8644            if (incoming) {
8645                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8646                        callingUid);
8647                if (perms == null) {
8648                    Slog.w(TAG, "No permission grants found for " + packageName);
8649                } else {
8650                    for (UriPermission perm : perms.values()) {
8651                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8652                            result.add(perm.buildPersistedPublicApiObject());
8653                        }
8654                    }
8655                }
8656            } else {
8657                final int size = mGrantedUriPermissions.size();
8658                for (int i = 0; i < size; i++) {
8659                    final ArrayMap<GrantUri, UriPermission> perms =
8660                            mGrantedUriPermissions.valueAt(i);
8661                    for (UriPermission perm : perms.values()) {
8662                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8663                            result.add(perm.buildPersistedPublicApiObject());
8664                        }
8665                    }
8666                }
8667            }
8668        }
8669        return new ParceledListSlice<android.content.UriPermission>(result);
8670    }
8671
8672    @Override
8673    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8674            String packageName, int userId) {
8675        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8676                "getGrantedUriPermissions");
8677
8678        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8679        synchronized (this) {
8680            final int size = mGrantedUriPermissions.size();
8681            for (int i = 0; i < size; i++) {
8682                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8683                for (UriPermission perm : perms.values()) {
8684                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8685                            && perm.persistedModeFlags != 0) {
8686                        result.add(perm.buildPersistedPublicApiObject());
8687                    }
8688                }
8689            }
8690        }
8691        return new ParceledListSlice<android.content.UriPermission>(result);
8692    }
8693
8694    @Override
8695    public void clearGrantedUriPermissions(String packageName, int userId) {
8696        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8697                "clearGrantedUriPermissions");
8698        removeUriPermissionsForPackageLocked(packageName, userId, true);
8699    }
8700
8701    @Override
8702    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8703        synchronized (this) {
8704            ProcessRecord app =
8705                who != null ? getRecordForAppLocked(who) : null;
8706            if (app == null) return;
8707
8708            Message msg = Message.obtain();
8709            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8710            msg.obj = app;
8711            msg.arg1 = waiting ? 1 : 0;
8712            mUiHandler.sendMessage(msg);
8713        }
8714    }
8715
8716    @Override
8717    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8718        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8719        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8720        outInfo.availMem = Process.getFreeMemory();
8721        outInfo.totalMem = Process.getTotalMemory();
8722        outInfo.threshold = homeAppMem;
8723        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8724        outInfo.hiddenAppThreshold = cachedAppMem;
8725        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8726                ProcessList.SERVICE_ADJ);
8727        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8728                ProcessList.VISIBLE_APP_ADJ);
8729        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8730                ProcessList.FOREGROUND_APP_ADJ);
8731    }
8732
8733    // =========================================================
8734    // TASK MANAGEMENT
8735    // =========================================================
8736
8737    @Override
8738    public List<IAppTask> getAppTasks(String callingPackage) {
8739        int callingUid = Binder.getCallingUid();
8740        long ident = Binder.clearCallingIdentity();
8741
8742        synchronized(this) {
8743            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8744            try {
8745                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8746
8747                final int N = mRecentTasks.size();
8748                for (int i = 0; i < N; i++) {
8749                    TaskRecord tr = mRecentTasks.get(i);
8750                    // Skip tasks that do not match the caller.  We don't need to verify
8751                    // callingPackage, because we are also limiting to callingUid and know
8752                    // that will limit to the correct security sandbox.
8753                    if (tr.effectiveUid != callingUid) {
8754                        continue;
8755                    }
8756                    Intent intent = tr.getBaseIntent();
8757                    if (intent == null ||
8758                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8759                        continue;
8760                    }
8761                    ActivityManager.RecentTaskInfo taskInfo =
8762                            createRecentTaskInfoFromTaskRecord(tr);
8763                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8764                    list.add(taskImpl);
8765                }
8766            } finally {
8767                Binder.restoreCallingIdentity(ident);
8768            }
8769            return list;
8770        }
8771    }
8772
8773    @Override
8774    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8775        final int callingUid = Binder.getCallingUid();
8776        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8777
8778        synchronized(this) {
8779            if (DEBUG_ALL) Slog.v(
8780                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8781
8782            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8783                    callingUid);
8784
8785            // TODO: Improve with MRU list from all ActivityStacks.
8786            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8787        }
8788
8789        return list;
8790    }
8791
8792    /**
8793     * Creates a new RecentTaskInfo from a TaskRecord.
8794     */
8795    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8796        // Update the task description to reflect any changes in the task stack
8797        tr.updateTaskDescription();
8798
8799        // Compose the recent task info
8800        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8801        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8802        rti.persistentId = tr.taskId;
8803        rti.baseIntent = new Intent(tr.getBaseIntent());
8804        rti.origActivity = tr.origActivity;
8805        rti.realActivity = tr.realActivity;
8806        rti.description = tr.lastDescription;
8807        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8808        rti.userId = tr.userId;
8809        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8810        rti.firstActiveTime = tr.firstActiveTime;
8811        rti.lastActiveTime = tr.lastActiveTime;
8812        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8813        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8814        rti.numActivities = 0;
8815        if (tr.mBounds != null) {
8816            rti.bounds = new Rect(tr.mBounds);
8817        }
8818        rti.isDockable = tr.canGoInDockedStack();
8819        rti.resizeMode = tr.mResizeMode;
8820
8821        ActivityRecord base = null;
8822        ActivityRecord top = null;
8823        ActivityRecord tmp;
8824
8825        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8826            tmp = tr.mActivities.get(i);
8827            if (tmp.finishing) {
8828                continue;
8829            }
8830            base = tmp;
8831            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8832                top = base;
8833            }
8834            rti.numActivities++;
8835        }
8836
8837        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8838        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8839
8840        return rti;
8841    }
8842
8843    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8844        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8845                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8846        if (!allowed) {
8847            if (checkPermission(android.Manifest.permission.GET_TASKS,
8848                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8849                // Temporary compatibility: some existing apps on the system image may
8850                // still be requesting the old permission and not switched to the new
8851                // one; if so, we'll still allow them full access.  This means we need
8852                // to see if they are holding the old permission and are a system app.
8853                try {
8854                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8855                        allowed = true;
8856                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8857                                + " is using old GET_TASKS but privileged; allowing");
8858                    }
8859                } catch (RemoteException e) {
8860                }
8861            }
8862        }
8863        if (!allowed) {
8864            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8865                    + " does not hold REAL_GET_TASKS; limiting output");
8866        }
8867        return allowed;
8868    }
8869
8870    @Override
8871    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8872        final int callingUid = Binder.getCallingUid();
8873        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8874                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8875
8876        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8877        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8878        synchronized (this) {
8879            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8880                    callingUid);
8881            final boolean detailed = checkCallingPermission(
8882                    android.Manifest.permission.GET_DETAILED_TASKS)
8883                    == PackageManager.PERMISSION_GRANTED;
8884
8885            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8886                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8887                return Collections.emptyList();
8888            }
8889            mRecentTasks.loadUserRecentsLocked(userId);
8890
8891            final int recentsCount = mRecentTasks.size();
8892            ArrayList<ActivityManager.RecentTaskInfo> res =
8893                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8894
8895            final Set<Integer> includedUsers;
8896            if (includeProfiles) {
8897                includedUsers = mUserController.getProfileIds(userId);
8898            } else {
8899                includedUsers = new HashSet<>();
8900            }
8901            includedUsers.add(Integer.valueOf(userId));
8902
8903            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8904                TaskRecord tr = mRecentTasks.get(i);
8905                // Only add calling user or related users recent tasks
8906                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8907                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8908                    continue;
8909                }
8910
8911                if (tr.realActivitySuspended) {
8912                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8913                    continue;
8914                }
8915
8916                // Return the entry if desired by the caller.  We always return
8917                // the first entry, because callers always expect this to be the
8918                // foreground app.  We may filter others if the caller has
8919                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8920                // we should exclude the entry.
8921
8922                if (i == 0
8923                        || withExcluded
8924                        || (tr.intent == null)
8925                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8926                                == 0)) {
8927                    if (!allowed) {
8928                        // If the caller doesn't have the GET_TASKS permission, then only
8929                        // allow them to see a small subset of tasks -- their own and home.
8930                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8931                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8932                            continue;
8933                        }
8934                    }
8935                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8936                        if (tr.stack != null && tr.stack.isHomeStack()) {
8937                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8938                                    "Skipping, home stack task: " + tr);
8939                            continue;
8940                        }
8941                    }
8942                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8943                        final ActivityStack stack = tr.stack;
8944                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8945                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8946                                    "Skipping, top task in docked stack: " + tr);
8947                            continue;
8948                        }
8949                    }
8950                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8951                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8952                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8953                                    "Skipping, pinned stack task: " + tr);
8954                            continue;
8955                        }
8956                    }
8957                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8958                        // Don't include auto remove tasks that are finished or finishing.
8959                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8960                                "Skipping, auto-remove without activity: " + tr);
8961                        continue;
8962                    }
8963                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8964                            && !tr.isAvailable) {
8965                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8966                                "Skipping, unavail real act: " + tr);
8967                        continue;
8968                    }
8969
8970                    if (!tr.mUserSetupComplete) {
8971                        // Don't include task launched while user is not done setting-up.
8972                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8973                                "Skipping, user setup not complete: " + tr);
8974                        continue;
8975                    }
8976
8977                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8978                    if (!detailed) {
8979                        rti.baseIntent.replaceExtras((Bundle)null);
8980                    }
8981
8982                    res.add(rti);
8983                    maxNum--;
8984                }
8985            }
8986            return res;
8987        }
8988    }
8989
8990    @Override
8991    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8992        synchronized (this) {
8993            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8994                    "getTaskThumbnail()");
8995            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8996                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8997            if (tr != null) {
8998                return tr.getTaskThumbnailLocked();
8999            }
9000        }
9001        return null;
9002    }
9003
9004    @Override
9005    public int addAppTask(IBinder activityToken, Intent intent,
9006            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9007        final int callingUid = Binder.getCallingUid();
9008        final long callingIdent = Binder.clearCallingIdentity();
9009
9010        try {
9011            synchronized (this) {
9012                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9013                if (r == null) {
9014                    throw new IllegalArgumentException("Activity does not exist; token="
9015                            + activityToken);
9016                }
9017                ComponentName comp = intent.getComponent();
9018                if (comp == null) {
9019                    throw new IllegalArgumentException("Intent " + intent
9020                            + " must specify explicit component");
9021                }
9022                if (thumbnail.getWidth() != mThumbnailWidth
9023                        || thumbnail.getHeight() != mThumbnailHeight) {
9024                    throw new IllegalArgumentException("Bad thumbnail size: got "
9025                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9026                            + mThumbnailWidth + "x" + mThumbnailHeight);
9027                }
9028                if (intent.getSelector() != null) {
9029                    intent.setSelector(null);
9030                }
9031                if (intent.getSourceBounds() != null) {
9032                    intent.setSourceBounds(null);
9033                }
9034                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9035                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9036                        // The caller has added this as an auto-remove task...  that makes no
9037                        // sense, so turn off auto-remove.
9038                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9039                    }
9040                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9041                    // Must be a new task.
9042                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9043                }
9044                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9045                    mLastAddedTaskActivity = null;
9046                }
9047                ActivityInfo ainfo = mLastAddedTaskActivity;
9048                if (ainfo == null) {
9049                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9050                            comp, 0, UserHandle.getUserId(callingUid));
9051                    if (ainfo.applicationInfo.uid != callingUid) {
9052                        throw new SecurityException(
9053                                "Can't add task for another application: target uid="
9054                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9055                    }
9056                }
9057
9058                // Use the full screen as the context for the task thumbnail
9059                final Point displaySize = new Point();
9060                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9061                r.task.stack.getDisplaySize(displaySize);
9062                thumbnailInfo.taskWidth = displaySize.x;
9063                thumbnailInfo.taskHeight = displaySize.y;
9064                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9065
9066                TaskRecord task = new TaskRecord(this,
9067                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9068                        ainfo, intent, description, thumbnailInfo);
9069
9070                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9071                if (trimIdx >= 0) {
9072                    // If this would have caused a trim, then we'll abort because that
9073                    // means it would be added at the end of the list but then just removed.
9074                    return INVALID_TASK_ID;
9075                }
9076
9077                final int N = mRecentTasks.size();
9078                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9079                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9080                    tr.removedFromRecents();
9081                }
9082
9083                task.inRecents = true;
9084                mRecentTasks.add(task);
9085                r.task.stack.addTask(task, false, "addAppTask");
9086
9087                task.setLastThumbnailLocked(thumbnail);
9088                task.freeLastThumbnail();
9089
9090                return task.taskId;
9091            }
9092        } finally {
9093            Binder.restoreCallingIdentity(callingIdent);
9094        }
9095    }
9096
9097    @Override
9098    public Point getAppTaskThumbnailSize() {
9099        synchronized (this) {
9100            return new Point(mThumbnailWidth,  mThumbnailHeight);
9101        }
9102    }
9103
9104    @Override
9105    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9106        synchronized (this) {
9107            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9108            if (r != null) {
9109                r.setTaskDescription(td);
9110                r.task.updateTaskDescription();
9111            }
9112        }
9113    }
9114
9115    @Override
9116    public void setTaskResizeable(int taskId, int resizeableMode) {
9117        synchronized (this) {
9118            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9119                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9120            if (task == null) {
9121                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9122                return;
9123            }
9124            if (task.mResizeMode != resizeableMode) {
9125                task.mResizeMode = resizeableMode;
9126                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9127                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9128                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9129            }
9130        }
9131    }
9132
9133    @Override
9134    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9135        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9136        long ident = Binder.clearCallingIdentity();
9137        try {
9138            synchronized (this) {
9139                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9140                if (task == null) {
9141                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9142                    return;
9143                }
9144                int stackId = task.stack.mStackId;
9145                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9146                // in crop windows resize mode or if the task size is affected by the docked stack
9147                // changing size. No need to update configuration.
9148                if (bounds != null && task.inCropWindowsResizeMode()
9149                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9150                    mWindowManager.scrollTask(task.taskId, bounds);
9151                    return;
9152                }
9153
9154                // Place the task in the right stack if it isn't there already based on
9155                // the requested bounds.
9156                // The stack transition logic is:
9157                // - a null bounds on a freeform task moves that task to fullscreen
9158                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9159                //   that task to freeform
9160                // - otherwise the task is not moved
9161                if (!StackId.isTaskResizeAllowed(stackId)) {
9162                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9163                }
9164                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9165                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9166                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9167                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9168                }
9169                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9170                if (stackId != task.stack.mStackId) {
9171                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9172                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9173                    preserveWindow = false;
9174                }
9175
9176                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9177                        false /* deferResume */);
9178            }
9179        } finally {
9180            Binder.restoreCallingIdentity(ident);
9181        }
9182    }
9183
9184    @Override
9185    public Rect getTaskBounds(int taskId) {
9186        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9187        long ident = Binder.clearCallingIdentity();
9188        Rect rect = new Rect();
9189        try {
9190            synchronized (this) {
9191                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9192                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9193                if (task == null) {
9194                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9195                    return rect;
9196                }
9197                if (task.stack != null) {
9198                    // Return the bounds from window manager since it will be adjusted for various
9199                    // things like the presense of a docked stack for tasks that aren't resizeable.
9200                    mWindowManager.getTaskBounds(task.taskId, rect);
9201                } else {
9202                    // Task isn't in window manager yet since it isn't associated with a stack.
9203                    // Return the persist value from activity manager
9204                    if (task.mBounds != null) {
9205                        rect.set(task.mBounds);
9206                    } else if (task.mLastNonFullscreenBounds != null) {
9207                        rect.set(task.mLastNonFullscreenBounds);
9208                    }
9209                }
9210            }
9211        } finally {
9212            Binder.restoreCallingIdentity(ident);
9213        }
9214        return rect;
9215    }
9216
9217    @Override
9218    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9219        if (userId != UserHandle.getCallingUserId()) {
9220            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9221                    "getTaskDescriptionIcon");
9222        }
9223        final File passedIconFile = new File(filePath);
9224        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9225                passedIconFile.getName());
9226        if (!legitIconFile.getPath().equals(filePath)
9227                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9228            throw new IllegalArgumentException("Bad file path: " + filePath
9229                    + " passed for userId " + userId);
9230        }
9231        return mRecentTasks.getTaskDescriptionIcon(filePath);
9232    }
9233
9234    @Override
9235    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9236            throws RemoteException {
9237        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9238                opts.getCustomInPlaceResId() == 0) {
9239            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9240                    "with valid animation");
9241        }
9242        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9243        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9244                opts.getCustomInPlaceResId());
9245        mWindowManager.executeAppTransition();
9246    }
9247
9248    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9249            boolean removeFromRecents) {
9250        if (removeFromRecents) {
9251            mRecentTasks.remove(tr);
9252            tr.removedFromRecents();
9253        }
9254        ComponentName component = tr.getBaseIntent().getComponent();
9255        if (component == null) {
9256            Slog.w(TAG, "No component for base intent of task: " + tr);
9257            return;
9258        }
9259
9260        // Find any running services associated with this app and stop if needed.
9261        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9262
9263        if (!killProcess) {
9264            return;
9265        }
9266
9267        // Determine if the process(es) for this task should be killed.
9268        final String pkg = component.getPackageName();
9269        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9270        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9271        for (int i = 0; i < pmap.size(); i++) {
9272
9273            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9274            for (int j = 0; j < uids.size(); j++) {
9275                ProcessRecord proc = uids.valueAt(j);
9276                if (proc.userId != tr.userId) {
9277                    // Don't kill process for a different user.
9278                    continue;
9279                }
9280                if (proc == mHomeProcess) {
9281                    // Don't kill the home process along with tasks from the same package.
9282                    continue;
9283                }
9284                if (!proc.pkgList.containsKey(pkg)) {
9285                    // Don't kill process that is not associated with this task.
9286                    continue;
9287                }
9288
9289                for (int k = 0; k < proc.activities.size(); k++) {
9290                    TaskRecord otherTask = proc.activities.get(k).task;
9291                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9292                        // Don't kill process(es) that has an activity in a different task that is
9293                        // also in recents.
9294                        return;
9295                    }
9296                }
9297
9298                if (proc.foregroundServices) {
9299                    // Don't kill process(es) with foreground service.
9300                    return;
9301                }
9302
9303                // Add process to kill list.
9304                procsToKill.add(proc);
9305            }
9306        }
9307
9308        // Kill the running processes.
9309        for (int i = 0; i < procsToKill.size(); i++) {
9310            ProcessRecord pr = procsToKill.get(i);
9311            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9312                    && pr.curReceiver == null) {
9313                pr.kill("remove task", true);
9314            } else {
9315                // We delay killing processes that are not in the background or running a receiver.
9316                pr.waitingToKill = "remove task";
9317            }
9318        }
9319    }
9320
9321    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9322        // Remove all tasks with activities in the specified package from the list of recent tasks
9323        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9324            TaskRecord tr = mRecentTasks.get(i);
9325            if (tr.userId != userId) continue;
9326
9327            ComponentName cn = tr.intent.getComponent();
9328            if (cn != null && cn.getPackageName().equals(packageName)) {
9329                // If the package name matches, remove the task.
9330                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9331            }
9332        }
9333    }
9334
9335    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9336            int userId) {
9337
9338        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9339            TaskRecord tr = mRecentTasks.get(i);
9340            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9341                continue;
9342            }
9343
9344            ComponentName cn = tr.intent.getComponent();
9345            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9346                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9347            if (sameComponent) {
9348                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9349            }
9350        }
9351    }
9352
9353    /**
9354     * Removes the task with the specified task id.
9355     *
9356     * @param taskId Identifier of the task to be removed.
9357     * @param killProcess Kill any process associated with the task if possible.
9358     * @param removeFromRecents Whether to also remove the task from recents.
9359     * @return Returns true if the given task was found and removed.
9360     */
9361    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9362            boolean removeFromRecents) {
9363        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9364                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9365        if (tr != null) {
9366            tr.removeTaskActivitiesLocked();
9367            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9368            if (tr.isPersistable) {
9369                notifyTaskPersisterLocked(null, true);
9370            }
9371            return true;
9372        }
9373        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9374        return false;
9375    }
9376
9377    @Override
9378    public void removeStack(int stackId) {
9379        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9380        if (stackId == HOME_STACK_ID) {
9381            throw new IllegalArgumentException("Removing home stack is not allowed.");
9382        }
9383
9384        synchronized (this) {
9385            final long ident = Binder.clearCallingIdentity();
9386            try {
9387                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9388                if (stack == null) {
9389                    return;
9390                }
9391                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9392                for (int i = tasks.size() - 1; i >= 0; i--) {
9393                    removeTaskByIdLocked(
9394                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9395                }
9396            } finally {
9397                Binder.restoreCallingIdentity(ident);
9398            }
9399        }
9400    }
9401
9402    @Override
9403    public boolean removeTask(int taskId) {
9404        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9405        synchronized (this) {
9406            final long ident = Binder.clearCallingIdentity();
9407            try {
9408                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9409            } finally {
9410                Binder.restoreCallingIdentity(ident);
9411            }
9412        }
9413    }
9414
9415    /**
9416     * TODO: Add mController hook
9417     */
9418    @Override
9419    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9420        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9421
9422        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9423        synchronized(this) {
9424            moveTaskToFrontLocked(taskId, flags, bOptions);
9425        }
9426    }
9427
9428    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9429        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9430
9431        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9432                Binder.getCallingUid(), -1, -1, "Task to front")) {
9433            ActivityOptions.abort(options);
9434            return;
9435        }
9436        final long origId = Binder.clearCallingIdentity();
9437        try {
9438            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9439            if (task == null) {
9440                Slog.d(TAG, "Could not find task for id: "+ taskId);
9441                return;
9442            }
9443            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9444                mStackSupervisor.showLockTaskToast();
9445                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9446                return;
9447            }
9448            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9449            if (prev != null && prev.isRecentsActivity()) {
9450                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9451            }
9452            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9453                    false /* forceNonResizable */);
9454        } finally {
9455            Binder.restoreCallingIdentity(origId);
9456        }
9457        ActivityOptions.abort(options);
9458    }
9459
9460    /**
9461     * Moves an activity, and all of the other activities within the same task, to the bottom
9462     * of the history stack.  The activity's order within the task is unchanged.
9463     *
9464     * @param token A reference to the activity we wish to move
9465     * @param nonRoot If false then this only works if the activity is the root
9466     *                of a task; if true it will work for any activity in a task.
9467     * @return Returns true if the move completed, false if not.
9468     */
9469    @Override
9470    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9471        enforceNotIsolatedCaller("moveActivityTaskToBack");
9472        synchronized(this) {
9473            final long origId = Binder.clearCallingIdentity();
9474            try {
9475                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9476                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9477                if (task != null) {
9478                    if (mStackSupervisor.isLockedTask(task)) {
9479                        mStackSupervisor.showLockTaskToast();
9480                        return false;
9481                    }
9482                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9483                }
9484            } finally {
9485                Binder.restoreCallingIdentity(origId);
9486            }
9487        }
9488        return false;
9489    }
9490
9491    @Override
9492    public void moveTaskBackwards(int task) {
9493        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9494                "moveTaskBackwards()");
9495
9496        synchronized(this) {
9497            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9498                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9499                return;
9500            }
9501            final long origId = Binder.clearCallingIdentity();
9502            moveTaskBackwardsLocked(task);
9503            Binder.restoreCallingIdentity(origId);
9504        }
9505    }
9506
9507    private final void moveTaskBackwardsLocked(int task) {
9508        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9509    }
9510
9511    @Override
9512    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9513            IActivityContainerCallback callback) throws RemoteException {
9514        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9515        synchronized (this) {
9516            if (parentActivityToken == null) {
9517                throw new IllegalArgumentException("parent token must not be null");
9518            }
9519            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9520            if (r == null) {
9521                return null;
9522            }
9523            if (callback == null) {
9524                throw new IllegalArgumentException("callback must not be null");
9525            }
9526            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9527        }
9528    }
9529
9530    @Override
9531    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9532        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9533        synchronized (this) {
9534            mStackSupervisor.deleteActivityContainer(container);
9535        }
9536    }
9537
9538    @Override
9539    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9540        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9541        synchronized (this) {
9542            final int stackId = mStackSupervisor.getNextStackId();
9543            final ActivityStack stack =
9544                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9545            if (stack == null) {
9546                return null;
9547            }
9548            return stack.mActivityContainer;
9549        }
9550    }
9551
9552    @Override
9553    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9554        synchronized (this) {
9555            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9556            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9557                return stack.mActivityContainer.getDisplayId();
9558            }
9559            return Display.DEFAULT_DISPLAY;
9560        }
9561    }
9562
9563    @Override
9564    public int getActivityStackId(IBinder token) throws RemoteException {
9565        synchronized (this) {
9566            ActivityStack stack = ActivityRecord.getStackLocked(token);
9567            if (stack == null) {
9568                return INVALID_STACK_ID;
9569            }
9570            return stack.mStackId;
9571        }
9572    }
9573
9574    @Override
9575    public void exitFreeformMode(IBinder token) throws RemoteException {
9576        synchronized (this) {
9577            long ident = Binder.clearCallingIdentity();
9578            try {
9579                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9580                if (r == null) {
9581                    throw new IllegalArgumentException(
9582                            "exitFreeformMode: No activity record matching token=" + token);
9583                }
9584                final ActivityStack stack = r.getStackLocked(token);
9585                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9586                    throw new IllegalStateException(
9587                            "exitFreeformMode: You can only go fullscreen from freeform.");
9588                }
9589                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9590                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9591                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9592            } finally {
9593                Binder.restoreCallingIdentity(ident);
9594            }
9595        }
9596    }
9597
9598    @Override
9599    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9600        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9601        if (stackId == HOME_STACK_ID) {
9602            throw new IllegalArgumentException(
9603                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9604        }
9605        synchronized (this) {
9606            long ident = Binder.clearCallingIdentity();
9607            try {
9608                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9609                        + " to stackId=" + stackId + " toTop=" + toTop);
9610                if (stackId == DOCKED_STACK_ID) {
9611                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9612                            null /* initialBounds */);
9613                }
9614                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9615                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9616                if (result && stackId == DOCKED_STACK_ID) {
9617                    // If task moved to docked stack - show recents if needed.
9618                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9619                            "moveTaskToDockedStack");
9620                }
9621            } finally {
9622                Binder.restoreCallingIdentity(ident);
9623            }
9624        }
9625    }
9626
9627    @Override
9628    public void swapDockedAndFullscreenStack() throws RemoteException {
9629        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9630        synchronized (this) {
9631            long ident = Binder.clearCallingIdentity();
9632            try {
9633                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9634                        FULLSCREEN_WORKSPACE_STACK_ID);
9635                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9636                        : null;
9637                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9638                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9639                        : null;
9640                if (topTask == null || tasks == null || tasks.size() == 0) {
9641                    Slog.w(TAG,
9642                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9643                    return;
9644                }
9645
9646                // TODO: App transition
9647                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9648
9649                // Defer the resume so resume/pausing while moving stacks is dangerous.
9650                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9651                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9652                        ANIMATE, true /* deferResume */);
9653                final int size = tasks.size();
9654                for (int i = 0; i < size; i++) {
9655                    final int id = tasks.get(i).taskId;
9656                    if (id == topTask.taskId) {
9657                        continue;
9658                    }
9659                    mStackSupervisor.moveTaskToStackLocked(id,
9660                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9661                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9662                }
9663
9664                // Because we deferred the resume, to avoid conflicts with stack switches while
9665                // resuming, we need to do it after all the tasks are moved.
9666                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9667                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9668
9669                mWindowManager.executeAppTransition();
9670            } finally {
9671                Binder.restoreCallingIdentity(ident);
9672            }
9673        }
9674    }
9675
9676    /**
9677     * Moves the input task to the docked stack.
9678     *
9679     * @param taskId Id of task to move.
9680     * @param createMode The mode the docked stack should be created in if it doesn't exist
9681     *                   already. See
9682     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9683     *                   and
9684     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9685     * @param toTop If the task and stack should be moved to the top.
9686     * @param animate Whether we should play an animation for the moving the task
9687     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9688     *                      docked stack. Pass {@code null} to use default bounds.
9689     */
9690    @Override
9691    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9692            Rect initialBounds) {
9693        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9694        synchronized (this) {
9695            long ident = Binder.clearCallingIdentity();
9696            try {
9697                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9698                        + " to createMode=" + createMode + " toTop=" + toTop);
9699                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9700                return mStackSupervisor.moveTaskToStackLocked(
9701                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9702                        "moveTaskToDockedStack", animate);
9703            } finally {
9704                Binder.restoreCallingIdentity(ident);
9705            }
9706        }
9707    }
9708
9709    /**
9710     * Moves the top activity in the input stackId to the pinned stack.
9711     *
9712     * @param stackId Id of stack to move the top activity to pinned stack.
9713     * @param bounds Bounds to use for pinned stack.
9714     *
9715     * @return True if the top activity of the input stack was successfully moved to the pinned
9716     *          stack.
9717     */
9718    @Override
9719    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9720        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9721        synchronized (this) {
9722            if (!mSupportsPictureInPicture) {
9723                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9724                        + "Device doesn't support picture-in-pciture mode");
9725            }
9726
9727            long ident = Binder.clearCallingIdentity();
9728            try {
9729                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9730            } finally {
9731                Binder.restoreCallingIdentity(ident);
9732            }
9733        }
9734    }
9735
9736    @Override
9737    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9738            boolean preserveWindows, boolean animate, int animationDuration) {
9739        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9740        long ident = Binder.clearCallingIdentity();
9741        try {
9742            synchronized (this) {
9743                if (animate) {
9744                    if (stackId == PINNED_STACK_ID) {
9745                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9746                    } else {
9747                        throw new IllegalArgumentException("Stack: " + stackId
9748                                + " doesn't support animated resize.");
9749                    }
9750                } else {
9751                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9752                            null /* tempTaskInsetBounds */, preserveWindows,
9753                            allowResizeInDockedMode, !DEFER_RESUME);
9754                }
9755            }
9756        } finally {
9757            Binder.restoreCallingIdentity(ident);
9758        }
9759    }
9760
9761    @Override
9762    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9763            Rect tempDockedTaskInsetBounds,
9764            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9766                "resizeDockedStack()");
9767        long ident = Binder.clearCallingIdentity();
9768        try {
9769            synchronized (this) {
9770                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9771                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9772                        PRESERVE_WINDOWS);
9773            }
9774        } finally {
9775            Binder.restoreCallingIdentity(ident);
9776        }
9777    }
9778
9779    @Override
9780    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9781        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9782                "resizePinnedStack()");
9783        final long ident = Binder.clearCallingIdentity();
9784        try {
9785            synchronized (this) {
9786                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9787            }
9788        } finally {
9789            Binder.restoreCallingIdentity(ident);
9790        }
9791    }
9792
9793    @Override
9794    public void positionTaskInStack(int taskId, int stackId, int position) {
9795        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9796        if (stackId == HOME_STACK_ID) {
9797            throw new IllegalArgumentException(
9798                    "positionTaskInStack: Attempt to change the position of task "
9799                    + taskId + " in/to home stack");
9800        }
9801        synchronized (this) {
9802            long ident = Binder.clearCallingIdentity();
9803            try {
9804                if (DEBUG_STACK) Slog.d(TAG_STACK,
9805                        "positionTaskInStack: positioning task=" + taskId
9806                        + " in stackId=" + stackId + " at position=" + position);
9807                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811        }
9812    }
9813
9814    @Override
9815    public List<StackInfo> getAllStackInfos() {
9816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9817        long ident = Binder.clearCallingIdentity();
9818        try {
9819            synchronized (this) {
9820                return mStackSupervisor.getAllStackInfosLocked();
9821            }
9822        } finally {
9823            Binder.restoreCallingIdentity(ident);
9824        }
9825    }
9826
9827    @Override
9828    public StackInfo getStackInfo(int stackId) {
9829        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9830        long ident = Binder.clearCallingIdentity();
9831        try {
9832            synchronized (this) {
9833                return mStackSupervisor.getStackInfoLocked(stackId);
9834            }
9835        } finally {
9836            Binder.restoreCallingIdentity(ident);
9837        }
9838    }
9839
9840    @Override
9841    public boolean isInHomeStack(int taskId) {
9842        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9843        long ident = Binder.clearCallingIdentity();
9844        try {
9845            synchronized (this) {
9846                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9847                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9848                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9849            }
9850        } finally {
9851            Binder.restoreCallingIdentity(ident);
9852        }
9853    }
9854
9855    @Override
9856    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9857        synchronized(this) {
9858            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9859        }
9860    }
9861
9862    @Override
9863    public void updateDeviceOwner(String packageName) {
9864        final int callingUid = Binder.getCallingUid();
9865        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9866            throw new SecurityException("updateDeviceOwner called from non-system process");
9867        }
9868        synchronized (this) {
9869            mDeviceOwnerName = packageName;
9870        }
9871    }
9872
9873    @Override
9874    public void updateLockTaskPackages(int userId, String[] packages) {
9875        final int callingUid = Binder.getCallingUid();
9876        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9877            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9878                    "updateLockTaskPackages()");
9879        }
9880        synchronized (this) {
9881            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9882                    Arrays.toString(packages));
9883            mLockTaskPackages.put(userId, packages);
9884            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9885        }
9886    }
9887
9888
9889    void startLockTaskModeLocked(TaskRecord task) {
9890        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9891        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9892            return;
9893        }
9894
9895        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9896        // is initiated by system after the pinning request was shown and locked mode is initiated
9897        // by an authorized app directly
9898        final int callingUid = Binder.getCallingUid();
9899        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9900        long ident = Binder.clearCallingIdentity();
9901        try {
9902            if (!isSystemInitiated) {
9903                task.mLockTaskUid = callingUid;
9904                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9905                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9906                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9907                    StatusBarManagerInternal statusBarManager =
9908                            LocalServices.getService(StatusBarManagerInternal.class);
9909                    if (statusBarManager != null) {
9910                        statusBarManager.showScreenPinningRequest(task.taskId);
9911                    }
9912                    return;
9913                }
9914
9915                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9916                if (stack == null || task != stack.topTask()) {
9917                    throw new IllegalArgumentException("Invalid task, not in foreground");
9918                }
9919            }
9920            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9921                    "Locking fully");
9922            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9923                    ActivityManager.LOCK_TASK_MODE_PINNED :
9924                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9925                    "startLockTask", true);
9926        } finally {
9927            Binder.restoreCallingIdentity(ident);
9928        }
9929    }
9930
9931    @Override
9932    public void startLockTaskMode(int taskId) {
9933        synchronized (this) {
9934            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9935            if (task != null) {
9936                startLockTaskModeLocked(task);
9937            }
9938        }
9939    }
9940
9941    @Override
9942    public void startLockTaskMode(IBinder token) {
9943        synchronized (this) {
9944            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9945            if (r == null) {
9946                return;
9947            }
9948            final TaskRecord task = r.task;
9949            if (task != null) {
9950                startLockTaskModeLocked(task);
9951            }
9952        }
9953    }
9954
9955    @Override
9956    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9957        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9958        // This makes inner call to look as if it was initiated by system.
9959        long ident = Binder.clearCallingIdentity();
9960        try {
9961            synchronized (this) {
9962                startLockTaskMode(taskId);
9963            }
9964        } finally {
9965            Binder.restoreCallingIdentity(ident);
9966        }
9967    }
9968
9969    @Override
9970    public void stopLockTaskMode() {
9971        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9972        if (lockTask == null) {
9973            // Our work here is done.
9974            return;
9975        }
9976
9977        final int callingUid = Binder.getCallingUid();
9978        final int lockTaskUid = lockTask.mLockTaskUid;
9979        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9980        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9981            // Done.
9982            return;
9983        } else {
9984            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9985            // It is possible lockTaskMode was started by the system process because
9986            // android:lockTaskMode is set to a locking value in the application manifest
9987            // instead of the app calling startLockTaskMode. In this case
9988            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9989            // {@link TaskRecord.effectiveUid} instead. Also caller with
9990            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9991            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9992                    && callingUid != lockTaskUid
9993                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9994                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9995                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9996            }
9997        }
9998        long ident = Binder.clearCallingIdentity();
9999        try {
10000            Log.d(TAG, "stopLockTaskMode");
10001            // Stop lock task
10002            synchronized (this) {
10003                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10004                        "stopLockTask", true);
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    /**
10012     * This API should be called by SystemUI only when user perform certain action to dismiss
10013     * lock task mode. We should only dismiss pinned lock task mode in this case.
10014     */
10015    @Override
10016    public void stopSystemLockTaskMode() throws RemoteException {
10017        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10018            stopLockTaskMode();
10019        } else {
10020            mStackSupervisor.showLockTaskToast();
10021        }
10022    }
10023
10024    @Override
10025    public boolean isInLockTaskMode() {
10026        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10027    }
10028
10029    @Override
10030    public int getLockTaskModeState() {
10031        synchronized (this) {
10032            return mStackSupervisor.getLockTaskModeState();
10033        }
10034    }
10035
10036    @Override
10037    public void showLockTaskEscapeMessage(IBinder token) {
10038        synchronized (this) {
10039            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10040            if (r == null) {
10041                return;
10042            }
10043            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10044        }
10045    }
10046
10047    // =========================================================
10048    // CONTENT PROVIDERS
10049    // =========================================================
10050
10051    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10052        List<ProviderInfo> providers = null;
10053        try {
10054            providers = AppGlobals.getPackageManager()
10055                    .queryContentProviders(app.processName, app.uid,
10056                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10057                                    | MATCH_DEBUG_TRIAGED_MISSING)
10058                    .getList();
10059        } catch (RemoteException ex) {
10060        }
10061        if (DEBUG_MU) Slog.v(TAG_MU,
10062                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10063        int userId = app.userId;
10064        if (providers != null) {
10065            int N = providers.size();
10066            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10067            for (int i=0; i<N; i++) {
10068                ProviderInfo cpi =
10069                    (ProviderInfo)providers.get(i);
10070                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10071                        cpi.name, cpi.flags);
10072                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10073                    // This is a singleton provider, but a user besides the
10074                    // default user is asking to initialize a process it runs
10075                    // in...  well, no, it doesn't actually run in this process,
10076                    // it runs in the process of the default user.  Get rid of it.
10077                    providers.remove(i);
10078                    N--;
10079                    i--;
10080                    continue;
10081                }
10082
10083                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10084                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10085                if (cpr == null) {
10086                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10087                    mProviderMap.putProviderByClass(comp, cpr);
10088                }
10089                if (DEBUG_MU) Slog.v(TAG_MU,
10090                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10091                app.pubProviders.put(cpi.name, cpr);
10092                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10093                    // Don't add this if it is a platform component that is marked
10094                    // to run in multiple processes, because this is actually
10095                    // part of the framework so doesn't make sense to track as a
10096                    // separate apk in the process.
10097                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10098                            mProcessStats);
10099                }
10100                notifyPackageUse(cpi.applicationInfo.packageName,
10101                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10102            }
10103        }
10104        return providers;
10105    }
10106
10107    /**
10108     * Check if {@link ProcessRecord} has a possible chance at accessing the
10109     * given {@link ProviderInfo}. Final permission checking is always done
10110     * in {@link ContentProvider}.
10111     */
10112    private final String checkContentProviderPermissionLocked(
10113            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10114        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10115        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10116        boolean checkedGrants = false;
10117        if (checkUser) {
10118            // Looking for cross-user grants before enforcing the typical cross-users permissions
10119            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10120            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10121                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10122                    return null;
10123                }
10124                checkedGrants = true;
10125            }
10126            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10127                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10128            if (userId != tmpTargetUserId) {
10129                // When we actually went to determine the final targer user ID, this ended
10130                // up different than our initial check for the authority.  This is because
10131                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10132                // SELF.  So we need to re-check the grants again.
10133                checkedGrants = false;
10134            }
10135        }
10136        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10137                cpi.applicationInfo.uid, cpi.exported)
10138                == PackageManager.PERMISSION_GRANTED) {
10139            return null;
10140        }
10141        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10142                cpi.applicationInfo.uid, cpi.exported)
10143                == PackageManager.PERMISSION_GRANTED) {
10144            return null;
10145        }
10146
10147        PathPermission[] pps = cpi.pathPermissions;
10148        if (pps != null) {
10149            int i = pps.length;
10150            while (i > 0) {
10151                i--;
10152                PathPermission pp = pps[i];
10153                String pprperm = pp.getReadPermission();
10154                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10155                        cpi.applicationInfo.uid, cpi.exported)
10156                        == PackageManager.PERMISSION_GRANTED) {
10157                    return null;
10158                }
10159                String ppwperm = pp.getWritePermission();
10160                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10161                        cpi.applicationInfo.uid, cpi.exported)
10162                        == PackageManager.PERMISSION_GRANTED) {
10163                    return null;
10164                }
10165            }
10166        }
10167        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10168            return null;
10169        }
10170
10171        String msg;
10172        if (!cpi.exported) {
10173            msg = "Permission Denial: opening provider " + cpi.name
10174                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10175                    + ", uid=" + callingUid + ") that is not exported from uid "
10176                    + cpi.applicationInfo.uid;
10177        } else {
10178            msg = "Permission Denial: opening provider " + cpi.name
10179                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10180                    + ", uid=" + callingUid + ") requires "
10181                    + cpi.readPermission + " or " + cpi.writePermission;
10182        }
10183        Slog.w(TAG, msg);
10184        return msg;
10185    }
10186
10187    /**
10188     * Returns if the ContentProvider has granted a uri to callingUid
10189     */
10190    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10191        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10192        if (perms != null) {
10193            for (int i=perms.size()-1; i>=0; i--) {
10194                GrantUri grantUri = perms.keyAt(i);
10195                if (grantUri.sourceUserId == userId || !checkUser) {
10196                    if (matchesProvider(grantUri.uri, cpi)) {
10197                        return true;
10198                    }
10199                }
10200            }
10201        }
10202        return false;
10203    }
10204
10205    /**
10206     * Returns true if the uri authority is one of the authorities specified in the provider.
10207     */
10208    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10209        String uriAuth = uri.getAuthority();
10210        String cpiAuth = cpi.authority;
10211        if (cpiAuth.indexOf(';') == -1) {
10212            return cpiAuth.equals(uriAuth);
10213        }
10214        String[] cpiAuths = cpiAuth.split(";");
10215        int length = cpiAuths.length;
10216        for (int i = 0; i < length; i++) {
10217            if (cpiAuths[i].equals(uriAuth)) return true;
10218        }
10219        return false;
10220    }
10221
10222    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10223            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10224        if (r != null) {
10225            for (int i=0; i<r.conProviders.size(); i++) {
10226                ContentProviderConnection conn = r.conProviders.get(i);
10227                if (conn.provider == cpr) {
10228                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10229                            "Adding provider requested by "
10230                            + r.processName + " from process "
10231                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10232                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10233                    if (stable) {
10234                        conn.stableCount++;
10235                        conn.numStableIncs++;
10236                    } else {
10237                        conn.unstableCount++;
10238                        conn.numUnstableIncs++;
10239                    }
10240                    return conn;
10241                }
10242            }
10243            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10244            if (stable) {
10245                conn.stableCount = 1;
10246                conn.numStableIncs = 1;
10247            } else {
10248                conn.unstableCount = 1;
10249                conn.numUnstableIncs = 1;
10250            }
10251            cpr.connections.add(conn);
10252            r.conProviders.add(conn);
10253            startAssociationLocked(r.uid, r.processName, r.curProcState,
10254                    cpr.uid, cpr.name, cpr.info.processName);
10255            return conn;
10256        }
10257        cpr.addExternalProcessHandleLocked(externalProcessToken);
10258        return null;
10259    }
10260
10261    boolean decProviderCountLocked(ContentProviderConnection conn,
10262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10263        if (conn != null) {
10264            cpr = conn.provider;
10265            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10266                    "Removing provider requested by "
10267                    + conn.client.processName + " from process "
10268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10270            if (stable) {
10271                conn.stableCount--;
10272            } else {
10273                conn.unstableCount--;
10274            }
10275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10276                cpr.connections.remove(conn);
10277                conn.client.conProviders.remove(conn);
10278                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10279                    // The client is more important than last activity -- note the time this
10280                    // is happening, so we keep the old provider process around a bit as last
10281                    // activity to avoid thrashing it.
10282                    if (cpr.proc != null) {
10283                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10284                    }
10285                }
10286                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10287                return true;
10288            }
10289            return false;
10290        }
10291        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10292        return false;
10293    }
10294
10295    private void checkTime(long startTime, String where) {
10296        long now = SystemClock.elapsedRealtime();
10297        if ((now-startTime) > 1000) {
10298            // If we are taking more than a second, log about it.
10299            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10300        }
10301    }
10302
10303    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10304            String name, IBinder token, boolean stable, int userId) {
10305        ContentProviderRecord cpr;
10306        ContentProviderConnection conn = null;
10307        ProviderInfo cpi = null;
10308
10309        synchronized(this) {
10310            long startTime = SystemClock.elapsedRealtime();
10311
10312            ProcessRecord r = null;
10313            if (caller != null) {
10314                r = getRecordForAppLocked(caller);
10315                if (r == null) {
10316                    throw new SecurityException(
10317                            "Unable to find app for caller " + caller
10318                          + " (pid=" + Binder.getCallingPid()
10319                          + ") when getting content provider " + name);
10320                }
10321            }
10322
10323            boolean checkCrossUser = true;
10324
10325            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10326
10327            // First check if this content provider has been published...
10328            cpr = mProviderMap.getProviderByName(name, userId);
10329            // If that didn't work, check if it exists for user 0 and then
10330            // verify that it's a singleton provider before using it.
10331            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10332                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10333                if (cpr != null) {
10334                    cpi = cpr.info;
10335                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10336                            cpi.name, cpi.flags)
10337                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10338                        userId = UserHandle.USER_SYSTEM;
10339                        checkCrossUser = false;
10340                    } else {
10341                        cpr = null;
10342                        cpi = null;
10343                    }
10344                }
10345            }
10346
10347            boolean providerRunning = cpr != null;
10348            if (providerRunning) {
10349                cpi = cpr.info;
10350                String msg;
10351                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10352                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10353                        != null) {
10354                    throw new SecurityException(msg);
10355                }
10356                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10357
10358                if (r != null && cpr.canRunHere(r)) {
10359                    // This provider has been published or is in the process
10360                    // of being published...  but it is also allowed to run
10361                    // in the caller's process, so don't make a connection
10362                    // and just let the caller instantiate its own instance.
10363                    ContentProviderHolder holder = cpr.newHolder(null);
10364                    // don't give caller the provider object, it needs
10365                    // to make its own.
10366                    holder.provider = null;
10367                    return holder;
10368                }
10369
10370                final long origId = Binder.clearCallingIdentity();
10371
10372                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10373
10374                // In this case the provider instance already exists, so we can
10375                // return it right away.
10376                conn = incProviderCountLocked(r, cpr, token, stable);
10377                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10378                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10379                        // If this is a perceptible app accessing the provider,
10380                        // make sure to count it as being accessed and thus
10381                        // back up on the LRU list.  This is good because
10382                        // content providers are often expensive to start.
10383                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10384                        updateLruProcessLocked(cpr.proc, false, null);
10385                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10386                    }
10387                }
10388
10389                if (cpr.proc != null) {
10390                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10391                    boolean success = updateOomAdjLocked(cpr.proc);
10392                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10393                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10394                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10395                    // NOTE: there is still a race here where a signal could be
10396                    // pending on the process even though we managed to update its
10397                    // adj level.  Not sure what to do about this, but at least
10398                    // the race is now smaller.
10399                    if (!success) {
10400                        // Uh oh...  it looks like the provider's process
10401                        // has been killed on us.  We need to wait for a new
10402                        // process to be started, and make sure its death
10403                        // doesn't kill our process.
10404                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10405                                + " is crashing; detaching " + r);
10406                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10407                        checkTime(startTime, "getContentProviderImpl: before appDied");
10408                        appDiedLocked(cpr.proc);
10409                        checkTime(startTime, "getContentProviderImpl: after appDied");
10410                        if (!lastRef) {
10411                            // This wasn't the last ref our process had on
10412                            // the provider...  we have now been killed, bail.
10413                            return null;
10414                        }
10415                        providerRunning = false;
10416                        conn = null;
10417                    }
10418                }
10419
10420                Binder.restoreCallingIdentity(origId);
10421            }
10422
10423            if (!providerRunning) {
10424                try {
10425                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10426                    cpi = AppGlobals.getPackageManager().
10427                        resolveContentProvider(name,
10428                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10429                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10430                } catch (RemoteException ex) {
10431                }
10432                if (cpi == null) {
10433                    return null;
10434                }
10435                // If the provider is a singleton AND
10436                // (it's a call within the same user || the provider is a
10437                // privileged app)
10438                // Then allow connecting to the singleton provider
10439                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10440                        cpi.name, cpi.flags)
10441                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10442                if (singleton) {
10443                    userId = UserHandle.USER_SYSTEM;
10444                }
10445                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10446                checkTime(startTime, "getContentProviderImpl: got app info for user");
10447
10448                String msg;
10449                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10450                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10451                        != null) {
10452                    throw new SecurityException(msg);
10453                }
10454                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10455
10456                if (!mProcessesReady
10457                        && !cpi.processName.equals("system")) {
10458                    // If this content provider does not run in the system
10459                    // process, and the system is not yet ready to run other
10460                    // processes, then fail fast instead of hanging.
10461                    throw new IllegalArgumentException(
10462                            "Attempt to launch content provider before system ready");
10463                }
10464
10465                // Make sure that the user who owns this provider is running.  If not,
10466                // we don't want to allow it to run.
10467                if (!mUserController.isUserRunningLocked(userId, 0)) {
10468                    Slog.w(TAG, "Unable to launch app "
10469                            + cpi.applicationInfo.packageName + "/"
10470                            + cpi.applicationInfo.uid + " for provider "
10471                            + name + ": user " + userId + " is stopped");
10472                    return null;
10473                }
10474
10475                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10476                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10477                cpr = mProviderMap.getProviderByClass(comp, userId);
10478                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10479                final boolean firstClass = cpr == null;
10480                if (firstClass) {
10481                    final long ident = Binder.clearCallingIdentity();
10482
10483                    // If permissions need a review before any of the app components can run,
10484                    // we return no provider and launch a review activity if the calling app
10485                    // is in the foreground.
10486                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10487                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10488                            return null;
10489                        }
10490                    }
10491
10492                    try {
10493                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10494                        ApplicationInfo ai =
10495                            AppGlobals.getPackageManager().
10496                                getApplicationInfo(
10497                                        cpi.applicationInfo.packageName,
10498                                        STOCK_PM_FLAGS, userId);
10499                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10500                        if (ai == null) {
10501                            Slog.w(TAG, "No package info for content provider "
10502                                    + cpi.name);
10503                            return null;
10504                        }
10505                        ai = getAppInfoForUser(ai, userId);
10506                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10507                    } catch (RemoteException ex) {
10508                        // pm is in same process, this will never happen.
10509                    } finally {
10510                        Binder.restoreCallingIdentity(ident);
10511                    }
10512                }
10513
10514                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10515
10516                if (r != null && cpr.canRunHere(r)) {
10517                    // If this is a multiprocess provider, then just return its
10518                    // info and allow the caller to instantiate it.  Only do
10519                    // this if the provider is the same user as the caller's
10520                    // process, or can run as root (so can be in any process).
10521                    return cpr.newHolder(null);
10522                }
10523
10524                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10525                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10526                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10527
10528                // This is single process, and our app is now connecting to it.
10529                // See if we are already in the process of launching this
10530                // provider.
10531                final int N = mLaunchingProviders.size();
10532                int i;
10533                for (i = 0; i < N; i++) {
10534                    if (mLaunchingProviders.get(i) == cpr) {
10535                        break;
10536                    }
10537                }
10538
10539                // If the provider is not already being launched, then get it
10540                // started.
10541                if (i >= N) {
10542                    final long origId = Binder.clearCallingIdentity();
10543
10544                    try {
10545                        // Content provider is now in use, its package can't be stopped.
10546                        try {
10547                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10548                            AppGlobals.getPackageManager().setPackageStoppedState(
10549                                    cpr.appInfo.packageName, false, userId);
10550                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10551                        } catch (RemoteException e) {
10552                        } catch (IllegalArgumentException e) {
10553                            Slog.w(TAG, "Failed trying to unstop package "
10554                                    + cpr.appInfo.packageName + ": " + e);
10555                        }
10556
10557                        // Use existing process if already started
10558                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10559                        ProcessRecord proc = getProcessRecordLocked(
10560                                cpi.processName, cpr.appInfo.uid, false);
10561                        if (proc != null && proc.thread != null) {
10562                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10563                                    "Installing in existing process " + proc);
10564                            if (!proc.pubProviders.containsKey(cpi.name)) {
10565                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10566                                proc.pubProviders.put(cpi.name, cpr);
10567                                try {
10568                                    proc.thread.scheduleInstallProvider(cpi);
10569                                } catch (RemoteException e) {
10570                                }
10571                            }
10572                        } else {
10573                            checkTime(startTime, "getContentProviderImpl: before start process");
10574                            proc = startProcessLocked(cpi.processName,
10575                                    cpr.appInfo, false, 0, "content provider",
10576                                    new ComponentName(cpi.applicationInfo.packageName,
10577                                            cpi.name), false, false, false);
10578                            checkTime(startTime, "getContentProviderImpl: after start process");
10579                            if (proc == null) {
10580                                Slog.w(TAG, "Unable to launch app "
10581                                        + cpi.applicationInfo.packageName + "/"
10582                                        + cpi.applicationInfo.uid + " for provider "
10583                                        + name + ": process is bad");
10584                                return null;
10585                            }
10586                        }
10587                        cpr.launchingApp = proc;
10588                        mLaunchingProviders.add(cpr);
10589                    } finally {
10590                        Binder.restoreCallingIdentity(origId);
10591                    }
10592                }
10593
10594                checkTime(startTime, "getContentProviderImpl: updating data structures");
10595
10596                // Make sure the provider is published (the same provider class
10597                // may be published under multiple names).
10598                if (firstClass) {
10599                    mProviderMap.putProviderByClass(comp, cpr);
10600                }
10601
10602                mProviderMap.putProviderByName(name, cpr);
10603                conn = incProviderCountLocked(r, cpr, token, stable);
10604                if (conn != null) {
10605                    conn.waiting = true;
10606                }
10607            }
10608            checkTime(startTime, "getContentProviderImpl: done!");
10609        }
10610
10611        // Wait for the provider to be published...
10612        synchronized (cpr) {
10613            while (cpr.provider == null) {
10614                if (cpr.launchingApp == null) {
10615                    Slog.w(TAG, "Unable to launch app "
10616                            + cpi.applicationInfo.packageName + "/"
10617                            + cpi.applicationInfo.uid + " for provider "
10618                            + name + ": launching app became null");
10619                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10620                            UserHandle.getUserId(cpi.applicationInfo.uid),
10621                            cpi.applicationInfo.packageName,
10622                            cpi.applicationInfo.uid, name);
10623                    return null;
10624                }
10625                try {
10626                    if (DEBUG_MU) Slog.v(TAG_MU,
10627                            "Waiting to start provider " + cpr
10628                            + " launchingApp=" + cpr.launchingApp);
10629                    if (conn != null) {
10630                        conn.waiting = true;
10631                    }
10632                    cpr.wait();
10633                } catch (InterruptedException ex) {
10634                } finally {
10635                    if (conn != null) {
10636                        conn.waiting = false;
10637                    }
10638                }
10639            }
10640        }
10641        return cpr != null ? cpr.newHolder(conn) : null;
10642    }
10643
10644    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10645            ProcessRecord r, final int userId) {
10646        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10647                cpi.packageName, userId)) {
10648
10649            final boolean callerForeground = r == null || r.setSchedGroup
10650                    != ProcessList.SCHED_GROUP_BACKGROUND;
10651
10652            // Show a permission review UI only for starting from a foreground app
10653            if (!callerForeground) {
10654                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10655                        + cpi.packageName + " requires a permissions review");
10656                return false;
10657            }
10658
10659            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10660            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10661                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10662            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10663
10664            if (DEBUG_PERMISSIONS_REVIEW) {
10665                Slog.i(TAG, "u" + userId + " Launching permission review "
10666                        + "for package " + cpi.packageName);
10667            }
10668
10669            final UserHandle userHandle = new UserHandle(userId);
10670            mHandler.post(new Runnable() {
10671                @Override
10672                public void run() {
10673                    mContext.startActivityAsUser(intent, userHandle);
10674                }
10675            });
10676
10677            return false;
10678        }
10679
10680        return true;
10681    }
10682
10683    PackageManagerInternal getPackageManagerInternalLocked() {
10684        if (mPackageManagerInt == null) {
10685            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10686        }
10687        return mPackageManagerInt;
10688    }
10689
10690    @Override
10691    public final ContentProviderHolder getContentProvider(
10692            IApplicationThread caller, String name, int userId, boolean stable) {
10693        enforceNotIsolatedCaller("getContentProvider");
10694        if (caller == null) {
10695            String msg = "null IApplicationThread when getting content provider "
10696                    + name;
10697            Slog.w(TAG, msg);
10698            throw new SecurityException(msg);
10699        }
10700        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10701        // with cross-user grant.
10702        return getContentProviderImpl(caller, name, null, stable, userId);
10703    }
10704
10705    public ContentProviderHolder getContentProviderExternal(
10706            String name, int userId, IBinder token) {
10707        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10708            "Do not have permission in call getContentProviderExternal()");
10709        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10710                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10711        return getContentProviderExternalUnchecked(name, token, userId);
10712    }
10713
10714    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10715            IBinder token, int userId) {
10716        return getContentProviderImpl(null, name, token, true, userId);
10717    }
10718
10719    /**
10720     * Drop a content provider from a ProcessRecord's bookkeeping
10721     */
10722    public void removeContentProvider(IBinder connection, boolean stable) {
10723        enforceNotIsolatedCaller("removeContentProvider");
10724        long ident = Binder.clearCallingIdentity();
10725        try {
10726            synchronized (this) {
10727                ContentProviderConnection conn;
10728                try {
10729                    conn = (ContentProviderConnection)connection;
10730                } catch (ClassCastException e) {
10731                    String msg ="removeContentProvider: " + connection
10732                            + " not a ContentProviderConnection";
10733                    Slog.w(TAG, msg);
10734                    throw new IllegalArgumentException(msg);
10735                }
10736                if (conn == null) {
10737                    throw new NullPointerException("connection is null");
10738                }
10739                if (decProviderCountLocked(conn, null, null, stable)) {
10740                    updateOomAdjLocked();
10741                }
10742            }
10743        } finally {
10744            Binder.restoreCallingIdentity(ident);
10745        }
10746    }
10747
10748    public void removeContentProviderExternal(String name, IBinder token) {
10749        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10750            "Do not have permission in call removeContentProviderExternal()");
10751        int userId = UserHandle.getCallingUserId();
10752        long ident = Binder.clearCallingIdentity();
10753        try {
10754            removeContentProviderExternalUnchecked(name, token, userId);
10755        } finally {
10756            Binder.restoreCallingIdentity(ident);
10757        }
10758    }
10759
10760    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10761        synchronized (this) {
10762            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10763            if(cpr == null) {
10764                //remove from mProvidersByClass
10765                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10766                return;
10767            }
10768
10769            //update content provider record entry info
10770            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10771            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10772            if (localCpr.hasExternalProcessHandles()) {
10773                if (localCpr.removeExternalProcessHandleLocked(token)) {
10774                    updateOomAdjLocked();
10775                } else {
10776                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10777                            + " with no external reference for token: "
10778                            + token + ".");
10779                }
10780            } else {
10781                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10782                        + " with no external references.");
10783            }
10784        }
10785    }
10786
10787    public final void publishContentProviders(IApplicationThread caller,
10788            List<ContentProviderHolder> providers) {
10789        if (providers == null) {
10790            return;
10791        }
10792
10793        enforceNotIsolatedCaller("publishContentProviders");
10794        synchronized (this) {
10795            final ProcessRecord r = getRecordForAppLocked(caller);
10796            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10797            if (r == null) {
10798                throw new SecurityException(
10799                        "Unable to find app for caller " + caller
10800                      + " (pid=" + Binder.getCallingPid()
10801                      + ") when publishing content providers");
10802            }
10803
10804            final long origId = Binder.clearCallingIdentity();
10805
10806            final int N = providers.size();
10807            for (int i = 0; i < N; i++) {
10808                ContentProviderHolder src = providers.get(i);
10809                if (src == null || src.info == null || src.provider == null) {
10810                    continue;
10811                }
10812                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10813                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10814                if (dst != null) {
10815                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10816                    mProviderMap.putProviderByClass(comp, dst);
10817                    String names[] = dst.info.authority.split(";");
10818                    for (int j = 0; j < names.length; j++) {
10819                        mProviderMap.putProviderByName(names[j], dst);
10820                    }
10821
10822                    int launchingCount = mLaunchingProviders.size();
10823                    int j;
10824                    boolean wasInLaunchingProviders = false;
10825                    for (j = 0; j < launchingCount; j++) {
10826                        if (mLaunchingProviders.get(j) == dst) {
10827                            mLaunchingProviders.remove(j);
10828                            wasInLaunchingProviders = true;
10829                            j--;
10830                            launchingCount--;
10831                        }
10832                    }
10833                    if (wasInLaunchingProviders) {
10834                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10835                    }
10836                    synchronized (dst) {
10837                        dst.provider = src.provider;
10838                        dst.proc = r;
10839                        dst.notifyAll();
10840                    }
10841                    updateOomAdjLocked(r);
10842                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10843                            src.info.authority);
10844                }
10845            }
10846
10847            Binder.restoreCallingIdentity(origId);
10848        }
10849    }
10850
10851    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10852        ContentProviderConnection conn;
10853        try {
10854            conn = (ContentProviderConnection)connection;
10855        } catch (ClassCastException e) {
10856            String msg ="refContentProvider: " + connection
10857                    + " not a ContentProviderConnection";
10858            Slog.w(TAG, msg);
10859            throw new IllegalArgumentException(msg);
10860        }
10861        if (conn == null) {
10862            throw new NullPointerException("connection is null");
10863        }
10864
10865        synchronized (this) {
10866            if (stable > 0) {
10867                conn.numStableIncs += stable;
10868            }
10869            stable = conn.stableCount + stable;
10870            if (stable < 0) {
10871                throw new IllegalStateException("stableCount < 0: " + stable);
10872            }
10873
10874            if (unstable > 0) {
10875                conn.numUnstableIncs += unstable;
10876            }
10877            unstable = conn.unstableCount + unstable;
10878            if (unstable < 0) {
10879                throw new IllegalStateException("unstableCount < 0: " + unstable);
10880            }
10881
10882            if ((stable+unstable) <= 0) {
10883                throw new IllegalStateException("ref counts can't go to zero here: stable="
10884                        + stable + " unstable=" + unstable);
10885            }
10886            conn.stableCount = stable;
10887            conn.unstableCount = unstable;
10888            return !conn.dead;
10889        }
10890    }
10891
10892    public void unstableProviderDied(IBinder connection) {
10893        ContentProviderConnection conn;
10894        try {
10895            conn = (ContentProviderConnection)connection;
10896        } catch (ClassCastException e) {
10897            String msg ="refContentProvider: " + connection
10898                    + " not a ContentProviderConnection";
10899            Slog.w(TAG, msg);
10900            throw new IllegalArgumentException(msg);
10901        }
10902        if (conn == null) {
10903            throw new NullPointerException("connection is null");
10904        }
10905
10906        // Safely retrieve the content provider associated with the connection.
10907        IContentProvider provider;
10908        synchronized (this) {
10909            provider = conn.provider.provider;
10910        }
10911
10912        if (provider == null) {
10913            // Um, yeah, we're way ahead of you.
10914            return;
10915        }
10916
10917        // Make sure the caller is being honest with us.
10918        if (provider.asBinder().pingBinder()) {
10919            // Er, no, still looks good to us.
10920            synchronized (this) {
10921                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10922                        + " says " + conn + " died, but we don't agree");
10923                return;
10924            }
10925        }
10926
10927        // Well look at that!  It's dead!
10928        synchronized (this) {
10929            if (conn.provider.provider != provider) {
10930                // But something changed...  good enough.
10931                return;
10932            }
10933
10934            ProcessRecord proc = conn.provider.proc;
10935            if (proc == null || proc.thread == null) {
10936                // Seems like the process is already cleaned up.
10937                return;
10938            }
10939
10940            // As far as we're concerned, this is just like receiving a
10941            // death notification...  just a bit prematurely.
10942            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10943                    + ") early provider death");
10944            final long ident = Binder.clearCallingIdentity();
10945            try {
10946                appDiedLocked(proc);
10947            } finally {
10948                Binder.restoreCallingIdentity(ident);
10949            }
10950        }
10951    }
10952
10953    @Override
10954    public void appNotRespondingViaProvider(IBinder connection) {
10955        enforceCallingPermission(
10956                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10957
10958        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10959        if (conn == null) {
10960            Slog.w(TAG, "ContentProviderConnection is null");
10961            return;
10962        }
10963
10964        final ProcessRecord host = conn.provider.proc;
10965        if (host == null) {
10966            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10967            return;
10968        }
10969
10970        mHandler.post(new Runnable() {
10971            @Override
10972            public void run() {
10973                mAppErrors.appNotResponding(host, null, null, false,
10974                        "ContentProvider not responding");
10975            }
10976        });
10977    }
10978
10979    public final void installSystemProviders() {
10980        List<ProviderInfo> providers;
10981        synchronized (this) {
10982            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10983            providers = generateApplicationProvidersLocked(app);
10984            if (providers != null) {
10985                for (int i=providers.size()-1; i>=0; i--) {
10986                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10987                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10988                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10989                                + ": not system .apk");
10990                        providers.remove(i);
10991                    }
10992                }
10993            }
10994        }
10995        if (providers != null) {
10996            mSystemThread.installSystemProviders(providers);
10997        }
10998
10999        mCoreSettingsObserver = new CoreSettingsObserver(this);
11000        mFontScaleSettingObserver = new FontScaleSettingObserver();
11001
11002        //mUsageStatsService.monitorPackages();
11003    }
11004
11005    private void startPersistentApps(int matchFlags) {
11006        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11007
11008        synchronized (this) {
11009            try {
11010                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11011                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11012                for (ApplicationInfo app : apps) {
11013                    if (!"android".equals(app.packageName)) {
11014                        addAppLocked(app, false, null /* ABI override */);
11015                    }
11016                }
11017            } catch (RemoteException ex) {
11018            }
11019        }
11020    }
11021
11022    /**
11023     * When a user is unlocked, we need to install encryption-unaware providers
11024     * belonging to any running apps.
11025     */
11026    private void installEncryptionUnawareProviders(int userId) {
11027        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11028            // TODO: eventually pivot this back to look at current user state,
11029            // similar to the comment in UserManager.isUserUnlocked(), but for
11030            // now, if we started apps when "unlocked" then unaware providers
11031            // have already been spun up.
11032            return;
11033        }
11034
11035        // We're only interested in providers that are encryption unaware, and
11036        // we don't care about uninstalled apps, since there's no way they're
11037        // running at this point.
11038        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11039
11040        synchronized (this) {
11041            final int NP = mProcessNames.getMap().size();
11042            for (int ip = 0; ip < NP; ip++) {
11043                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11044                final int NA = apps.size();
11045                for (int ia = 0; ia < NA; ia++) {
11046                    final ProcessRecord app = apps.valueAt(ia);
11047                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11048
11049                    final int NG = app.pkgList.size();
11050                    for (int ig = 0; ig < NG; ig++) {
11051                        try {
11052                            final String pkgName = app.pkgList.keyAt(ig);
11053                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11054                                    .getPackageInfo(pkgName, matchFlags, userId);
11055                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11056                                for (ProviderInfo provInfo : pkgInfo.providers) {
11057                                    Log.v(TAG, "Installing " + provInfo);
11058                                    app.thread.scheduleInstallProvider(provInfo);
11059                                }
11060                            }
11061                        } catch (RemoteException ignored) {
11062                        }
11063                    }
11064                }
11065            }
11066        }
11067    }
11068
11069    /**
11070     * Allows apps to retrieve the MIME type of a URI.
11071     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11072     * users, then it does not need permission to access the ContentProvider.
11073     * Either, it needs cross-user uri grants.
11074     *
11075     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11076     *
11077     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11078     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11079     */
11080    public String getProviderMimeType(Uri uri, int userId) {
11081        enforceNotIsolatedCaller("getProviderMimeType");
11082        final String name = uri.getAuthority();
11083        int callingUid = Binder.getCallingUid();
11084        int callingPid = Binder.getCallingPid();
11085        long ident = 0;
11086        boolean clearedIdentity = false;
11087        synchronized (this) {
11088            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11089        }
11090        if (canClearIdentity(callingPid, callingUid, userId)) {
11091            clearedIdentity = true;
11092            ident = Binder.clearCallingIdentity();
11093        }
11094        ContentProviderHolder holder = null;
11095        try {
11096            holder = getContentProviderExternalUnchecked(name, null, userId);
11097            if (holder != null) {
11098                return holder.provider.getType(uri);
11099            }
11100        } catch (RemoteException e) {
11101            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11102            return null;
11103        } finally {
11104            // We need to clear the identity to call removeContentProviderExternalUnchecked
11105            if (!clearedIdentity) {
11106                ident = Binder.clearCallingIdentity();
11107            }
11108            try {
11109                if (holder != null) {
11110                    removeContentProviderExternalUnchecked(name, null, userId);
11111                }
11112            } finally {
11113                Binder.restoreCallingIdentity(ident);
11114            }
11115        }
11116
11117        return null;
11118    }
11119
11120    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11121        if (UserHandle.getUserId(callingUid) == userId) {
11122            return true;
11123        }
11124        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11125                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11126                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11127                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11128                return true;
11129        }
11130        return false;
11131    }
11132
11133    // =========================================================
11134    // GLOBAL MANAGEMENT
11135    // =========================================================
11136
11137    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11138            boolean isolated, int isolatedUid) {
11139        String proc = customProcess != null ? customProcess : info.processName;
11140        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11141        final int userId = UserHandle.getUserId(info.uid);
11142        int uid = info.uid;
11143        if (isolated) {
11144            if (isolatedUid == 0) {
11145                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11146                while (true) {
11147                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11148                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11149                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11150                    }
11151                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11152                    mNextIsolatedProcessUid++;
11153                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11154                        // No process for this uid, use it.
11155                        break;
11156                    }
11157                    stepsLeft--;
11158                    if (stepsLeft <= 0) {
11159                        return null;
11160                    }
11161                }
11162            } else {
11163                // Special case for startIsolatedProcess (internal only), where
11164                // the uid of the isolated process is specified by the caller.
11165                uid = isolatedUid;
11166            }
11167        }
11168        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11169        if (!mBooted && !mBooting
11170                && userId == UserHandle.USER_SYSTEM
11171                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11172            r.persistent = true;
11173        }
11174        addProcessNameLocked(r);
11175        return r;
11176    }
11177
11178    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11179            String abiOverride) {
11180        ProcessRecord app;
11181        if (!isolated) {
11182            app = getProcessRecordLocked(info.processName, info.uid, true);
11183        } else {
11184            app = null;
11185        }
11186
11187        if (app == null) {
11188            app = newProcessRecordLocked(info, null, isolated, 0);
11189            updateLruProcessLocked(app, false, null);
11190            updateOomAdjLocked();
11191        }
11192
11193        // This package really, really can not be stopped.
11194        try {
11195            AppGlobals.getPackageManager().setPackageStoppedState(
11196                    info.packageName, false, UserHandle.getUserId(app.uid));
11197        } catch (RemoteException e) {
11198        } catch (IllegalArgumentException e) {
11199            Slog.w(TAG, "Failed trying to unstop package "
11200                    + info.packageName + ": " + e);
11201        }
11202
11203        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11204            app.persistent = true;
11205            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11206        }
11207        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11208            mPersistentStartingProcesses.add(app);
11209            startProcessLocked(app, "added application", app.processName, abiOverride,
11210                    null /* entryPoint */, null /* entryPointArgs */);
11211        }
11212
11213        return app;
11214    }
11215
11216    public void unhandledBack() {
11217        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11218                "unhandledBack()");
11219
11220        synchronized(this) {
11221            final long origId = Binder.clearCallingIdentity();
11222            try {
11223                getFocusedStack().unhandledBackLocked();
11224            } finally {
11225                Binder.restoreCallingIdentity(origId);
11226            }
11227        }
11228    }
11229
11230    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11231        enforceNotIsolatedCaller("openContentUri");
11232        final int userId = UserHandle.getCallingUserId();
11233        String name = uri.getAuthority();
11234        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11235        ParcelFileDescriptor pfd = null;
11236        if (cph != null) {
11237            // We record the binder invoker's uid in thread-local storage before
11238            // going to the content provider to open the file.  Later, in the code
11239            // that handles all permissions checks, we look for this uid and use
11240            // that rather than the Activity Manager's own uid.  The effect is that
11241            // we do the check against the caller's permissions even though it looks
11242            // to the content provider like the Activity Manager itself is making
11243            // the request.
11244            Binder token = new Binder();
11245            sCallerIdentity.set(new Identity(
11246                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11247            try {
11248                pfd = cph.provider.openFile(null, uri, "r", null, token);
11249            } catch (FileNotFoundException e) {
11250                // do nothing; pfd will be returned null
11251            } finally {
11252                // Ensure that whatever happens, we clean up the identity state
11253                sCallerIdentity.remove();
11254                // Ensure we're done with the provider.
11255                removeContentProviderExternalUnchecked(name, null, userId);
11256            }
11257        } else {
11258            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11259        }
11260        return pfd;
11261    }
11262
11263    // Actually is sleeping or shutting down or whatever else in the future
11264    // is an inactive state.
11265    public boolean isSleepingOrShuttingDown() {
11266        return isSleeping() || mShuttingDown;
11267    }
11268
11269    public boolean isSleeping() {
11270        return mSleeping;
11271    }
11272
11273    void onWakefulnessChanged(int wakefulness) {
11274        synchronized(this) {
11275            mWakefulness = wakefulness;
11276            updateSleepIfNeededLocked();
11277        }
11278    }
11279
11280    void finishRunningVoiceLocked() {
11281        if (mRunningVoice != null) {
11282            mRunningVoice = null;
11283            mVoiceWakeLock.release();
11284            updateSleepIfNeededLocked();
11285        }
11286    }
11287
11288    void startTimeTrackingFocusedActivityLocked() {
11289        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11290            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11291        }
11292    }
11293
11294    void updateSleepIfNeededLocked() {
11295        if (mSleeping && !shouldSleepLocked()) {
11296            mSleeping = false;
11297            startTimeTrackingFocusedActivityLocked();
11298            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11299            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11300            updateOomAdjLocked();
11301        } else if (!mSleeping && shouldSleepLocked()) {
11302            mSleeping = true;
11303            if (mCurAppTimeTracker != null) {
11304                mCurAppTimeTracker.stop();
11305            }
11306            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11307            mStackSupervisor.goingToSleepLocked();
11308            updateOomAdjLocked();
11309
11310            // Initialize the wake times of all processes.
11311            checkExcessivePowerUsageLocked(false);
11312            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11313            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11314            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11315        }
11316    }
11317
11318    private boolean shouldSleepLocked() {
11319        // Resume applications while running a voice interactor.
11320        if (mRunningVoice != null) {
11321            return false;
11322        }
11323
11324        // TODO: Transform the lock screen state into a sleep token instead.
11325        switch (mWakefulness) {
11326            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11327            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11328            case PowerManagerInternal.WAKEFULNESS_DOZING:
11329                // Pause applications whenever the lock screen is shown or any sleep
11330                // tokens have been acquired.
11331                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11332            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11333            default:
11334                // If we're asleep then pause applications unconditionally.
11335                return true;
11336        }
11337    }
11338
11339    /** Pokes the task persister. */
11340    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11341        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11342    }
11343
11344    /** Notifies all listeners when the task stack has changed. */
11345    void notifyTaskStackChangedLocked() {
11346        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11347        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11348        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11349        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11350    }
11351
11352    /** Notifies all listeners when an Activity is pinned. */
11353    void notifyActivityPinnedLocked() {
11354        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11355        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11356    }
11357
11358    /**
11359     * Notifies all listeners when an attempt was made to start an an activity that is already
11360     * running in the pinned stack and the activity was not actually started, but the task is
11361     * either brought to the front or a new Intent is delivered to it.
11362     */
11363    void notifyPinnedActivityRestartAttemptLocked() {
11364        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11365        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11366    }
11367
11368    /** Notifies all listeners when the pinned stack animation ends. */
11369    @Override
11370    public void notifyPinnedStackAnimationEnded() {
11371        synchronized (this) {
11372            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11373            mHandler.obtainMessage(
11374                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11375        }
11376    }
11377
11378    @Override
11379    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11380        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11381    }
11382
11383    @Override
11384    public boolean shutdown(int timeout) {
11385        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11386                != PackageManager.PERMISSION_GRANTED) {
11387            throw new SecurityException("Requires permission "
11388                    + android.Manifest.permission.SHUTDOWN);
11389        }
11390
11391        boolean timedout = false;
11392
11393        synchronized(this) {
11394            mShuttingDown = true;
11395            updateEventDispatchingLocked();
11396            timedout = mStackSupervisor.shutdownLocked(timeout);
11397        }
11398
11399        mAppOpsService.shutdown();
11400        if (mUsageStatsService != null) {
11401            mUsageStatsService.prepareShutdown();
11402        }
11403        mBatteryStatsService.shutdown();
11404        synchronized (this) {
11405            mProcessStats.shutdownLocked();
11406            notifyTaskPersisterLocked(null, true);
11407        }
11408
11409        return timedout;
11410    }
11411
11412    public final void activitySlept(IBinder token) {
11413        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11414
11415        final long origId = Binder.clearCallingIdentity();
11416
11417        synchronized (this) {
11418            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11419            if (r != null) {
11420                mStackSupervisor.activitySleptLocked(r);
11421            }
11422        }
11423
11424        Binder.restoreCallingIdentity(origId);
11425    }
11426
11427    private String lockScreenShownToString() {
11428        switch (mLockScreenShown) {
11429            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11430            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11431            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11432            default: return "Unknown=" + mLockScreenShown;
11433        }
11434    }
11435
11436    void logLockScreen(String msg) {
11437        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11438                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11439                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11440                + " mSleeping=" + mSleeping);
11441    }
11442
11443    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11444        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11445        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11446        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11447            boolean wasRunningVoice = mRunningVoice != null;
11448            mRunningVoice = session;
11449            if (!wasRunningVoice) {
11450                mVoiceWakeLock.acquire();
11451                updateSleepIfNeededLocked();
11452            }
11453        }
11454    }
11455
11456    private void updateEventDispatchingLocked() {
11457        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11458    }
11459
11460    public void setLockScreenShown(boolean shown) {
11461        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11462                != PackageManager.PERMISSION_GRANTED) {
11463            throw new SecurityException("Requires permission "
11464                    + android.Manifest.permission.DEVICE_POWER);
11465        }
11466
11467        synchronized(this) {
11468            long ident = Binder.clearCallingIdentity();
11469            try {
11470                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11471                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11472                updateSleepIfNeededLocked();
11473            } finally {
11474                Binder.restoreCallingIdentity(ident);
11475            }
11476        }
11477    }
11478
11479    @Override
11480    public void notifyLockedProfile(@UserIdInt int userId) {
11481        try {
11482            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11483                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11484            }
11485        } catch (RemoteException ex) {
11486            throw new SecurityException("Fail to check is caller a privileged app", ex);
11487        }
11488
11489        synchronized (this) {
11490            if (mStackSupervisor.isUserLockedProfile(userId)) {
11491                final long ident = Binder.clearCallingIdentity();
11492                try {
11493                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11494                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11495                        // If there is no device lock, we will show the profile's credential page.
11496                        mActivityStarter.showConfirmDeviceCredential(userId);
11497                    } else {
11498                        // Showing launcher to avoid user entering credential twice.
11499                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11500                    }
11501                } finally {
11502                    Binder.restoreCallingIdentity(ident);
11503                }
11504            }
11505        }
11506    }
11507
11508    @Override
11509    public void startConfirmDeviceCredentialIntent(Intent intent) {
11510        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11511        synchronized (this) {
11512            final long ident = Binder.clearCallingIdentity();
11513            try {
11514                mActivityStarter.startConfirmCredentialIntent(intent);
11515            } finally {
11516                Binder.restoreCallingIdentity(ident);
11517            }
11518        }
11519    }
11520
11521    @Override
11522    public void stopAppSwitches() {
11523        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11524                != PackageManager.PERMISSION_GRANTED) {
11525            throw new SecurityException("viewquires permission "
11526                    + android.Manifest.permission.STOP_APP_SWITCHES);
11527        }
11528
11529        synchronized(this) {
11530            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11531                    + APP_SWITCH_DELAY_TIME;
11532            mDidAppSwitch = false;
11533            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11534            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11535            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11536        }
11537    }
11538
11539    public void resumeAppSwitches() {
11540        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11541                != PackageManager.PERMISSION_GRANTED) {
11542            throw new SecurityException("Requires permission "
11543                    + android.Manifest.permission.STOP_APP_SWITCHES);
11544        }
11545
11546        synchronized(this) {
11547            // Note that we don't execute any pending app switches... we will
11548            // let those wait until either the timeout, or the next start
11549            // activity request.
11550            mAppSwitchesAllowedTime = 0;
11551        }
11552    }
11553
11554    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11555            int callingPid, int callingUid, String name) {
11556        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11557            return true;
11558        }
11559
11560        int perm = checkComponentPermission(
11561                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11562                sourceUid, -1, true);
11563        if (perm == PackageManager.PERMISSION_GRANTED) {
11564            return true;
11565        }
11566
11567        // If the actual IPC caller is different from the logical source, then
11568        // also see if they are allowed to control app switches.
11569        if (callingUid != -1 && callingUid != sourceUid) {
11570            perm = checkComponentPermission(
11571                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11572                    callingUid, -1, true);
11573            if (perm == PackageManager.PERMISSION_GRANTED) {
11574                return true;
11575            }
11576        }
11577
11578        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11579        return false;
11580    }
11581
11582    public void setDebugApp(String packageName, boolean waitForDebugger,
11583            boolean persistent) {
11584        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11585                "setDebugApp()");
11586
11587        long ident = Binder.clearCallingIdentity();
11588        try {
11589            // Note that this is not really thread safe if there are multiple
11590            // callers into it at the same time, but that's not a situation we
11591            // care about.
11592            if (persistent) {
11593                final ContentResolver resolver = mContext.getContentResolver();
11594                Settings.Global.putString(
11595                    resolver, Settings.Global.DEBUG_APP,
11596                    packageName);
11597                Settings.Global.putInt(
11598                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11599                    waitForDebugger ? 1 : 0);
11600            }
11601
11602            synchronized (this) {
11603                if (!persistent) {
11604                    mOrigDebugApp = mDebugApp;
11605                    mOrigWaitForDebugger = mWaitForDebugger;
11606                }
11607                mDebugApp = packageName;
11608                mWaitForDebugger = waitForDebugger;
11609                mDebugTransient = !persistent;
11610                if (packageName != null) {
11611                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11612                            false, UserHandle.USER_ALL, "set debug app");
11613                }
11614            }
11615        } finally {
11616            Binder.restoreCallingIdentity(ident);
11617        }
11618    }
11619
11620    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11621        synchronized (this) {
11622            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11623            if (!isDebuggable) {
11624                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11625                    throw new SecurityException("Process not debuggable: " + app.packageName);
11626                }
11627            }
11628
11629            mTrackAllocationApp = processName;
11630        }
11631    }
11632
11633    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11634        synchronized (this) {
11635            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11636            if (!isDebuggable) {
11637                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11638                    throw new SecurityException("Process not debuggable: " + app.packageName);
11639                }
11640            }
11641            mProfileApp = processName;
11642            mProfileFile = profilerInfo.profileFile;
11643            if (mProfileFd != null) {
11644                try {
11645                    mProfileFd.close();
11646                } catch (IOException e) {
11647                }
11648                mProfileFd = null;
11649            }
11650            mProfileFd = profilerInfo.profileFd;
11651            mSamplingInterval = profilerInfo.samplingInterval;
11652            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11653            mProfileType = 0;
11654        }
11655    }
11656
11657    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11658        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11659        if (!isDebuggable) {
11660            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11661                throw new SecurityException("Process not debuggable: " + app.packageName);
11662            }
11663        }
11664        mNativeDebuggingApp = processName;
11665    }
11666
11667    @Override
11668    public void setAlwaysFinish(boolean enabled) {
11669        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11670                "setAlwaysFinish()");
11671
11672        long ident = Binder.clearCallingIdentity();
11673        try {
11674            Settings.Global.putInt(
11675                    mContext.getContentResolver(),
11676                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11677
11678            synchronized (this) {
11679                mAlwaysFinishActivities = enabled;
11680            }
11681        } finally {
11682            Binder.restoreCallingIdentity(ident);
11683        }
11684    }
11685
11686    @Override
11687    public void setLenientBackgroundCheck(boolean enabled) {
11688        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11689                "setLenientBackgroundCheck()");
11690
11691        long ident = Binder.clearCallingIdentity();
11692        try {
11693            Settings.Global.putInt(
11694                    mContext.getContentResolver(),
11695                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11696
11697            synchronized (this) {
11698                mLenientBackgroundCheck = enabled;
11699            }
11700        } finally {
11701            Binder.restoreCallingIdentity(ident);
11702        }
11703    }
11704
11705    @Override
11706    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11707        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11708                "setActivityController()");
11709        synchronized (this) {
11710            mController = controller;
11711            mControllerIsAMonkey = imAMonkey;
11712            Watchdog.getInstance().setActivityController(controller);
11713        }
11714    }
11715
11716    @Override
11717    public void setUserIsMonkey(boolean userIsMonkey) {
11718        synchronized (this) {
11719            synchronized (mPidsSelfLocked) {
11720                final int callingPid = Binder.getCallingPid();
11721                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11722                if (precessRecord == null) {
11723                    throw new SecurityException("Unknown process: " + callingPid);
11724                }
11725                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11726                    throw new SecurityException("Only an instrumentation process "
11727                            + "with a UiAutomation can call setUserIsMonkey");
11728                }
11729            }
11730            mUserIsMonkey = userIsMonkey;
11731        }
11732    }
11733
11734    @Override
11735    public boolean isUserAMonkey() {
11736        synchronized (this) {
11737            // If there is a controller also implies the user is a monkey.
11738            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11739        }
11740    }
11741
11742    public void requestBugReport(int bugreportType) {
11743        String service = null;
11744        switch (bugreportType) {
11745            case ActivityManager.BUGREPORT_OPTION_FULL:
11746                service = "bugreport";
11747                break;
11748            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11749                service = "bugreportplus";
11750                break;
11751            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11752                service = "bugreportremote";
11753                break;
11754        }
11755        if (service == null) {
11756            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11757                    + bugreportType);
11758        }
11759        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11760        SystemProperties.set("ctl.start", service);
11761    }
11762
11763    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11764        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11765    }
11766
11767    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11768        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11769            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11770        }
11771        return KEY_DISPATCHING_TIMEOUT;
11772    }
11773
11774    @Override
11775    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11776        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11777                != PackageManager.PERMISSION_GRANTED) {
11778            throw new SecurityException("Requires permission "
11779                    + android.Manifest.permission.FILTER_EVENTS);
11780        }
11781        ProcessRecord proc;
11782        long timeout;
11783        synchronized (this) {
11784            synchronized (mPidsSelfLocked) {
11785                proc = mPidsSelfLocked.get(pid);
11786            }
11787            timeout = getInputDispatchingTimeoutLocked(proc);
11788        }
11789
11790        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11791            return -1;
11792        }
11793
11794        return timeout;
11795    }
11796
11797    /**
11798     * Handle input dispatching timeouts.
11799     * Returns whether input dispatching should be aborted or not.
11800     */
11801    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11802            final ActivityRecord activity, final ActivityRecord parent,
11803            final boolean aboveSystem, String reason) {
11804        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11805                != PackageManager.PERMISSION_GRANTED) {
11806            throw new SecurityException("Requires permission "
11807                    + android.Manifest.permission.FILTER_EVENTS);
11808        }
11809
11810        final String annotation;
11811        if (reason == null) {
11812            annotation = "Input dispatching timed out";
11813        } else {
11814            annotation = "Input dispatching timed out (" + reason + ")";
11815        }
11816
11817        if (proc != null) {
11818            synchronized (this) {
11819                if (proc.debugging) {
11820                    return false;
11821                }
11822
11823                if (mDidDexOpt) {
11824                    // Give more time since we were dexopting.
11825                    mDidDexOpt = false;
11826                    return false;
11827                }
11828
11829                if (proc.instrumentationClass != null) {
11830                    Bundle info = new Bundle();
11831                    info.putString("shortMsg", "keyDispatchingTimedOut");
11832                    info.putString("longMsg", annotation);
11833                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11834                    return true;
11835                }
11836            }
11837            mHandler.post(new Runnable() {
11838                @Override
11839                public void run() {
11840                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11841                }
11842            });
11843        }
11844
11845        return true;
11846    }
11847
11848    @Override
11849    public Bundle getAssistContextExtras(int requestType) {
11850        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11851                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11852        if (pae == null) {
11853            return null;
11854        }
11855        synchronized (pae) {
11856            while (!pae.haveResult) {
11857                try {
11858                    pae.wait();
11859                } catch (InterruptedException e) {
11860                }
11861            }
11862        }
11863        synchronized (this) {
11864            buildAssistBundleLocked(pae, pae.result);
11865            mPendingAssistExtras.remove(pae);
11866            mUiHandler.removeCallbacks(pae);
11867        }
11868        return pae.extras;
11869    }
11870
11871    @Override
11872    public boolean isAssistDataAllowedOnCurrentActivity() {
11873        int userId;
11874        synchronized (this) {
11875            userId = mUserController.getCurrentUserIdLocked();
11876            ActivityRecord activity = getFocusedStack().topActivity();
11877            if (activity == null) {
11878                return false;
11879            }
11880            userId = activity.userId;
11881        }
11882        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11883                Context.DEVICE_POLICY_SERVICE);
11884        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11885    }
11886
11887    @Override
11888    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11889        long ident = Binder.clearCallingIdentity();
11890        try {
11891            synchronized (this) {
11892                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11893                ActivityRecord top = getFocusedStack().topActivity();
11894                if (top != caller) {
11895                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11896                            + " is not current top " + top);
11897                    return false;
11898                }
11899                if (!top.nowVisible) {
11900                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11901                            + " is not visible");
11902                    return false;
11903                }
11904            }
11905            AssistUtils utils = new AssistUtils(mContext);
11906            return utils.showSessionForActiveService(args,
11907                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11908        } finally {
11909            Binder.restoreCallingIdentity(ident);
11910        }
11911    }
11912
11913    @Override
11914    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11915            Bundle receiverExtras,
11916            IBinder activityToken, boolean focused) {
11917        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11918                activityToken, focused,
11919                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11920                != null;
11921    }
11922
11923    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11924            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11925            int userHandle, Bundle args, long timeout) {
11926        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11927                "enqueueAssistContext()");
11928        synchronized (this) {
11929            ActivityRecord activity = getFocusedStack().topActivity();
11930            if (activity == null) {
11931                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11932                return null;
11933            }
11934            if (activity.app == null || activity.app.thread == null) {
11935                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11936                return null;
11937            }
11938            if (focused) {
11939                if (activityToken != null) {
11940                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11941                    if (activity != caller) {
11942                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11943                                + " is not current top " + activity);
11944                        return null;
11945                    }
11946                }
11947            } else {
11948                activity = ActivityRecord.forTokenLocked(activityToken);
11949                if (activity == null) {
11950                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11951                            + " couldn't be found");
11952                    return null;
11953                }
11954            }
11955
11956            PendingAssistExtras pae;
11957            Bundle extras = new Bundle();
11958            if (args != null) {
11959                extras.putAll(args);
11960            }
11961            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11962            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11963            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11964                    userHandle);
11965            try {
11966                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11967                        requestType);
11968                mPendingAssistExtras.add(pae);
11969                mUiHandler.postDelayed(pae, timeout);
11970            } catch (RemoteException e) {
11971                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11972                return null;
11973            }
11974            return pae;
11975        }
11976    }
11977
11978    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11979        IResultReceiver receiver;
11980        synchronized (this) {
11981            mPendingAssistExtras.remove(pae);
11982            receiver = pae.receiver;
11983        }
11984        if (receiver != null) {
11985            // Caller wants result sent back to them.
11986            try {
11987                pae.receiver.send(0, null);
11988            } catch (RemoteException e) {
11989            }
11990        }
11991    }
11992
11993    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11994        if (result != null) {
11995            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11996        }
11997        if (pae.hint != null) {
11998            pae.extras.putBoolean(pae.hint, true);
11999        }
12000    }
12001
12002    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12003            AssistContent content, Uri referrer) {
12004        PendingAssistExtras pae = (PendingAssistExtras)token;
12005        synchronized (pae) {
12006            pae.result = extras;
12007            pae.structure = structure;
12008            pae.content = content;
12009            if (referrer != null) {
12010                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12011            }
12012            pae.haveResult = true;
12013            pae.notifyAll();
12014            if (pae.intent == null && pae.receiver == null) {
12015                // Caller is just waiting for the result.
12016                return;
12017            }
12018        }
12019
12020        // We are now ready to launch the assist activity.
12021        IResultReceiver sendReceiver = null;
12022        Bundle sendBundle = null;
12023        synchronized (this) {
12024            buildAssistBundleLocked(pae, extras);
12025            boolean exists = mPendingAssistExtras.remove(pae);
12026            mUiHandler.removeCallbacks(pae);
12027            if (!exists) {
12028                // Timed out.
12029                return;
12030            }
12031            if ((sendReceiver=pae.receiver) != null) {
12032                // Caller wants result sent back to them.
12033                sendBundle = new Bundle();
12034                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12035                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12036                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12037                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12038                        pae.receiverExtras);
12039            }
12040        }
12041        if (sendReceiver != null) {
12042            try {
12043                sendReceiver.send(0, sendBundle);
12044            } catch (RemoteException e) {
12045            }
12046            return;
12047        }
12048
12049        long ident = Binder.clearCallingIdentity();
12050        try {
12051            pae.intent.replaceExtras(pae.extras);
12052            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12053                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12054                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12055            closeSystemDialogs("assist");
12056            try {
12057                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12058            } catch (ActivityNotFoundException e) {
12059                Slog.w(TAG, "No activity to handle assist action.", e);
12060            }
12061        } finally {
12062            Binder.restoreCallingIdentity(ident);
12063        }
12064    }
12065
12066    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12067            Bundle args) {
12068        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12069                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12070    }
12071
12072    public void registerProcessObserver(IProcessObserver observer) {
12073        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12074                "registerProcessObserver()");
12075        synchronized (this) {
12076            mProcessObservers.register(observer);
12077        }
12078    }
12079
12080    @Override
12081    public void unregisterProcessObserver(IProcessObserver observer) {
12082        synchronized (this) {
12083            mProcessObservers.unregister(observer);
12084        }
12085    }
12086
12087    @Override
12088    public void registerUidObserver(IUidObserver observer, int which) {
12089        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12090                "registerUidObserver()");
12091        synchronized (this) {
12092            mUidObservers.register(observer, which);
12093        }
12094    }
12095
12096    @Override
12097    public void unregisterUidObserver(IUidObserver observer) {
12098        synchronized (this) {
12099            mUidObservers.unregister(observer);
12100        }
12101    }
12102
12103    @Override
12104    public boolean convertFromTranslucent(IBinder token) {
12105        final long origId = Binder.clearCallingIdentity();
12106        try {
12107            synchronized (this) {
12108                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12109                if (r == null) {
12110                    return false;
12111                }
12112                final boolean translucentChanged = r.changeWindowTranslucency(true);
12113                if (translucentChanged) {
12114                    r.task.stack.releaseBackgroundResources(r);
12115                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12116                }
12117                mWindowManager.setAppFullscreen(token, true);
12118                return translucentChanged;
12119            }
12120        } finally {
12121            Binder.restoreCallingIdentity(origId);
12122        }
12123    }
12124
12125    @Override
12126    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12127        final long origId = Binder.clearCallingIdentity();
12128        try {
12129            synchronized (this) {
12130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12131                if (r == null) {
12132                    return false;
12133                }
12134                int index = r.task.mActivities.lastIndexOf(r);
12135                if (index > 0) {
12136                    ActivityRecord under = r.task.mActivities.get(index - 1);
12137                    under.returningOptions = options;
12138                }
12139                final boolean translucentChanged = r.changeWindowTranslucency(false);
12140                if (translucentChanged) {
12141                    r.task.stack.convertActivityToTranslucent(r);
12142                }
12143                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12144                mWindowManager.setAppFullscreen(token, false);
12145                return translucentChanged;
12146            }
12147        } finally {
12148            Binder.restoreCallingIdentity(origId);
12149        }
12150    }
12151
12152    @Override
12153    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12154        final long origId = Binder.clearCallingIdentity();
12155        try {
12156            synchronized (this) {
12157                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12158                if (r != null) {
12159                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12160                }
12161            }
12162            return false;
12163        } finally {
12164            Binder.restoreCallingIdentity(origId);
12165        }
12166    }
12167
12168    @Override
12169    public boolean isBackgroundVisibleBehind(IBinder token) {
12170        final long origId = Binder.clearCallingIdentity();
12171        try {
12172            synchronized (this) {
12173                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12174                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12175                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12176                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12177                return visible;
12178            }
12179        } finally {
12180            Binder.restoreCallingIdentity(origId);
12181        }
12182    }
12183
12184    @Override
12185    public ActivityOptions getActivityOptions(IBinder token) {
12186        final long origId = Binder.clearCallingIdentity();
12187        try {
12188            synchronized (this) {
12189                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12190                if (r != null) {
12191                    final ActivityOptions activityOptions = r.pendingOptions;
12192                    r.pendingOptions = null;
12193                    return activityOptions;
12194                }
12195                return null;
12196            }
12197        } finally {
12198            Binder.restoreCallingIdentity(origId);
12199        }
12200    }
12201
12202    @Override
12203    public void setImmersive(IBinder token, boolean immersive) {
12204        synchronized(this) {
12205            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12206            if (r == null) {
12207                throw new IllegalArgumentException();
12208            }
12209            r.immersive = immersive;
12210
12211            // update associated state if we're frontmost
12212            if (r == mFocusedActivity) {
12213                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12214                applyUpdateLockStateLocked(r);
12215            }
12216        }
12217    }
12218
12219    @Override
12220    public boolean isImmersive(IBinder token) {
12221        synchronized (this) {
12222            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12223            if (r == null) {
12224                throw new IllegalArgumentException();
12225            }
12226            return r.immersive;
12227        }
12228    }
12229
12230    @Override
12231    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12232        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12233            throw new UnsupportedOperationException("VR mode not supported on this device!");
12234        }
12235
12236        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12237
12238        ActivityRecord r;
12239        synchronized (this) {
12240            r = ActivityRecord.isInStackLocked(token);
12241        }
12242
12243        if (r == null) {
12244            throw new IllegalArgumentException();
12245        }
12246
12247        int err;
12248        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12249                VrManagerInternal.NO_ERROR) {
12250            return err;
12251        }
12252
12253        synchronized(this) {
12254            r.requestedVrComponent = (enabled) ? packageName : null;
12255
12256            // Update associated state if this activity is currently focused
12257            if (r == mFocusedActivity) {
12258                applyUpdateVrModeLocked(r);
12259            }
12260            return 0;
12261        }
12262    }
12263
12264    @Override
12265    public boolean isVrModePackageEnabled(ComponentName packageName) {
12266        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12267            throw new UnsupportedOperationException("VR mode not supported on this device!");
12268        }
12269
12270        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12271
12272        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12273                VrManagerInternal.NO_ERROR;
12274    }
12275
12276    public boolean isTopActivityImmersive() {
12277        enforceNotIsolatedCaller("startActivity");
12278        synchronized (this) {
12279            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12280            return (r != null) ? r.immersive : false;
12281        }
12282    }
12283
12284    @Override
12285    public boolean isTopOfTask(IBinder token) {
12286        synchronized (this) {
12287            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12288            if (r == null) {
12289                throw new IllegalArgumentException();
12290            }
12291            return r.task.getTopActivity() == r;
12292        }
12293    }
12294
12295    public final void enterSafeMode() {
12296        synchronized(this) {
12297            // It only makes sense to do this before the system is ready
12298            // and started launching other packages.
12299            if (!mSystemReady) {
12300                try {
12301                    AppGlobals.getPackageManager().enterSafeMode();
12302                } catch (RemoteException e) {
12303                }
12304            }
12305
12306            mSafeMode = true;
12307        }
12308    }
12309
12310    public final void showSafeModeOverlay() {
12311        View v = LayoutInflater.from(mContext).inflate(
12312                com.android.internal.R.layout.safe_mode, null);
12313        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12314        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12315        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12316        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12317        lp.gravity = Gravity.BOTTOM | Gravity.START;
12318        lp.format = v.getBackground().getOpacity();
12319        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12320                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12321        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12322        ((WindowManager)mContext.getSystemService(
12323                Context.WINDOW_SERVICE)).addView(v, lp);
12324    }
12325
12326    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12327        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12328            return;
12329        }
12330        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12331        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12332        synchronized (stats) {
12333            if (mBatteryStatsService.isOnBattery()) {
12334                mBatteryStatsService.enforceCallingPermission();
12335                int MY_UID = Binder.getCallingUid();
12336                final int uid;
12337                if (sender == null) {
12338                    uid = sourceUid;
12339                } else {
12340                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12341                }
12342                BatteryStatsImpl.Uid.Pkg pkg =
12343                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12344                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12345                pkg.noteWakeupAlarmLocked(tag);
12346            }
12347        }
12348    }
12349
12350    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12351        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12352            return;
12353        }
12354        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12355        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12356        synchronized (stats) {
12357            mBatteryStatsService.enforceCallingPermission();
12358            int MY_UID = Binder.getCallingUid();
12359            final int uid;
12360            if (sender == null) {
12361                uid = sourceUid;
12362            } else {
12363                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12364            }
12365            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12366        }
12367    }
12368
12369    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12370        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12371            return;
12372        }
12373        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12374        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12375        synchronized (stats) {
12376            mBatteryStatsService.enforceCallingPermission();
12377            int MY_UID = Binder.getCallingUid();
12378            final int uid;
12379            if (sender == null) {
12380                uid = sourceUid;
12381            } else {
12382                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12383            }
12384            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12385        }
12386    }
12387
12388    public boolean killPids(int[] pids, String pReason, boolean secure) {
12389        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12390            throw new SecurityException("killPids only available to the system");
12391        }
12392        String reason = (pReason == null) ? "Unknown" : pReason;
12393        // XXX Note: don't acquire main activity lock here, because the window
12394        // manager calls in with its locks held.
12395
12396        boolean killed = false;
12397        synchronized (mPidsSelfLocked) {
12398            int worstType = 0;
12399            for (int i=0; i<pids.length; i++) {
12400                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12401                if (proc != null) {
12402                    int type = proc.setAdj;
12403                    if (type > worstType) {
12404                        worstType = type;
12405                    }
12406                }
12407            }
12408
12409            // If the worst oom_adj is somewhere in the cached proc LRU range,
12410            // then constrain it so we will kill all cached procs.
12411            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12412                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12413                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12414            }
12415
12416            // If this is not a secure call, don't let it kill processes that
12417            // are important.
12418            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12419                worstType = ProcessList.SERVICE_ADJ;
12420            }
12421
12422            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12423            for (int i=0; i<pids.length; i++) {
12424                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12425                if (proc == null) {
12426                    continue;
12427                }
12428                int adj = proc.setAdj;
12429                if (adj >= worstType && !proc.killedByAm) {
12430                    proc.kill(reason, true);
12431                    killed = true;
12432                }
12433            }
12434        }
12435        return killed;
12436    }
12437
12438    @Override
12439    public void killUid(int appId, int userId, String reason) {
12440        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12441        synchronized (this) {
12442            final long identity = Binder.clearCallingIdentity();
12443            try {
12444                killPackageProcessesLocked(null, appId, userId,
12445                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12446                        reason != null ? reason : "kill uid");
12447            } finally {
12448                Binder.restoreCallingIdentity(identity);
12449            }
12450        }
12451    }
12452
12453    @Override
12454    public boolean killProcessesBelowForeground(String reason) {
12455        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12456            throw new SecurityException("killProcessesBelowForeground() only available to system");
12457        }
12458
12459        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12460    }
12461
12462    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12463        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12464            throw new SecurityException("killProcessesBelowAdj() only available to system");
12465        }
12466
12467        boolean killed = false;
12468        synchronized (mPidsSelfLocked) {
12469            final int size = mPidsSelfLocked.size();
12470            for (int i = 0; i < size; i++) {
12471                final int pid = mPidsSelfLocked.keyAt(i);
12472                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12473                if (proc == null) continue;
12474
12475                final int adj = proc.setAdj;
12476                if (adj > belowAdj && !proc.killedByAm) {
12477                    proc.kill(reason, true);
12478                    killed = true;
12479                }
12480            }
12481        }
12482        return killed;
12483    }
12484
12485    @Override
12486    public void hang(final IBinder who, boolean allowRestart) {
12487        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12488                != PackageManager.PERMISSION_GRANTED) {
12489            throw new SecurityException("Requires permission "
12490                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12491        }
12492
12493        final IBinder.DeathRecipient death = new DeathRecipient() {
12494            @Override
12495            public void binderDied() {
12496                synchronized (this) {
12497                    notifyAll();
12498                }
12499            }
12500        };
12501
12502        try {
12503            who.linkToDeath(death, 0);
12504        } catch (RemoteException e) {
12505            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12506            return;
12507        }
12508
12509        synchronized (this) {
12510            Watchdog.getInstance().setAllowRestart(allowRestart);
12511            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12512            synchronized (death) {
12513                while (who.isBinderAlive()) {
12514                    try {
12515                        death.wait();
12516                    } catch (InterruptedException e) {
12517                    }
12518                }
12519            }
12520            Watchdog.getInstance().setAllowRestart(true);
12521        }
12522    }
12523
12524    @Override
12525    public void restart() {
12526        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12527                != PackageManager.PERMISSION_GRANTED) {
12528            throw new SecurityException("Requires permission "
12529                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12530        }
12531
12532        Log.i(TAG, "Sending shutdown broadcast...");
12533
12534        BroadcastReceiver br = new BroadcastReceiver() {
12535            @Override public void onReceive(Context context, Intent intent) {
12536                // Now the broadcast is done, finish up the low-level shutdown.
12537                Log.i(TAG, "Shutting down activity manager...");
12538                shutdown(10000);
12539                Log.i(TAG, "Shutdown complete, restarting!");
12540                Process.killProcess(Process.myPid());
12541                System.exit(10);
12542            }
12543        };
12544
12545        // First send the high-level shut down broadcast.
12546        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12547        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12548        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12549        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12550        mContext.sendOrderedBroadcastAsUser(intent,
12551                UserHandle.ALL, null, br, mHandler, 0, null, null);
12552        */
12553        br.onReceive(mContext, intent);
12554    }
12555
12556    private long getLowRamTimeSinceIdle(long now) {
12557        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12558    }
12559
12560    @Override
12561    public void performIdleMaintenance() {
12562        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12563                != PackageManager.PERMISSION_GRANTED) {
12564            throw new SecurityException("Requires permission "
12565                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12566        }
12567
12568        synchronized (this) {
12569            final long now = SystemClock.uptimeMillis();
12570            final long timeSinceLastIdle = now - mLastIdleTime;
12571            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12572            mLastIdleTime = now;
12573            mLowRamTimeSinceLastIdle = 0;
12574            if (mLowRamStartTime != 0) {
12575                mLowRamStartTime = now;
12576            }
12577
12578            StringBuilder sb = new StringBuilder(128);
12579            sb.append("Idle maintenance over ");
12580            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12581            sb.append(" low RAM for ");
12582            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12583            Slog.i(TAG, sb.toString());
12584
12585            // If at least 1/3 of our time since the last idle period has been spent
12586            // with RAM low, then we want to kill processes.
12587            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12588
12589            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12590                ProcessRecord proc = mLruProcesses.get(i);
12591                if (proc.notCachedSinceIdle) {
12592                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12593                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12594                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12595                        if (doKilling && proc.initialIdlePss != 0
12596                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12597                            sb = new StringBuilder(128);
12598                            sb.append("Kill");
12599                            sb.append(proc.processName);
12600                            sb.append(" in idle maint: pss=");
12601                            sb.append(proc.lastPss);
12602                            sb.append(", swapPss=");
12603                            sb.append(proc.lastSwapPss);
12604                            sb.append(", initialPss=");
12605                            sb.append(proc.initialIdlePss);
12606                            sb.append(", period=");
12607                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12608                            sb.append(", lowRamPeriod=");
12609                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12610                            Slog.wtfQuiet(TAG, sb.toString());
12611                            proc.kill("idle maint (pss " + proc.lastPss
12612                                    + " from " + proc.initialIdlePss + ")", true);
12613                        }
12614                    }
12615                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12616                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12617                    proc.notCachedSinceIdle = true;
12618                    proc.initialIdlePss = 0;
12619                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12620                            mTestPssMode, isSleeping(), now);
12621                }
12622            }
12623
12624            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12625            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12626        }
12627    }
12628
12629    private void retrieveSettings() {
12630        final ContentResolver resolver = mContext.getContentResolver();
12631        final boolean freeformWindowManagement =
12632                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12633                        || Settings.Global.getInt(
12634                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12635        final boolean supportsPictureInPicture =
12636                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12637
12638        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12639        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12640        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12641        final boolean alwaysFinishActivities =
12642                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12643        final boolean lenientBackgroundCheck =
12644                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12645        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12646        final boolean forceResizable = Settings.Global.getInt(
12647                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12648        // Transfer any global setting for forcing RTL layout, into a System Property
12649        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12650
12651        final Configuration configuration = new Configuration();
12652        Settings.System.getConfiguration(resolver, configuration);
12653        if (forceRtl) {
12654            // This will take care of setting the correct layout direction flags
12655            configuration.setLayoutDirection(configuration.locale);
12656        }
12657
12658        synchronized (this) {
12659            mDebugApp = mOrigDebugApp = debugApp;
12660            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12661            mAlwaysFinishActivities = alwaysFinishActivities;
12662            mLenientBackgroundCheck = lenientBackgroundCheck;
12663            mForceResizableActivities = forceResizable;
12664            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12665            if (supportsMultiWindow || forceResizable) {
12666                mSupportsMultiWindow = true;
12667                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12668                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12669            } else {
12670                mSupportsMultiWindow = false;
12671                mSupportsFreeformWindowManagement = false;
12672                mSupportsPictureInPicture = false;
12673            }
12674            // This happens before any activities are started, so we can
12675            // change mConfiguration in-place.
12676            updateConfigurationLocked(configuration, null, true);
12677            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12678                    "Initial config: " + mConfiguration);
12679
12680            // Load resources only after the current configuration has been set.
12681            final Resources res = mContext.getResources();
12682            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12683            mThumbnailWidth = res.getDimensionPixelSize(
12684                    com.android.internal.R.dimen.thumbnail_width);
12685            mThumbnailHeight = res.getDimensionPixelSize(
12686                    com.android.internal.R.dimen.thumbnail_height);
12687            mFullscreenThumbnailScale = res.getFraction(
12688                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12689            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12690                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12691            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12692                    com.android.internal.R.string.config_appsNotReportingCrashes));
12693        }
12694    }
12695
12696    public boolean testIsSystemReady() {
12697        // no need to synchronize(this) just to read & return the value
12698        return mSystemReady;
12699    }
12700
12701    public void systemReady(final Runnable goingCallback) {
12702        synchronized(this) {
12703            if (mSystemReady) {
12704                // If we're done calling all the receivers, run the next "boot phase" passed in
12705                // by the SystemServer
12706                if (goingCallback != null) {
12707                    goingCallback.run();
12708                }
12709                return;
12710            }
12711
12712            mLocalDeviceIdleController
12713                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12714
12715            // Make sure we have the current profile info, since it is needed for security checks.
12716            mUserController.onSystemReady();
12717            mRecentTasks.onSystemReadyLocked();
12718            mAppOpsService.systemReady();
12719            mSystemReady = true;
12720        }
12721
12722        ArrayList<ProcessRecord> procsToKill = null;
12723        synchronized(mPidsSelfLocked) {
12724            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12725                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12726                if (!isAllowedWhileBooting(proc.info)){
12727                    if (procsToKill == null) {
12728                        procsToKill = new ArrayList<ProcessRecord>();
12729                    }
12730                    procsToKill.add(proc);
12731                }
12732            }
12733        }
12734
12735        synchronized(this) {
12736            if (procsToKill != null) {
12737                for (int i=procsToKill.size()-1; i>=0; i--) {
12738                    ProcessRecord proc = procsToKill.get(i);
12739                    Slog.i(TAG, "Removing system update proc: " + proc);
12740                    removeProcessLocked(proc, true, false, "system update done");
12741                }
12742            }
12743
12744            // Now that we have cleaned up any update processes, we
12745            // are ready to start launching real processes and know that
12746            // we won't trample on them any more.
12747            mProcessesReady = true;
12748        }
12749
12750        Slog.i(TAG, "System now ready");
12751        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12752            SystemClock.uptimeMillis());
12753
12754        synchronized(this) {
12755            // Make sure we have no pre-ready processes sitting around.
12756
12757            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12758                ResolveInfo ri = mContext.getPackageManager()
12759                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12760                                STOCK_PM_FLAGS);
12761                CharSequence errorMsg = null;
12762                if (ri != null) {
12763                    ActivityInfo ai = ri.activityInfo;
12764                    ApplicationInfo app = ai.applicationInfo;
12765                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12766                        mTopAction = Intent.ACTION_FACTORY_TEST;
12767                        mTopData = null;
12768                        mTopComponent = new ComponentName(app.packageName,
12769                                ai.name);
12770                    } else {
12771                        errorMsg = mContext.getResources().getText(
12772                                com.android.internal.R.string.factorytest_not_system);
12773                    }
12774                } else {
12775                    errorMsg = mContext.getResources().getText(
12776                            com.android.internal.R.string.factorytest_no_action);
12777                }
12778                if (errorMsg != null) {
12779                    mTopAction = null;
12780                    mTopData = null;
12781                    mTopComponent = null;
12782                    Message msg = Message.obtain();
12783                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12784                    msg.getData().putCharSequence("msg", errorMsg);
12785                    mUiHandler.sendMessage(msg);
12786                }
12787            }
12788        }
12789
12790        retrieveSettings();
12791        final int currentUserId;
12792        synchronized (this) {
12793            currentUserId = mUserController.getCurrentUserIdLocked();
12794            readGrantedUriPermissionsLocked();
12795        }
12796
12797        if (goingCallback != null) goingCallback.run();
12798
12799        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12800                Integer.toString(currentUserId), currentUserId);
12801        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12802                Integer.toString(currentUserId), currentUserId);
12803        mSystemServiceManager.startUser(currentUserId);
12804
12805        synchronized (this) {
12806            // Only start up encryption-aware persistent apps; once user is
12807            // unlocked we'll come back around and start unaware apps
12808            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12809
12810            // Start up initial activity.
12811            mBooting = true;
12812            // Enable home activity for system user, so that the system can always boot
12813            if (UserManager.isSplitSystemUser()) {
12814                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12815                try {
12816                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12817                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12818                            UserHandle.USER_SYSTEM);
12819                } catch (RemoteException e) {
12820                    throw e.rethrowAsRuntimeException();
12821                }
12822            }
12823            startHomeActivityLocked(currentUserId, "systemReady");
12824
12825            try {
12826                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12827                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12828                            + " data partition or your device will be unstable.");
12829                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12830                }
12831            } catch (RemoteException e) {
12832            }
12833
12834            if (!Build.isBuildConsistent()) {
12835                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12836                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12837            }
12838
12839            long ident = Binder.clearCallingIdentity();
12840            try {
12841                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12842                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12843                        | Intent.FLAG_RECEIVER_FOREGROUND);
12844                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12845                broadcastIntentLocked(null, null, intent,
12846                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12847                        null, false, false, MY_PID, Process.SYSTEM_UID,
12848                        currentUserId);
12849                intent = new Intent(Intent.ACTION_USER_STARTING);
12850                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12851                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12852                broadcastIntentLocked(null, null, intent,
12853                        null, new IIntentReceiver.Stub() {
12854                            @Override
12855                            public void performReceive(Intent intent, int resultCode, String data,
12856                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12857                                    throws RemoteException {
12858                            }
12859                        }, 0, null, null,
12860                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12861                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12862            } catch (Throwable t) {
12863                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12864            } finally {
12865                Binder.restoreCallingIdentity(ident);
12866            }
12867            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12868            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12869        }
12870    }
12871
12872    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12873        synchronized (this) {
12874            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12875        }
12876    }
12877
12878    void skipCurrentReceiverLocked(ProcessRecord app) {
12879        for (BroadcastQueue queue : mBroadcastQueues) {
12880            queue.skipCurrentReceiverLocked(app);
12881        }
12882    }
12883
12884    /**
12885     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12886     * The application process will exit immediately after this call returns.
12887     * @param app object of the crashing app, null for the system server
12888     * @param crashInfo describing the exception
12889     */
12890    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12891        ProcessRecord r = findAppProcess(app, "Crash");
12892        final String processName = app == null ? "system_server"
12893                : (r == null ? "unknown" : r.processName);
12894
12895        handleApplicationCrashInner("crash", r, processName, crashInfo);
12896    }
12897
12898    /* Native crash reporting uses this inner version because it needs to be somewhat
12899     * decoupled from the AM-managed cleanup lifecycle
12900     */
12901    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12902            ApplicationErrorReport.CrashInfo crashInfo) {
12903        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12904                UserHandle.getUserId(Binder.getCallingUid()), processName,
12905                r == null ? -1 : r.info.flags,
12906                crashInfo.exceptionClassName,
12907                crashInfo.exceptionMessage,
12908                crashInfo.throwFileName,
12909                crashInfo.throwLineNumber);
12910
12911        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12912
12913        mAppErrors.crashApplication(r, crashInfo);
12914    }
12915
12916    public void handleApplicationStrictModeViolation(
12917            IBinder app,
12918            int violationMask,
12919            StrictMode.ViolationInfo info) {
12920        ProcessRecord r = findAppProcess(app, "StrictMode");
12921        if (r == null) {
12922            return;
12923        }
12924
12925        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12926            Integer stackFingerprint = info.hashCode();
12927            boolean logIt = true;
12928            synchronized (mAlreadyLoggedViolatedStacks) {
12929                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12930                    logIt = false;
12931                    // TODO: sub-sample into EventLog for these, with
12932                    // the info.durationMillis?  Then we'd get
12933                    // the relative pain numbers, without logging all
12934                    // the stack traces repeatedly.  We'd want to do
12935                    // likewise in the client code, which also does
12936                    // dup suppression, before the Binder call.
12937                } else {
12938                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12939                        mAlreadyLoggedViolatedStacks.clear();
12940                    }
12941                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12942                }
12943            }
12944            if (logIt) {
12945                logStrictModeViolationToDropBox(r, info);
12946            }
12947        }
12948
12949        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12950            AppErrorResult result = new AppErrorResult();
12951            synchronized (this) {
12952                final long origId = Binder.clearCallingIdentity();
12953
12954                Message msg = Message.obtain();
12955                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12956                HashMap<String, Object> data = new HashMap<String, Object>();
12957                data.put("result", result);
12958                data.put("app", r);
12959                data.put("violationMask", violationMask);
12960                data.put("info", info);
12961                msg.obj = data;
12962                mUiHandler.sendMessage(msg);
12963
12964                Binder.restoreCallingIdentity(origId);
12965            }
12966            int res = result.get();
12967            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12968        }
12969    }
12970
12971    // Depending on the policy in effect, there could be a bunch of
12972    // these in quick succession so we try to batch these together to
12973    // minimize disk writes, number of dropbox entries, and maximize
12974    // compression, by having more fewer, larger records.
12975    private void logStrictModeViolationToDropBox(
12976            ProcessRecord process,
12977            StrictMode.ViolationInfo info) {
12978        if (info == null) {
12979            return;
12980        }
12981        final boolean isSystemApp = process == null ||
12982                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12983                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12984        final String processName = process == null ? "unknown" : process.processName;
12985        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12986        final DropBoxManager dbox = (DropBoxManager)
12987                mContext.getSystemService(Context.DROPBOX_SERVICE);
12988
12989        // Exit early if the dropbox isn't configured to accept this report type.
12990        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12991
12992        boolean bufferWasEmpty;
12993        boolean needsFlush;
12994        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12995        synchronized (sb) {
12996            bufferWasEmpty = sb.length() == 0;
12997            appendDropBoxProcessHeaders(process, processName, sb);
12998            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12999            sb.append("System-App: ").append(isSystemApp).append("\n");
13000            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13001            if (info.violationNumThisLoop != 0) {
13002                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13003            }
13004            if (info.numAnimationsRunning != 0) {
13005                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13006            }
13007            if (info.broadcastIntentAction != null) {
13008                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13009            }
13010            if (info.durationMillis != -1) {
13011                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13012            }
13013            if (info.numInstances != -1) {
13014                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13015            }
13016            if (info.tags != null) {
13017                for (String tag : info.tags) {
13018                    sb.append("Span-Tag: ").append(tag).append("\n");
13019                }
13020            }
13021            sb.append("\n");
13022            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13023                sb.append(info.crashInfo.stackTrace);
13024                sb.append("\n");
13025            }
13026            if (info.message != null) {
13027                sb.append(info.message);
13028                sb.append("\n");
13029            }
13030
13031            // Only buffer up to ~64k.  Various logging bits truncate
13032            // things at 128k.
13033            needsFlush = (sb.length() > 64 * 1024);
13034        }
13035
13036        // Flush immediately if the buffer's grown too large, or this
13037        // is a non-system app.  Non-system apps are isolated with a
13038        // different tag & policy and not batched.
13039        //
13040        // Batching is useful during internal testing with
13041        // StrictMode settings turned up high.  Without batching,
13042        // thousands of separate files could be created on boot.
13043        if (!isSystemApp || needsFlush) {
13044            new Thread("Error dump: " + dropboxTag) {
13045                @Override
13046                public void run() {
13047                    String report;
13048                    synchronized (sb) {
13049                        report = sb.toString();
13050                        sb.delete(0, sb.length());
13051                        sb.trimToSize();
13052                    }
13053                    if (report.length() != 0) {
13054                        dbox.addText(dropboxTag, report);
13055                    }
13056                }
13057            }.start();
13058            return;
13059        }
13060
13061        // System app batching:
13062        if (!bufferWasEmpty) {
13063            // An existing dropbox-writing thread is outstanding, so
13064            // we don't need to start it up.  The existing thread will
13065            // catch the buffer appends we just did.
13066            return;
13067        }
13068
13069        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13070        // (After this point, we shouldn't access AMS internal data structures.)
13071        new Thread("Error dump: " + dropboxTag) {
13072            @Override
13073            public void run() {
13074                // 5 second sleep to let stacks arrive and be batched together
13075                try {
13076                    Thread.sleep(5000);  // 5 seconds
13077                } catch (InterruptedException e) {}
13078
13079                String errorReport;
13080                synchronized (mStrictModeBuffer) {
13081                    errorReport = mStrictModeBuffer.toString();
13082                    if (errorReport.length() == 0) {
13083                        return;
13084                    }
13085                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13086                    mStrictModeBuffer.trimToSize();
13087                }
13088                dbox.addText(dropboxTag, errorReport);
13089            }
13090        }.start();
13091    }
13092
13093    /**
13094     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13095     * @param app object of the crashing app, null for the system server
13096     * @param tag reported by the caller
13097     * @param system whether this wtf is coming from the system
13098     * @param crashInfo describing the context of the error
13099     * @return true if the process should exit immediately (WTF is fatal)
13100     */
13101    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13102            final ApplicationErrorReport.CrashInfo crashInfo) {
13103        final int callingUid = Binder.getCallingUid();
13104        final int callingPid = Binder.getCallingPid();
13105
13106        if (system) {
13107            // If this is coming from the system, we could very well have low-level
13108            // system locks held, so we want to do this all asynchronously.  And we
13109            // never want this to become fatal, so there is that too.
13110            mHandler.post(new Runnable() {
13111                @Override public void run() {
13112                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13113                }
13114            });
13115            return false;
13116        }
13117
13118        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13119                crashInfo);
13120
13121        if (r != null && r.pid != Process.myPid() &&
13122                Settings.Global.getInt(mContext.getContentResolver(),
13123                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13124            mAppErrors.crashApplication(r, crashInfo);
13125            return true;
13126        } else {
13127            return false;
13128        }
13129    }
13130
13131    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13132            final ApplicationErrorReport.CrashInfo crashInfo) {
13133        final ProcessRecord r = findAppProcess(app, "WTF");
13134        final String processName = app == null ? "system_server"
13135                : (r == null ? "unknown" : r.processName);
13136
13137        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13138                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13139
13140        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13141
13142        return r;
13143    }
13144
13145    /**
13146     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13147     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13148     */
13149    private ProcessRecord findAppProcess(IBinder app, String reason) {
13150        if (app == null) {
13151            return null;
13152        }
13153
13154        synchronized (this) {
13155            final int NP = mProcessNames.getMap().size();
13156            for (int ip=0; ip<NP; ip++) {
13157                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13158                final int NA = apps.size();
13159                for (int ia=0; ia<NA; ia++) {
13160                    ProcessRecord p = apps.valueAt(ia);
13161                    if (p.thread != null && p.thread.asBinder() == app) {
13162                        return p;
13163                    }
13164                }
13165            }
13166
13167            Slog.w(TAG, "Can't find mystery application for " + reason
13168                    + " from pid=" + Binder.getCallingPid()
13169                    + " uid=" + Binder.getCallingUid() + ": " + app);
13170            return null;
13171        }
13172    }
13173
13174    /**
13175     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13176     * to append various headers to the dropbox log text.
13177     */
13178    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13179            StringBuilder sb) {
13180        // Watchdog thread ends up invoking this function (with
13181        // a null ProcessRecord) to add the stack file to dropbox.
13182        // Do not acquire a lock on this (am) in such cases, as it
13183        // could cause a potential deadlock, if and when watchdog
13184        // is invoked due to unavailability of lock on am and it
13185        // would prevent watchdog from killing system_server.
13186        if (process == null) {
13187            sb.append("Process: ").append(processName).append("\n");
13188            return;
13189        }
13190        // Note: ProcessRecord 'process' is guarded by the service
13191        // instance.  (notably process.pkgList, which could otherwise change
13192        // concurrently during execution of this method)
13193        synchronized (this) {
13194            sb.append("Process: ").append(processName).append("\n");
13195            int flags = process.info.flags;
13196            IPackageManager pm = AppGlobals.getPackageManager();
13197            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13198            for (int ip=0; ip<process.pkgList.size(); ip++) {
13199                String pkg = process.pkgList.keyAt(ip);
13200                sb.append("Package: ").append(pkg);
13201                try {
13202                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13203                    if (pi != null) {
13204                        sb.append(" v").append(pi.versionCode);
13205                        if (pi.versionName != null) {
13206                            sb.append(" (").append(pi.versionName).append(")");
13207                        }
13208                    }
13209                } catch (RemoteException e) {
13210                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13211                }
13212                sb.append("\n");
13213            }
13214        }
13215    }
13216
13217    private static String processClass(ProcessRecord process) {
13218        if (process == null || process.pid == MY_PID) {
13219            return "system_server";
13220        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13221            return "system_app";
13222        } else {
13223            return "data_app";
13224        }
13225    }
13226
13227    private volatile long mWtfClusterStart;
13228    private volatile int mWtfClusterCount;
13229
13230    /**
13231     * Write a description of an error (crash, WTF, ANR) to the drop box.
13232     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13233     * @param process which caused the error, null means the system server
13234     * @param activity which triggered the error, null if unknown
13235     * @param parent activity related to the error, null if unknown
13236     * @param subject line related to the error, null if absent
13237     * @param report in long form describing the error, null if absent
13238     * @param logFile to include in the report, null if none
13239     * @param crashInfo giving an application stack trace, null if absent
13240     */
13241    public void addErrorToDropBox(String eventType,
13242            ProcessRecord process, String processName, ActivityRecord activity,
13243            ActivityRecord parent, String subject,
13244            final String report, final File logFile,
13245            final ApplicationErrorReport.CrashInfo crashInfo) {
13246        // NOTE -- this must never acquire the ActivityManagerService lock,
13247        // otherwise the watchdog may be prevented from resetting the system.
13248
13249        final String dropboxTag = processClass(process) + "_" + eventType;
13250        final DropBoxManager dbox = (DropBoxManager)
13251                mContext.getSystemService(Context.DROPBOX_SERVICE);
13252
13253        // Exit early if the dropbox isn't configured to accept this report type.
13254        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13255
13256        // Rate-limit how often we're willing to do the heavy lifting below to
13257        // collect and record logs; currently 5 logs per 10 second period.
13258        final long now = SystemClock.elapsedRealtime();
13259        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13260            mWtfClusterStart = now;
13261            mWtfClusterCount = 1;
13262        } else {
13263            if (mWtfClusterCount++ >= 5) return;
13264        }
13265
13266        final StringBuilder sb = new StringBuilder(1024);
13267        appendDropBoxProcessHeaders(process, processName, sb);
13268        if (process != null) {
13269            sb.append("Foreground: ")
13270                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13271                    .append("\n");
13272        }
13273        if (activity != null) {
13274            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13275        }
13276        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13277            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13278        }
13279        if (parent != null && parent != activity) {
13280            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13281        }
13282        if (subject != null) {
13283            sb.append("Subject: ").append(subject).append("\n");
13284        }
13285        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13286        if (Debug.isDebuggerConnected()) {
13287            sb.append("Debugger: Connected\n");
13288        }
13289        sb.append("\n");
13290
13291        // Do the rest in a worker thread to avoid blocking the caller on I/O
13292        // (After this point, we shouldn't access AMS internal data structures.)
13293        Thread worker = new Thread("Error dump: " + dropboxTag) {
13294            @Override
13295            public void run() {
13296                if (report != null) {
13297                    sb.append(report);
13298                }
13299                if (logFile != null) {
13300                    try {
13301                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13302                                    "\n\n[[TRUNCATED]]"));
13303                    } catch (IOException e) {
13304                        Slog.e(TAG, "Error reading " + logFile, e);
13305                    }
13306                }
13307                if (crashInfo != null && crashInfo.stackTrace != null) {
13308                    sb.append(crashInfo.stackTrace);
13309                }
13310
13311                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13312                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13313                if (lines > 0) {
13314                    sb.append("\n");
13315
13316                    // Merge several logcat streams, and take the last N lines
13317                    InputStreamReader input = null;
13318                    try {
13319                        java.lang.Process logcat = new ProcessBuilder(
13320                                "/system/bin/timeout", "-k", "15s", "10s",
13321                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13322                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13323                                        .redirectErrorStream(true).start();
13324
13325                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13326                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13327                        input = new InputStreamReader(logcat.getInputStream());
13328
13329                        int num;
13330                        char[] buf = new char[8192];
13331                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13332                    } catch (IOException e) {
13333                        Slog.e(TAG, "Error running logcat", e);
13334                    } finally {
13335                        if (input != null) try { input.close(); } catch (IOException e) {}
13336                    }
13337                }
13338
13339                dbox.addText(dropboxTag, sb.toString());
13340            }
13341        };
13342
13343        if (process == null) {
13344            // If process is null, we are being called from some internal code
13345            // and may be about to die -- run this synchronously.
13346            worker.run();
13347        } else {
13348            worker.start();
13349        }
13350    }
13351
13352    @Override
13353    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13354        enforceNotIsolatedCaller("getProcessesInErrorState");
13355        // assume our apps are happy - lazy create the list
13356        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13357
13358        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13359                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13360        int userId = UserHandle.getUserId(Binder.getCallingUid());
13361
13362        synchronized (this) {
13363
13364            // iterate across all processes
13365            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13366                ProcessRecord app = mLruProcesses.get(i);
13367                if (!allUsers && app.userId != userId) {
13368                    continue;
13369                }
13370                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13371                    // This one's in trouble, so we'll generate a report for it
13372                    // crashes are higher priority (in case there's a crash *and* an anr)
13373                    ActivityManager.ProcessErrorStateInfo report = null;
13374                    if (app.crashing) {
13375                        report = app.crashingReport;
13376                    } else if (app.notResponding) {
13377                        report = app.notRespondingReport;
13378                    }
13379
13380                    if (report != null) {
13381                        if (errList == null) {
13382                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13383                        }
13384                        errList.add(report);
13385                    } else {
13386                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13387                                " crashing = " + app.crashing +
13388                                " notResponding = " + app.notResponding);
13389                    }
13390                }
13391            }
13392        }
13393
13394        return errList;
13395    }
13396
13397    static int procStateToImportance(int procState, int memAdj,
13398            ActivityManager.RunningAppProcessInfo currApp) {
13399        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13400        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13401            currApp.lru = memAdj;
13402        } else {
13403            currApp.lru = 0;
13404        }
13405        return imp;
13406    }
13407
13408    private void fillInProcMemInfo(ProcessRecord app,
13409            ActivityManager.RunningAppProcessInfo outInfo) {
13410        outInfo.pid = app.pid;
13411        outInfo.uid = app.info.uid;
13412        if (mHeavyWeightProcess == app) {
13413            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13414        }
13415        if (app.persistent) {
13416            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13417        }
13418        if (app.activities.size() > 0) {
13419            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13420        }
13421        outInfo.lastTrimLevel = app.trimMemoryLevel;
13422        int adj = app.curAdj;
13423        int procState = app.curProcState;
13424        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13425        outInfo.importanceReasonCode = app.adjTypeCode;
13426        outInfo.processState = app.curProcState;
13427    }
13428
13429    @Override
13430    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13431        enforceNotIsolatedCaller("getRunningAppProcesses");
13432
13433        final int callingUid = Binder.getCallingUid();
13434
13435        // Lazy instantiation of list
13436        List<ActivityManager.RunningAppProcessInfo> runList = null;
13437        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13438                callingUid) == PackageManager.PERMISSION_GRANTED;
13439        final int userId = UserHandle.getUserId(callingUid);
13440        final boolean allUids = isGetTasksAllowed(
13441                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13442
13443        synchronized (this) {
13444            // Iterate across all processes
13445            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13446                ProcessRecord app = mLruProcesses.get(i);
13447                if ((!allUsers && app.userId != userId)
13448                        || (!allUids && app.uid != callingUid)) {
13449                    continue;
13450                }
13451                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13452                    // Generate process state info for running application
13453                    ActivityManager.RunningAppProcessInfo currApp =
13454                        new ActivityManager.RunningAppProcessInfo(app.processName,
13455                                app.pid, app.getPackageList());
13456                    fillInProcMemInfo(app, currApp);
13457                    if (app.adjSource instanceof ProcessRecord) {
13458                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13459                        currApp.importanceReasonImportance =
13460                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13461                                        app.adjSourceProcState);
13462                    } else if (app.adjSource instanceof ActivityRecord) {
13463                        ActivityRecord r = (ActivityRecord)app.adjSource;
13464                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13465                    }
13466                    if (app.adjTarget instanceof ComponentName) {
13467                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13468                    }
13469                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13470                    //        + " lru=" + currApp.lru);
13471                    if (runList == null) {
13472                        runList = new ArrayList<>();
13473                    }
13474                    runList.add(currApp);
13475                }
13476            }
13477        }
13478        return runList;
13479    }
13480
13481    @Override
13482    public List<ApplicationInfo> getRunningExternalApplications() {
13483        enforceNotIsolatedCaller("getRunningExternalApplications");
13484        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13485        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13486        if (runningApps != null && runningApps.size() > 0) {
13487            Set<String> extList = new HashSet<String>();
13488            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13489                if (app.pkgList != null) {
13490                    for (String pkg : app.pkgList) {
13491                        extList.add(pkg);
13492                    }
13493                }
13494            }
13495            IPackageManager pm = AppGlobals.getPackageManager();
13496            for (String pkg : extList) {
13497                try {
13498                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13499                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13500                        retList.add(info);
13501                    }
13502                } catch (RemoteException e) {
13503                }
13504            }
13505        }
13506        return retList;
13507    }
13508
13509    @Override
13510    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13511        enforceNotIsolatedCaller("getMyMemoryState");
13512        synchronized (this) {
13513            ProcessRecord proc;
13514            synchronized (mPidsSelfLocked) {
13515                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13516            }
13517            fillInProcMemInfo(proc, outInfo);
13518        }
13519    }
13520
13521    @Override
13522    public int getMemoryTrimLevel() {
13523        enforceNotIsolatedCaller("getMyMemoryState");
13524        synchronized (this) {
13525            return mLastMemoryLevel;
13526        }
13527    }
13528
13529    @Override
13530    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13531            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13532        (new ActivityManagerShellCommand(this, false)).exec(
13533                this, in, out, err, args, resultReceiver);
13534    }
13535
13536    @Override
13537    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13538        if (checkCallingPermission(android.Manifest.permission.DUMP)
13539                != PackageManager.PERMISSION_GRANTED) {
13540            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13541                    + Binder.getCallingPid()
13542                    + ", uid=" + Binder.getCallingUid()
13543                    + " without permission "
13544                    + android.Manifest.permission.DUMP);
13545            return;
13546        }
13547
13548        boolean dumpAll = false;
13549        boolean dumpClient = false;
13550        String dumpPackage = null;
13551
13552        int opti = 0;
13553        while (opti < args.length) {
13554            String opt = args[opti];
13555            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13556                break;
13557            }
13558            opti++;
13559            if ("-a".equals(opt)) {
13560                dumpAll = true;
13561            } else if ("-c".equals(opt)) {
13562                dumpClient = true;
13563            } else if ("-p".equals(opt)) {
13564                if (opti < args.length) {
13565                    dumpPackage = args[opti];
13566                    opti++;
13567                } else {
13568                    pw.println("Error: -p option requires package argument");
13569                    return;
13570                }
13571                dumpClient = true;
13572            } else if ("-h".equals(opt)) {
13573                ActivityManagerShellCommand.dumpHelp(pw, true);
13574                return;
13575            } else {
13576                pw.println("Unknown argument: " + opt + "; use -h for help");
13577            }
13578        }
13579
13580        long origId = Binder.clearCallingIdentity();
13581        boolean more = false;
13582        // Is the caller requesting to dump a particular piece of data?
13583        if (opti < args.length) {
13584            String cmd = args[opti];
13585            opti++;
13586            if ("activities".equals(cmd) || "a".equals(cmd)) {
13587                synchronized (this) {
13588                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13589                }
13590            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13591                synchronized (this) {
13592                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13593                }
13594            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13595                String[] newArgs;
13596                String name;
13597                if (opti >= args.length) {
13598                    name = null;
13599                    newArgs = EMPTY_STRING_ARRAY;
13600                } else {
13601                    dumpPackage = args[opti];
13602                    opti++;
13603                    newArgs = new String[args.length - opti];
13604                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13605                            args.length - opti);
13606                }
13607                synchronized (this) {
13608                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13609                }
13610            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13611                String[] newArgs;
13612                String name;
13613                if (opti >= args.length) {
13614                    name = null;
13615                    newArgs = EMPTY_STRING_ARRAY;
13616                } else {
13617                    dumpPackage = args[opti];
13618                    opti++;
13619                    newArgs = new String[args.length - opti];
13620                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13621                            args.length - opti);
13622                }
13623                synchronized (this) {
13624                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13625                }
13626            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13627                String[] newArgs;
13628                String name;
13629                if (opti >= args.length) {
13630                    name = null;
13631                    newArgs = EMPTY_STRING_ARRAY;
13632                } else {
13633                    dumpPackage = args[opti];
13634                    opti++;
13635                    newArgs = new String[args.length - opti];
13636                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13637                            args.length - opti);
13638                }
13639                synchronized (this) {
13640                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13641                }
13642            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13643                synchronized (this) {
13644                    dumpOomLocked(fd, pw, args, opti, true);
13645                }
13646            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13647                synchronized (this) {
13648                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13649                }
13650            } else if ("provider".equals(cmd)) {
13651                String[] newArgs;
13652                String name;
13653                if (opti >= args.length) {
13654                    name = null;
13655                    newArgs = EMPTY_STRING_ARRAY;
13656                } else {
13657                    name = args[opti];
13658                    opti++;
13659                    newArgs = new String[args.length - opti];
13660                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13661                }
13662                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13663                    pw.println("No providers match: " + name);
13664                    pw.println("Use -h for help.");
13665                }
13666            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13667                synchronized (this) {
13668                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13669                }
13670            } else if ("service".equals(cmd)) {
13671                String[] newArgs;
13672                String name;
13673                if (opti >= args.length) {
13674                    name = null;
13675                    newArgs = EMPTY_STRING_ARRAY;
13676                } else {
13677                    name = args[opti];
13678                    opti++;
13679                    newArgs = new String[args.length - opti];
13680                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13681                            args.length - opti);
13682                }
13683                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13684                    pw.println("No services match: " + name);
13685                    pw.println("Use -h for help.");
13686                }
13687            } else if ("package".equals(cmd)) {
13688                String[] newArgs;
13689                if (opti >= args.length) {
13690                    pw.println("package: no package name specified");
13691                    pw.println("Use -h for help.");
13692                } else {
13693                    dumpPackage = args[opti];
13694                    opti++;
13695                    newArgs = new String[args.length - opti];
13696                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13697                            args.length - opti);
13698                    args = newArgs;
13699                    opti = 0;
13700                    more = true;
13701                }
13702            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13703                synchronized (this) {
13704                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13705                }
13706            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13707                synchronized (this) {
13708                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13709                }
13710            } else if ("locks".equals(cmd)) {
13711                LockGuard.dump(fd, pw, args);
13712            } else {
13713                // Dumping a single activity?
13714                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13715                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13716                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13717                    if (res < 0) {
13718                        pw.println("Bad activity command, or no activities match: " + cmd);
13719                        pw.println("Use -h for help.");
13720                    }
13721                }
13722            }
13723            if (!more) {
13724                Binder.restoreCallingIdentity(origId);
13725                return;
13726            }
13727        }
13728
13729        // No piece of data specified, dump everything.
13730        synchronized (this) {
13731            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13732            pw.println();
13733            if (dumpAll) {
13734                pw.println("-------------------------------------------------------------------------------");
13735            }
13736            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13737            pw.println();
13738            if (dumpAll) {
13739                pw.println("-------------------------------------------------------------------------------");
13740            }
13741            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13742            pw.println();
13743            if (dumpAll) {
13744                pw.println("-------------------------------------------------------------------------------");
13745            }
13746            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13747            pw.println();
13748            if (dumpAll) {
13749                pw.println("-------------------------------------------------------------------------------");
13750            }
13751            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13752            pw.println();
13753            if (dumpAll) {
13754                pw.println("-------------------------------------------------------------------------------");
13755            }
13756            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13757            pw.println();
13758            if (dumpAll) {
13759                pw.println("-------------------------------------------------------------------------------");
13760            }
13761            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13762            if (mAssociations.size() > 0) {
13763                pw.println();
13764                if (dumpAll) {
13765                    pw.println("-------------------------------------------------------------------------------");
13766                }
13767                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13768            }
13769            pw.println();
13770            if (dumpAll) {
13771                pw.println("-------------------------------------------------------------------------------");
13772            }
13773            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13774        }
13775        Binder.restoreCallingIdentity(origId);
13776    }
13777
13778    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13779            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13780        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13781
13782        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13783                dumpPackage);
13784        boolean needSep = printedAnything;
13785
13786        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13787                dumpPackage, needSep, "  mFocusedActivity: ");
13788        if (printed) {
13789            printedAnything = true;
13790            needSep = false;
13791        }
13792
13793        if (dumpPackage == null) {
13794            if (needSep) {
13795                pw.println();
13796            }
13797            needSep = true;
13798            printedAnything = true;
13799            mStackSupervisor.dump(pw, "  ");
13800        }
13801
13802        if (!printedAnything) {
13803            pw.println("  (nothing)");
13804        }
13805    }
13806
13807    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13808            int opti, boolean dumpAll, String dumpPackage) {
13809        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13810
13811        boolean printedAnything = false;
13812
13813        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13814            boolean printedHeader = false;
13815
13816            final int N = mRecentTasks.size();
13817            for (int i=0; i<N; i++) {
13818                TaskRecord tr = mRecentTasks.get(i);
13819                if (dumpPackage != null) {
13820                    if (tr.realActivity == null ||
13821                            !dumpPackage.equals(tr.realActivity)) {
13822                        continue;
13823                    }
13824                }
13825                if (!printedHeader) {
13826                    pw.println("  Recent tasks:");
13827                    printedHeader = true;
13828                    printedAnything = true;
13829                }
13830                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13831                        pw.println(tr);
13832                if (dumpAll) {
13833                    mRecentTasks.get(i).dump(pw, "    ");
13834                }
13835            }
13836        }
13837
13838        if (!printedAnything) {
13839            pw.println("  (nothing)");
13840        }
13841    }
13842
13843    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13844            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13845        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13846
13847        int dumpUid = 0;
13848        if (dumpPackage != null) {
13849            IPackageManager pm = AppGlobals.getPackageManager();
13850            try {
13851                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13852            } catch (RemoteException e) {
13853            }
13854        }
13855
13856        boolean printedAnything = false;
13857
13858        final long now = SystemClock.uptimeMillis();
13859
13860        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13861            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13862                    = mAssociations.valueAt(i1);
13863            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13864                SparseArray<ArrayMap<String, Association>> sourceUids
13865                        = targetComponents.valueAt(i2);
13866                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13867                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13868                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13869                        Association ass = sourceProcesses.valueAt(i4);
13870                        if (dumpPackage != null) {
13871                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13872                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13873                                continue;
13874                            }
13875                        }
13876                        printedAnything = true;
13877                        pw.print("  ");
13878                        pw.print(ass.mTargetProcess);
13879                        pw.print("/");
13880                        UserHandle.formatUid(pw, ass.mTargetUid);
13881                        pw.print(" <- ");
13882                        pw.print(ass.mSourceProcess);
13883                        pw.print("/");
13884                        UserHandle.formatUid(pw, ass.mSourceUid);
13885                        pw.println();
13886                        pw.print("    via ");
13887                        pw.print(ass.mTargetComponent.flattenToShortString());
13888                        pw.println();
13889                        pw.print("    ");
13890                        long dur = ass.mTime;
13891                        if (ass.mNesting > 0) {
13892                            dur += now - ass.mStartTime;
13893                        }
13894                        TimeUtils.formatDuration(dur, pw);
13895                        pw.print(" (");
13896                        pw.print(ass.mCount);
13897                        pw.print(" times)");
13898                        pw.print("  ");
13899                        for (int i=0; i<ass.mStateTimes.length; i++) {
13900                            long amt = ass.mStateTimes[i];
13901                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13902                                amt += now - ass.mLastStateUptime;
13903                            }
13904                            if (amt != 0) {
13905                                pw.print(" ");
13906                                pw.print(ProcessList.makeProcStateString(
13907                                            i + ActivityManager.MIN_PROCESS_STATE));
13908                                pw.print("=");
13909                                TimeUtils.formatDuration(amt, pw);
13910                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13911                                    pw.print("*");
13912                                }
13913                            }
13914                        }
13915                        pw.println();
13916                        if (ass.mNesting > 0) {
13917                            pw.print("    Currently active: ");
13918                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13919                            pw.println();
13920                        }
13921                    }
13922                }
13923            }
13924
13925        }
13926
13927        if (!printedAnything) {
13928            pw.println("  (nothing)");
13929        }
13930    }
13931
13932    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13933            String header, boolean needSep) {
13934        boolean printed = false;
13935        int whichAppId = -1;
13936        if (dumpPackage != null) {
13937            try {
13938                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13939                        dumpPackage, 0);
13940                whichAppId = UserHandle.getAppId(info.uid);
13941            } catch (NameNotFoundException e) {
13942                e.printStackTrace();
13943            }
13944        }
13945        for (int i=0; i<uids.size(); i++) {
13946            UidRecord uidRec = uids.valueAt(i);
13947            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13948                continue;
13949            }
13950            if (!printed) {
13951                printed = true;
13952                if (needSep) {
13953                    pw.println();
13954                }
13955                pw.print("  ");
13956                pw.println(header);
13957                needSep = true;
13958            }
13959            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13960            pw.print(": "); pw.println(uidRec);
13961        }
13962        return printed;
13963    }
13964
13965    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13966            int opti, boolean dumpAll, String dumpPackage) {
13967        boolean needSep = false;
13968        boolean printedAnything = false;
13969        int numPers = 0;
13970
13971        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13972
13973        if (dumpAll) {
13974            final int NP = mProcessNames.getMap().size();
13975            for (int ip=0; ip<NP; ip++) {
13976                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13977                final int NA = procs.size();
13978                for (int ia=0; ia<NA; ia++) {
13979                    ProcessRecord r = procs.valueAt(ia);
13980                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13981                        continue;
13982                    }
13983                    if (!needSep) {
13984                        pw.println("  All known processes:");
13985                        needSep = true;
13986                        printedAnything = true;
13987                    }
13988                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13989                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13990                        pw.print(" "); pw.println(r);
13991                    r.dump(pw, "    ");
13992                    if (r.persistent) {
13993                        numPers++;
13994                    }
13995                }
13996            }
13997        }
13998
13999        if (mIsolatedProcesses.size() > 0) {
14000            boolean printed = false;
14001            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14002                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14003                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14004                    continue;
14005                }
14006                if (!printed) {
14007                    if (needSep) {
14008                        pw.println();
14009                    }
14010                    pw.println("  Isolated process list (sorted by uid):");
14011                    printedAnything = true;
14012                    printed = true;
14013                    needSep = true;
14014                }
14015                pw.println(String.format("%sIsolated #%2d: %s",
14016                        "    ", i, r.toString()));
14017            }
14018        }
14019
14020        if (mActiveUids.size() > 0) {
14021            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14022                printedAnything = needSep = true;
14023            }
14024        }
14025        if (mValidateUids.size() > 0) {
14026            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14027                printedAnything = needSep = true;
14028            }
14029        }
14030
14031        if (mLruProcesses.size() > 0) {
14032            if (needSep) {
14033                pw.println();
14034            }
14035            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14036                    pw.print(" total, non-act at ");
14037                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14038                    pw.print(", non-svc at ");
14039                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14040                    pw.println("):");
14041            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14042            needSep = true;
14043            printedAnything = true;
14044        }
14045
14046        if (dumpAll || dumpPackage != null) {
14047            synchronized (mPidsSelfLocked) {
14048                boolean printed = false;
14049                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14050                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14051                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14052                        continue;
14053                    }
14054                    if (!printed) {
14055                        if (needSep) pw.println();
14056                        needSep = true;
14057                        pw.println("  PID mappings:");
14058                        printed = true;
14059                        printedAnything = true;
14060                    }
14061                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14062                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14063                }
14064            }
14065        }
14066
14067        if (mForegroundProcesses.size() > 0) {
14068            synchronized (mPidsSelfLocked) {
14069                boolean printed = false;
14070                for (int i=0; i<mForegroundProcesses.size(); i++) {
14071                    ProcessRecord r = mPidsSelfLocked.get(
14072                            mForegroundProcesses.valueAt(i).pid);
14073                    if (dumpPackage != null && (r == null
14074                            || !r.pkgList.containsKey(dumpPackage))) {
14075                        continue;
14076                    }
14077                    if (!printed) {
14078                        if (needSep) pw.println();
14079                        needSep = true;
14080                        pw.println("  Foreground Processes:");
14081                        printed = true;
14082                        printedAnything = true;
14083                    }
14084                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14085                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14086                }
14087            }
14088        }
14089
14090        if (mPersistentStartingProcesses.size() > 0) {
14091            if (needSep) pw.println();
14092            needSep = true;
14093            printedAnything = true;
14094            pw.println("  Persisent processes that are starting:");
14095            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14096                    "Starting Norm", "Restarting PERS", dumpPackage);
14097        }
14098
14099        if (mRemovedProcesses.size() > 0) {
14100            if (needSep) pw.println();
14101            needSep = true;
14102            printedAnything = true;
14103            pw.println("  Processes that are being removed:");
14104            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14105                    "Removed Norm", "Removed PERS", dumpPackage);
14106        }
14107
14108        if (mProcessesOnHold.size() > 0) {
14109            if (needSep) pw.println();
14110            needSep = true;
14111            printedAnything = true;
14112            pw.println("  Processes that are on old until the system is ready:");
14113            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14114                    "OnHold Norm", "OnHold PERS", dumpPackage);
14115        }
14116
14117        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14118
14119        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14120        if (needSep) {
14121            printedAnything = true;
14122        }
14123
14124        if (dumpPackage == null) {
14125            pw.println();
14126            needSep = false;
14127            mUserController.dump(pw, dumpAll);
14128        }
14129        if (mHomeProcess != null && (dumpPackage == null
14130                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14131            if (needSep) {
14132                pw.println();
14133                needSep = false;
14134            }
14135            pw.println("  mHomeProcess: " + mHomeProcess);
14136        }
14137        if (mPreviousProcess != null && (dumpPackage == null
14138                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14139            if (needSep) {
14140                pw.println();
14141                needSep = false;
14142            }
14143            pw.println("  mPreviousProcess: " + mPreviousProcess);
14144        }
14145        if (dumpAll) {
14146            StringBuilder sb = new StringBuilder(128);
14147            sb.append("  mPreviousProcessVisibleTime: ");
14148            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14149            pw.println(sb);
14150        }
14151        if (mHeavyWeightProcess != null && (dumpPackage == null
14152                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14153            if (needSep) {
14154                pw.println();
14155                needSep = false;
14156            }
14157            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14158        }
14159        if (dumpPackage == null) {
14160            pw.println("  mConfiguration: " + mConfiguration);
14161        }
14162        if (dumpAll) {
14163            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14164            if (mCompatModePackages.getPackages().size() > 0) {
14165                boolean printed = false;
14166                for (Map.Entry<String, Integer> entry
14167                        : mCompatModePackages.getPackages().entrySet()) {
14168                    String pkg = entry.getKey();
14169                    int mode = entry.getValue();
14170                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14171                        continue;
14172                    }
14173                    if (!printed) {
14174                        pw.println("  mScreenCompatPackages:");
14175                        printed = true;
14176                    }
14177                    pw.print("    "); pw.print(pkg); pw.print(": ");
14178                            pw.print(mode); pw.println();
14179                }
14180            }
14181        }
14182        if (dumpPackage == null) {
14183            pw.println("  mWakefulness="
14184                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14185            pw.println("  mSleepTokens=" + mSleepTokens);
14186            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14187                    + lockScreenShownToString());
14188            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14189            if (mRunningVoice != null) {
14190                pw.println("  mRunningVoice=" + mRunningVoice);
14191                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14192            }
14193        }
14194        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14195                || mOrigWaitForDebugger) {
14196            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14197                    || dumpPackage.equals(mOrigDebugApp)) {
14198                if (needSep) {
14199                    pw.println();
14200                    needSep = false;
14201                }
14202                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14203                        + " mDebugTransient=" + mDebugTransient
14204                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14205            }
14206        }
14207        if (mCurAppTimeTracker != null) {
14208            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14209        }
14210        if (mMemWatchProcesses.getMap().size() > 0) {
14211            pw.println("  Mem watch processes:");
14212            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14213                    = mMemWatchProcesses.getMap();
14214            for (int i=0; i<procs.size(); i++) {
14215                final String proc = procs.keyAt(i);
14216                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14217                for (int j=0; j<uids.size(); j++) {
14218                    if (needSep) {
14219                        pw.println();
14220                        needSep = false;
14221                    }
14222                    StringBuilder sb = new StringBuilder();
14223                    sb.append("    ").append(proc).append('/');
14224                    UserHandle.formatUid(sb, uids.keyAt(j));
14225                    Pair<Long, String> val = uids.valueAt(j);
14226                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14227                    if (val.second != null) {
14228                        sb.append(", report to ").append(val.second);
14229                    }
14230                    pw.println(sb.toString());
14231                }
14232            }
14233            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14234            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14235            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14236                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14237        }
14238        if (mTrackAllocationApp != null) {
14239            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14240                if (needSep) {
14241                    pw.println();
14242                    needSep = false;
14243                }
14244                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14245            }
14246        }
14247        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14248                || mProfileFd != null) {
14249            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14250                if (needSep) {
14251                    pw.println();
14252                    needSep = false;
14253                }
14254                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14255                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14256                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14257                        + mAutoStopProfiler);
14258                pw.println("  mProfileType=" + mProfileType);
14259            }
14260        }
14261        if (mNativeDebuggingApp != null) {
14262            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14263                if (needSep) {
14264                    pw.println();
14265                    needSep = false;
14266                }
14267                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14268            }
14269        }
14270        if (dumpPackage == null) {
14271            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14272                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14273                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14274            }
14275            if (mController != null) {
14276                pw.println("  mController=" + mController
14277                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14278            }
14279            if (dumpAll) {
14280                pw.println("  Total persistent processes: " + numPers);
14281                pw.println("  mProcessesReady=" + mProcessesReady
14282                        + " mSystemReady=" + mSystemReady
14283                        + " mBooted=" + mBooted
14284                        + " mFactoryTest=" + mFactoryTest);
14285                pw.println("  mBooting=" + mBooting
14286                        + " mCallFinishBooting=" + mCallFinishBooting
14287                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14288                pw.print("  mLastPowerCheckRealtime=");
14289                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14290                        pw.println("");
14291                pw.print("  mLastPowerCheckUptime=");
14292                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14293                        pw.println("");
14294                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14295                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14296                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14297                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14298                        + " (" + mLruProcesses.size() + " total)"
14299                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14300                        + " mNumServiceProcs=" + mNumServiceProcs
14301                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14302                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14303                        + " mLastMemoryLevel=" + mLastMemoryLevel
14304                        + " mLastNumProcesses=" + mLastNumProcesses);
14305                long now = SystemClock.uptimeMillis();
14306                pw.print("  mLastIdleTime=");
14307                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14308                        pw.print(" mLowRamSinceLastIdle=");
14309                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14310                        pw.println();
14311            }
14312        }
14313
14314        if (!printedAnything) {
14315            pw.println("  (nothing)");
14316        }
14317    }
14318
14319    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14320            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14321        if (mProcessesToGc.size() > 0) {
14322            boolean printed = false;
14323            long now = SystemClock.uptimeMillis();
14324            for (int i=0; i<mProcessesToGc.size(); i++) {
14325                ProcessRecord proc = mProcessesToGc.get(i);
14326                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14327                    continue;
14328                }
14329                if (!printed) {
14330                    if (needSep) pw.println();
14331                    needSep = true;
14332                    pw.println("  Processes that are waiting to GC:");
14333                    printed = true;
14334                }
14335                pw.print("    Process "); pw.println(proc);
14336                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14337                        pw.print(", last gced=");
14338                        pw.print(now-proc.lastRequestedGc);
14339                        pw.print(" ms ago, last lowMem=");
14340                        pw.print(now-proc.lastLowMemory);
14341                        pw.println(" ms ago");
14342
14343            }
14344        }
14345        return needSep;
14346    }
14347
14348    void printOomLevel(PrintWriter pw, String name, int adj) {
14349        pw.print("    ");
14350        if (adj >= 0) {
14351            pw.print(' ');
14352            if (adj < 10) pw.print(' ');
14353        } else {
14354            if (adj > -10) pw.print(' ');
14355        }
14356        pw.print(adj);
14357        pw.print(": ");
14358        pw.print(name);
14359        pw.print(" (");
14360        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14361        pw.println(")");
14362    }
14363
14364    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14365            int opti, boolean dumpAll) {
14366        boolean needSep = false;
14367
14368        if (mLruProcesses.size() > 0) {
14369            if (needSep) pw.println();
14370            needSep = true;
14371            pw.println("  OOM levels:");
14372            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14373            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14374            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14375            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14376            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14377            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14378            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14379            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14380            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14381            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14382            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14383            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14384            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14385            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14386
14387            if (needSep) pw.println();
14388            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14389                    pw.print(" total, non-act at ");
14390                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14391                    pw.print(", non-svc at ");
14392                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14393                    pw.println("):");
14394            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14395            needSep = true;
14396        }
14397
14398        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14399
14400        pw.println();
14401        pw.println("  mHomeProcess: " + mHomeProcess);
14402        pw.println("  mPreviousProcess: " + mPreviousProcess);
14403        if (mHeavyWeightProcess != null) {
14404            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14405        }
14406
14407        return true;
14408    }
14409
14410    /**
14411     * There are three ways to call this:
14412     *  - no provider specified: dump all the providers
14413     *  - a flattened component name that matched an existing provider was specified as the
14414     *    first arg: dump that one provider
14415     *  - the first arg isn't the flattened component name of an existing provider:
14416     *    dump all providers whose component contains the first arg as a substring
14417     */
14418    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14419            int opti, boolean dumpAll) {
14420        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14421    }
14422
14423    static class ItemMatcher {
14424        ArrayList<ComponentName> components;
14425        ArrayList<String> strings;
14426        ArrayList<Integer> objects;
14427        boolean all;
14428
14429        ItemMatcher() {
14430            all = true;
14431        }
14432
14433        void build(String name) {
14434            ComponentName componentName = ComponentName.unflattenFromString(name);
14435            if (componentName != null) {
14436                if (components == null) {
14437                    components = new ArrayList<ComponentName>();
14438                }
14439                components.add(componentName);
14440                all = false;
14441            } else {
14442                int objectId = 0;
14443                // Not a '/' separated full component name; maybe an object ID?
14444                try {
14445                    objectId = Integer.parseInt(name, 16);
14446                    if (objects == null) {
14447                        objects = new ArrayList<Integer>();
14448                    }
14449                    objects.add(objectId);
14450                    all = false;
14451                } catch (RuntimeException e) {
14452                    // Not an integer; just do string match.
14453                    if (strings == null) {
14454                        strings = new ArrayList<String>();
14455                    }
14456                    strings.add(name);
14457                    all = false;
14458                }
14459            }
14460        }
14461
14462        int build(String[] args, int opti) {
14463            for (; opti<args.length; opti++) {
14464                String name = args[opti];
14465                if ("--".equals(name)) {
14466                    return opti+1;
14467                }
14468                build(name);
14469            }
14470            return opti;
14471        }
14472
14473        boolean match(Object object, ComponentName comp) {
14474            if (all) {
14475                return true;
14476            }
14477            if (components != null) {
14478                for (int i=0; i<components.size(); i++) {
14479                    if (components.get(i).equals(comp)) {
14480                        return true;
14481                    }
14482                }
14483            }
14484            if (objects != null) {
14485                for (int i=0; i<objects.size(); i++) {
14486                    if (System.identityHashCode(object) == objects.get(i)) {
14487                        return true;
14488                    }
14489                }
14490            }
14491            if (strings != null) {
14492                String flat = comp.flattenToString();
14493                for (int i=0; i<strings.size(); i++) {
14494                    if (flat.contains(strings.get(i))) {
14495                        return true;
14496                    }
14497                }
14498            }
14499            return false;
14500        }
14501    }
14502
14503    /**
14504     * There are three things that cmd can be:
14505     *  - a flattened component name that matches an existing activity
14506     *  - the cmd arg isn't the flattened component name of an existing activity:
14507     *    dump all activity whose component contains the cmd as a substring
14508     *  - A hex number of the ActivityRecord object instance.
14509     */
14510    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14511            int opti, boolean dumpAll) {
14512        ArrayList<ActivityRecord> activities;
14513
14514        synchronized (this) {
14515            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14516        }
14517
14518        if (activities.size() <= 0) {
14519            return false;
14520        }
14521
14522        String[] newArgs = new String[args.length - opti];
14523        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14524
14525        TaskRecord lastTask = null;
14526        boolean needSep = false;
14527        for (int i=activities.size()-1; i>=0; i--) {
14528            ActivityRecord r = activities.get(i);
14529            if (needSep) {
14530                pw.println();
14531            }
14532            needSep = true;
14533            synchronized (this) {
14534                if (lastTask != r.task) {
14535                    lastTask = r.task;
14536                    pw.print("TASK "); pw.print(lastTask.affinity);
14537                            pw.print(" id="); pw.println(lastTask.taskId);
14538                    if (dumpAll) {
14539                        lastTask.dump(pw, "  ");
14540                    }
14541                }
14542            }
14543            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14544        }
14545        return true;
14546    }
14547
14548    /**
14549     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14550     * there is a thread associated with the activity.
14551     */
14552    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14553            final ActivityRecord r, String[] args, boolean dumpAll) {
14554        String innerPrefix = prefix + "  ";
14555        synchronized (this) {
14556            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14557                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14558                    pw.print(" pid=");
14559                    if (r.app != null) pw.println(r.app.pid);
14560                    else pw.println("(not running)");
14561            if (dumpAll) {
14562                r.dump(pw, innerPrefix);
14563            }
14564        }
14565        if (r.app != null && r.app.thread != null) {
14566            // flush anything that is already in the PrintWriter since the thread is going
14567            // to write to the file descriptor directly
14568            pw.flush();
14569            try {
14570                TransferPipe tp = new TransferPipe();
14571                try {
14572                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14573                            r.appToken, innerPrefix, args);
14574                    tp.go(fd);
14575                } finally {
14576                    tp.kill();
14577                }
14578            } catch (IOException e) {
14579                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14580            } catch (RemoteException e) {
14581                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14582            }
14583        }
14584    }
14585
14586    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14587            int opti, boolean dumpAll, String dumpPackage) {
14588        boolean needSep = false;
14589        boolean onlyHistory = false;
14590        boolean printedAnything = false;
14591
14592        if ("history".equals(dumpPackage)) {
14593            if (opti < args.length && "-s".equals(args[opti])) {
14594                dumpAll = false;
14595            }
14596            onlyHistory = true;
14597            dumpPackage = null;
14598        }
14599
14600        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14601        if (!onlyHistory && dumpAll) {
14602            if (mRegisteredReceivers.size() > 0) {
14603                boolean printed = false;
14604                Iterator it = mRegisteredReceivers.values().iterator();
14605                while (it.hasNext()) {
14606                    ReceiverList r = (ReceiverList)it.next();
14607                    if (dumpPackage != null && (r.app == null ||
14608                            !dumpPackage.equals(r.app.info.packageName))) {
14609                        continue;
14610                    }
14611                    if (!printed) {
14612                        pw.println("  Registered Receivers:");
14613                        needSep = true;
14614                        printed = true;
14615                        printedAnything = true;
14616                    }
14617                    pw.print("  * "); pw.println(r);
14618                    r.dump(pw, "    ");
14619                }
14620            }
14621
14622            if (mReceiverResolver.dump(pw, needSep ?
14623                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14624                    "    ", dumpPackage, false, false)) {
14625                needSep = true;
14626                printedAnything = true;
14627            }
14628        }
14629
14630        for (BroadcastQueue q : mBroadcastQueues) {
14631            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14632            printedAnything |= needSep;
14633        }
14634
14635        needSep = true;
14636
14637        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14638            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14639                if (needSep) {
14640                    pw.println();
14641                }
14642                needSep = true;
14643                printedAnything = true;
14644                pw.print("  Sticky broadcasts for user ");
14645                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14646                StringBuilder sb = new StringBuilder(128);
14647                for (Map.Entry<String, ArrayList<Intent>> ent
14648                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14649                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14650                    if (dumpAll) {
14651                        pw.println(":");
14652                        ArrayList<Intent> intents = ent.getValue();
14653                        final int N = intents.size();
14654                        for (int i=0; i<N; i++) {
14655                            sb.setLength(0);
14656                            sb.append("    Intent: ");
14657                            intents.get(i).toShortString(sb, false, true, false, false);
14658                            pw.println(sb.toString());
14659                            Bundle bundle = intents.get(i).getExtras();
14660                            if (bundle != null) {
14661                                pw.print("      ");
14662                                pw.println(bundle.toString());
14663                            }
14664                        }
14665                    } else {
14666                        pw.println("");
14667                    }
14668                }
14669            }
14670        }
14671
14672        if (!onlyHistory && dumpAll) {
14673            pw.println();
14674            for (BroadcastQueue queue : mBroadcastQueues) {
14675                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14676                        + queue.mBroadcastsScheduled);
14677            }
14678            pw.println("  mHandler:");
14679            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14680            needSep = true;
14681            printedAnything = true;
14682        }
14683
14684        if (!printedAnything) {
14685            pw.println("  (nothing)");
14686        }
14687    }
14688
14689    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14690            int opti, boolean dumpAll, String dumpPackage) {
14691        boolean needSep;
14692        boolean printedAnything = false;
14693
14694        ItemMatcher matcher = new ItemMatcher();
14695        matcher.build(args, opti);
14696
14697        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14698
14699        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14700        printedAnything |= needSep;
14701
14702        if (mLaunchingProviders.size() > 0) {
14703            boolean printed = false;
14704            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14705                ContentProviderRecord r = mLaunchingProviders.get(i);
14706                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14707                    continue;
14708                }
14709                if (!printed) {
14710                    if (needSep) pw.println();
14711                    needSep = true;
14712                    pw.println("  Launching content providers:");
14713                    printed = true;
14714                    printedAnything = true;
14715                }
14716                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14717                        pw.println(r);
14718            }
14719        }
14720
14721        if (!printedAnything) {
14722            pw.println("  (nothing)");
14723        }
14724    }
14725
14726    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14727            int opti, boolean dumpAll, String dumpPackage) {
14728        boolean needSep = false;
14729        boolean printedAnything = false;
14730
14731        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14732
14733        if (mGrantedUriPermissions.size() > 0) {
14734            boolean printed = false;
14735            int dumpUid = -2;
14736            if (dumpPackage != null) {
14737                try {
14738                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14739                            MATCH_UNINSTALLED_PACKAGES, 0);
14740                } catch (NameNotFoundException e) {
14741                    dumpUid = -1;
14742                }
14743            }
14744            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14745                int uid = mGrantedUriPermissions.keyAt(i);
14746                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14747                    continue;
14748                }
14749                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14750                if (!printed) {
14751                    if (needSep) pw.println();
14752                    needSep = true;
14753                    pw.println("  Granted Uri Permissions:");
14754                    printed = true;
14755                    printedAnything = true;
14756                }
14757                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14758                for (UriPermission perm : perms.values()) {
14759                    pw.print("    "); pw.println(perm);
14760                    if (dumpAll) {
14761                        perm.dump(pw, "      ");
14762                    }
14763                }
14764            }
14765        }
14766
14767        if (!printedAnything) {
14768            pw.println("  (nothing)");
14769        }
14770    }
14771
14772    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14773            int opti, boolean dumpAll, String dumpPackage) {
14774        boolean printed = false;
14775
14776        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14777
14778        if (mIntentSenderRecords.size() > 0) {
14779            Iterator<WeakReference<PendingIntentRecord>> it
14780                    = mIntentSenderRecords.values().iterator();
14781            while (it.hasNext()) {
14782                WeakReference<PendingIntentRecord> ref = it.next();
14783                PendingIntentRecord rec = ref != null ? ref.get(): null;
14784                if (dumpPackage != null && (rec == null
14785                        || !dumpPackage.equals(rec.key.packageName))) {
14786                    continue;
14787                }
14788                printed = true;
14789                if (rec != null) {
14790                    pw.print("  * "); pw.println(rec);
14791                    if (dumpAll) {
14792                        rec.dump(pw, "    ");
14793                    }
14794                } else {
14795                    pw.print("  * "); pw.println(ref);
14796                }
14797            }
14798        }
14799
14800        if (!printed) {
14801            pw.println("  (nothing)");
14802        }
14803    }
14804
14805    private static final int dumpProcessList(PrintWriter pw,
14806            ActivityManagerService service, List list,
14807            String prefix, String normalLabel, String persistentLabel,
14808            String dumpPackage) {
14809        int numPers = 0;
14810        final int N = list.size()-1;
14811        for (int i=N; i>=0; i--) {
14812            ProcessRecord r = (ProcessRecord)list.get(i);
14813            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14814                continue;
14815            }
14816            pw.println(String.format("%s%s #%2d: %s",
14817                    prefix, (r.persistent ? persistentLabel : normalLabel),
14818                    i, r.toString()));
14819            if (r.persistent) {
14820                numPers++;
14821            }
14822        }
14823        return numPers;
14824    }
14825
14826    private static final boolean dumpProcessOomList(PrintWriter pw,
14827            ActivityManagerService service, List<ProcessRecord> origList,
14828            String prefix, String normalLabel, String persistentLabel,
14829            boolean inclDetails, String dumpPackage) {
14830
14831        ArrayList<Pair<ProcessRecord, Integer>> list
14832                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14833        for (int i=0; i<origList.size(); i++) {
14834            ProcessRecord r = origList.get(i);
14835            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14836                continue;
14837            }
14838            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14839        }
14840
14841        if (list.size() <= 0) {
14842            return false;
14843        }
14844
14845        Comparator<Pair<ProcessRecord, Integer>> comparator
14846                = new Comparator<Pair<ProcessRecord, Integer>>() {
14847            @Override
14848            public int compare(Pair<ProcessRecord, Integer> object1,
14849                    Pair<ProcessRecord, Integer> object2) {
14850                if (object1.first.setAdj != object2.first.setAdj) {
14851                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14852                }
14853                if (object1.first.setProcState != object2.first.setProcState) {
14854                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14855                }
14856                if (object1.second.intValue() != object2.second.intValue()) {
14857                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14858                }
14859                return 0;
14860            }
14861        };
14862
14863        Collections.sort(list, comparator);
14864
14865        final long curRealtime = SystemClock.elapsedRealtime();
14866        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14867        final long curUptime = SystemClock.uptimeMillis();
14868        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14869
14870        for (int i=list.size()-1; i>=0; i--) {
14871            ProcessRecord r = list.get(i).first;
14872            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14873            char schedGroup;
14874            switch (r.setSchedGroup) {
14875                case ProcessList.SCHED_GROUP_BACKGROUND:
14876                    schedGroup = 'B';
14877                    break;
14878                case ProcessList.SCHED_GROUP_DEFAULT:
14879                    schedGroup = 'F';
14880                    break;
14881                case ProcessList.SCHED_GROUP_TOP_APP:
14882                    schedGroup = 'T';
14883                    break;
14884                default:
14885                    schedGroup = '?';
14886                    break;
14887            }
14888            char foreground;
14889            if (r.foregroundActivities) {
14890                foreground = 'A';
14891            } else if (r.foregroundServices) {
14892                foreground = 'S';
14893            } else {
14894                foreground = ' ';
14895            }
14896            String procState = ProcessList.makeProcStateString(r.curProcState);
14897            pw.print(prefix);
14898            pw.print(r.persistent ? persistentLabel : normalLabel);
14899            pw.print(" #");
14900            int num = (origList.size()-1)-list.get(i).second;
14901            if (num < 10) pw.print(' ');
14902            pw.print(num);
14903            pw.print(": ");
14904            pw.print(oomAdj);
14905            pw.print(' ');
14906            pw.print(schedGroup);
14907            pw.print('/');
14908            pw.print(foreground);
14909            pw.print('/');
14910            pw.print(procState);
14911            pw.print(" trm:");
14912            if (r.trimMemoryLevel < 10) pw.print(' ');
14913            pw.print(r.trimMemoryLevel);
14914            pw.print(' ');
14915            pw.print(r.toShortString());
14916            pw.print(" (");
14917            pw.print(r.adjType);
14918            pw.println(')');
14919            if (r.adjSource != null || r.adjTarget != null) {
14920                pw.print(prefix);
14921                pw.print("    ");
14922                if (r.adjTarget instanceof ComponentName) {
14923                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14924                } else if (r.adjTarget != null) {
14925                    pw.print(r.adjTarget.toString());
14926                } else {
14927                    pw.print("{null}");
14928                }
14929                pw.print("<=");
14930                if (r.adjSource instanceof ProcessRecord) {
14931                    pw.print("Proc{");
14932                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14933                    pw.println("}");
14934                } else if (r.adjSource != null) {
14935                    pw.println(r.adjSource.toString());
14936                } else {
14937                    pw.println("{null}");
14938                }
14939            }
14940            if (inclDetails) {
14941                pw.print(prefix);
14942                pw.print("    ");
14943                pw.print("oom: max="); pw.print(r.maxAdj);
14944                pw.print(" curRaw="); pw.print(r.curRawAdj);
14945                pw.print(" setRaw="); pw.print(r.setRawAdj);
14946                pw.print(" cur="); pw.print(r.curAdj);
14947                pw.print(" set="); pw.println(r.setAdj);
14948                pw.print(prefix);
14949                pw.print("    ");
14950                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14951                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14952                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14953                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14954                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14955                pw.println();
14956                pw.print(prefix);
14957                pw.print("    ");
14958                pw.print("cached="); pw.print(r.cached);
14959                pw.print(" empty="); pw.print(r.empty);
14960                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14961
14962                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14963                    if (r.lastWakeTime != 0) {
14964                        long wtime;
14965                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14966                        synchronized (stats) {
14967                            wtime = stats.getProcessWakeTime(r.info.uid,
14968                                    r.pid, curRealtime);
14969                        }
14970                        long timeUsed = wtime - r.lastWakeTime;
14971                        pw.print(prefix);
14972                        pw.print("    ");
14973                        pw.print("keep awake over ");
14974                        TimeUtils.formatDuration(realtimeSince, pw);
14975                        pw.print(" used ");
14976                        TimeUtils.formatDuration(timeUsed, pw);
14977                        pw.print(" (");
14978                        pw.print((timeUsed*100)/realtimeSince);
14979                        pw.println("%)");
14980                    }
14981                    if (r.lastCpuTime != 0) {
14982                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14983                        pw.print(prefix);
14984                        pw.print("    ");
14985                        pw.print("run cpu over ");
14986                        TimeUtils.formatDuration(uptimeSince, pw);
14987                        pw.print(" used ");
14988                        TimeUtils.formatDuration(timeUsed, pw);
14989                        pw.print(" (");
14990                        pw.print((timeUsed*100)/uptimeSince);
14991                        pw.println("%)");
14992                    }
14993                }
14994            }
14995        }
14996        return true;
14997    }
14998
14999    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15000            String[] args) {
15001        ArrayList<ProcessRecord> procs;
15002        synchronized (this) {
15003            if (args != null && args.length > start
15004                    && args[start].charAt(0) != '-') {
15005                procs = new ArrayList<ProcessRecord>();
15006                int pid = -1;
15007                try {
15008                    pid = Integer.parseInt(args[start]);
15009                } catch (NumberFormatException e) {
15010                }
15011                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15012                    ProcessRecord proc = mLruProcesses.get(i);
15013                    if (proc.pid == pid) {
15014                        procs.add(proc);
15015                    } else if (allPkgs && proc.pkgList != null
15016                            && proc.pkgList.containsKey(args[start])) {
15017                        procs.add(proc);
15018                    } else if (proc.processName.equals(args[start])) {
15019                        procs.add(proc);
15020                    }
15021                }
15022                if (procs.size() <= 0) {
15023                    return null;
15024                }
15025            } else {
15026                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15027            }
15028        }
15029        return procs;
15030    }
15031
15032    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15033            PrintWriter pw, String[] args) {
15034        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15035        if (procs == null) {
15036            pw.println("No process found for: " + args[0]);
15037            return;
15038        }
15039
15040        long uptime = SystemClock.uptimeMillis();
15041        long realtime = SystemClock.elapsedRealtime();
15042        pw.println("Applications Graphics Acceleration Info:");
15043        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15044
15045        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15046            ProcessRecord r = procs.get(i);
15047            if (r.thread != null) {
15048                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15049                pw.flush();
15050                try {
15051                    TransferPipe tp = new TransferPipe();
15052                    try {
15053                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15054                        tp.go(fd);
15055                    } finally {
15056                        tp.kill();
15057                    }
15058                } catch (IOException e) {
15059                    pw.println("Failure while dumping the app: " + r);
15060                    pw.flush();
15061                } catch (RemoteException e) {
15062                    pw.println("Got a RemoteException while dumping the app " + r);
15063                    pw.flush();
15064                }
15065            }
15066        }
15067    }
15068
15069    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15070        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15071        if (procs == null) {
15072            pw.println("No process found for: " + args[0]);
15073            return;
15074        }
15075
15076        pw.println("Applications Database Info:");
15077
15078        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15079            ProcessRecord r = procs.get(i);
15080            if (r.thread != null) {
15081                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15082                pw.flush();
15083                try {
15084                    TransferPipe tp = new TransferPipe();
15085                    try {
15086                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15087                        tp.go(fd);
15088                    } finally {
15089                        tp.kill();
15090                    }
15091                } catch (IOException e) {
15092                    pw.println("Failure while dumping the app: " + r);
15093                    pw.flush();
15094                } catch (RemoteException e) {
15095                    pw.println("Got a RemoteException while dumping the app " + r);
15096                    pw.flush();
15097                }
15098            }
15099        }
15100    }
15101
15102    final static class MemItem {
15103        final boolean isProc;
15104        final String label;
15105        final String shortLabel;
15106        final long pss;
15107        final long swapPss;
15108        final int id;
15109        final boolean hasActivities;
15110        ArrayList<MemItem> subitems;
15111
15112        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15113                boolean _hasActivities) {
15114            isProc = true;
15115            label = _label;
15116            shortLabel = _shortLabel;
15117            pss = _pss;
15118            swapPss = _swapPss;
15119            id = _id;
15120            hasActivities = _hasActivities;
15121        }
15122
15123        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15124            isProc = false;
15125            label = _label;
15126            shortLabel = _shortLabel;
15127            pss = _pss;
15128            swapPss = _swapPss;
15129            id = _id;
15130            hasActivities = false;
15131        }
15132    }
15133
15134    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15135            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15136        if (sort && !isCompact) {
15137            Collections.sort(items, new Comparator<MemItem>() {
15138                @Override
15139                public int compare(MemItem lhs, MemItem rhs) {
15140                    if (lhs.pss < rhs.pss) {
15141                        return 1;
15142                    } else if (lhs.pss > rhs.pss) {
15143                        return -1;
15144                    }
15145                    return 0;
15146                }
15147            });
15148        }
15149
15150        for (int i=0; i<items.size(); i++) {
15151            MemItem mi = items.get(i);
15152            if (!isCompact) {
15153                if (dumpSwapPss) {
15154                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15155                            mi.label, stringifyKBSize(mi.swapPss));
15156                } else {
15157                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15158                }
15159            } else if (mi.isProc) {
15160                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15161                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15162                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15163                pw.println(mi.hasActivities ? ",a" : ",e");
15164            } else {
15165                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15166                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15167            }
15168            if (mi.subitems != null) {
15169                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15170                        true, isCompact, dumpSwapPss);
15171            }
15172        }
15173    }
15174
15175    // These are in KB.
15176    static final long[] DUMP_MEM_BUCKETS = new long[] {
15177        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15178        120*1024, 160*1024, 200*1024,
15179        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15180        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15181    };
15182
15183    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15184            boolean stackLike) {
15185        int start = label.lastIndexOf('.');
15186        if (start >= 0) start++;
15187        else start = 0;
15188        int end = label.length();
15189        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15190            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15191                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15192                out.append(bucket);
15193                out.append(stackLike ? "MB." : "MB ");
15194                out.append(label, start, end);
15195                return;
15196            }
15197        }
15198        out.append(memKB/1024);
15199        out.append(stackLike ? "MB." : "MB ");
15200        out.append(label, start, end);
15201    }
15202
15203    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15204            ProcessList.NATIVE_ADJ,
15205            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15206            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15207            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15208            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15209            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15210            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15211    };
15212    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15213            "Native",
15214            "System", "Persistent", "Persistent Service", "Foreground",
15215            "Visible", "Perceptible",
15216            "Heavy Weight", "Backup",
15217            "A Services", "Home",
15218            "Previous", "B Services", "Cached"
15219    };
15220    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15221            "native",
15222            "sys", "pers", "persvc", "fore",
15223            "vis", "percept",
15224            "heavy", "backup",
15225            "servicea", "home",
15226            "prev", "serviceb", "cached"
15227    };
15228
15229    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15230            long realtime, boolean isCheckinRequest, boolean isCompact) {
15231        if (isCompact) {
15232            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15233        }
15234        if (isCheckinRequest || isCompact) {
15235            // short checkin version
15236            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15237        } else {
15238            pw.println("Applications Memory Usage (in Kilobytes):");
15239            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15240        }
15241    }
15242
15243    private static final int KSM_SHARED = 0;
15244    private static final int KSM_SHARING = 1;
15245    private static final int KSM_UNSHARED = 2;
15246    private static final int KSM_VOLATILE = 3;
15247
15248    private final long[] getKsmInfo() {
15249        long[] longOut = new long[4];
15250        final int[] SINGLE_LONG_FORMAT = new int[] {
15251            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15252        };
15253        long[] longTmp = new long[1];
15254        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15255                SINGLE_LONG_FORMAT, null, longTmp, null);
15256        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15257        longTmp[0] = 0;
15258        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15259                SINGLE_LONG_FORMAT, null, longTmp, null);
15260        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15261        longTmp[0] = 0;
15262        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15263                SINGLE_LONG_FORMAT, null, longTmp, null);
15264        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15265        longTmp[0] = 0;
15266        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15267                SINGLE_LONG_FORMAT, null, longTmp, null);
15268        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15269        return longOut;
15270    }
15271
15272    private static String stringifySize(long size, int order) {
15273        Locale locale = Locale.US;
15274        switch (order) {
15275            case 1:
15276                return String.format(locale, "%,13d", size);
15277            case 1024:
15278                return String.format(locale, "%,9dK", size / 1024);
15279            case 1024 * 1024:
15280                return String.format(locale, "%,5dM", size / 1024 / 1024);
15281            case 1024 * 1024 * 1024:
15282                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15283            default:
15284                throw new IllegalArgumentException("Invalid size order");
15285        }
15286    }
15287
15288    private static String stringifyKBSize(long size) {
15289        return stringifySize(size * 1024, 1024);
15290    }
15291
15292    // Update this version number in case you change the 'compact' format
15293    private static final int MEMINFO_COMPACT_VERSION = 1;
15294
15295    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15296            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15297        boolean dumpDetails = false;
15298        boolean dumpFullDetails = false;
15299        boolean dumpDalvik = false;
15300        boolean dumpSummaryOnly = false;
15301        boolean dumpUnreachable = false;
15302        boolean oomOnly = false;
15303        boolean isCompact = false;
15304        boolean localOnly = false;
15305        boolean packages = false;
15306        boolean isCheckinRequest = false;
15307        boolean dumpSwapPss = false;
15308
15309        int opti = 0;
15310        while (opti < args.length) {
15311            String opt = args[opti];
15312            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15313                break;
15314            }
15315            opti++;
15316            if ("-a".equals(opt)) {
15317                dumpDetails = true;
15318                dumpFullDetails = true;
15319                dumpDalvik = true;
15320                dumpSwapPss = true;
15321            } else if ("-d".equals(opt)) {
15322                dumpDalvik = true;
15323            } else if ("-c".equals(opt)) {
15324                isCompact = true;
15325            } else if ("-s".equals(opt)) {
15326                dumpDetails = true;
15327                dumpSummaryOnly = true;
15328            } else if ("-S".equals(opt)) {
15329                dumpSwapPss = true;
15330            } else if ("--unreachable".equals(opt)) {
15331                dumpUnreachable = true;
15332            } else if ("--oom".equals(opt)) {
15333                oomOnly = true;
15334            } else if ("--local".equals(opt)) {
15335                localOnly = true;
15336            } else if ("--package".equals(opt)) {
15337                packages = true;
15338            } else if ("--checkin".equals(opt)) {
15339                isCheckinRequest = true;
15340
15341            } else if ("-h".equals(opt)) {
15342                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15343                pw.println("  -a: include all available information for each process.");
15344                pw.println("  -d: include dalvik details.");
15345                pw.println("  -c: dump in a compact machine-parseable representation.");
15346                pw.println("  -s: dump only summary of application memory usage.");
15347                pw.println("  -S: dump also SwapPss.");
15348                pw.println("  --oom: only show processes organized by oom adj.");
15349                pw.println("  --local: only collect details locally, don't call process.");
15350                pw.println("  --package: interpret process arg as package, dumping all");
15351                pw.println("             processes that have loaded that package.");
15352                pw.println("  --checkin: dump data for a checkin");
15353                pw.println("If [process] is specified it can be the name or ");
15354                pw.println("pid of a specific process to dump.");
15355                return;
15356            } else {
15357                pw.println("Unknown argument: " + opt + "; use -h for help");
15358            }
15359        }
15360
15361        long uptime = SystemClock.uptimeMillis();
15362        long realtime = SystemClock.elapsedRealtime();
15363        final long[] tmpLong = new long[1];
15364
15365        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15366        if (procs == null) {
15367            // No Java processes.  Maybe they want to print a native process.
15368            if (args != null && args.length > opti
15369                    && args[opti].charAt(0) != '-') {
15370                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15371                        = new ArrayList<ProcessCpuTracker.Stats>();
15372                updateCpuStatsNow();
15373                int findPid = -1;
15374                try {
15375                    findPid = Integer.parseInt(args[opti]);
15376                } catch (NumberFormatException e) {
15377                }
15378                synchronized (mProcessCpuTracker) {
15379                    final int N = mProcessCpuTracker.countStats();
15380                    for (int i=0; i<N; i++) {
15381                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15382                        if (st.pid == findPid || (st.baseName != null
15383                                && st.baseName.equals(args[opti]))) {
15384                            nativeProcs.add(st);
15385                        }
15386                    }
15387                }
15388                if (nativeProcs.size() > 0) {
15389                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15390                            isCompact);
15391                    Debug.MemoryInfo mi = null;
15392                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15393                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15394                        final int pid = r.pid;
15395                        if (!isCheckinRequest && dumpDetails) {
15396                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15397                        }
15398                        if (mi == null) {
15399                            mi = new Debug.MemoryInfo();
15400                        }
15401                        if (dumpDetails || (!brief && !oomOnly)) {
15402                            Debug.getMemoryInfo(pid, mi);
15403                        } else {
15404                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15405                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15406                        }
15407                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15408                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15409                        if (isCheckinRequest) {
15410                            pw.println();
15411                        }
15412                    }
15413                    return;
15414                }
15415            }
15416            pw.println("No process found for: " + args[opti]);
15417            return;
15418        }
15419
15420        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15421            dumpDetails = true;
15422        }
15423
15424        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15425
15426        String[] innerArgs = new String[args.length-opti];
15427        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15428
15429        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15430        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15431        long nativePss = 0;
15432        long nativeSwapPss = 0;
15433        long dalvikPss = 0;
15434        long dalvikSwapPss = 0;
15435        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15436                EmptyArray.LONG;
15437        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15438                EmptyArray.LONG;
15439        long otherPss = 0;
15440        long otherSwapPss = 0;
15441        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15442        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15443
15444        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15445        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15446        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15447                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15448
15449        long totalPss = 0;
15450        long totalSwapPss = 0;
15451        long cachedPss = 0;
15452        long cachedSwapPss = 0;
15453        boolean hasSwapPss = false;
15454
15455        Debug.MemoryInfo mi = null;
15456        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15457            final ProcessRecord r = procs.get(i);
15458            final IApplicationThread thread;
15459            final int pid;
15460            final int oomAdj;
15461            final boolean hasActivities;
15462            synchronized (this) {
15463                thread = r.thread;
15464                pid = r.pid;
15465                oomAdj = r.getSetAdjWithServices();
15466                hasActivities = r.activities.size() > 0;
15467            }
15468            if (thread != null) {
15469                if (!isCheckinRequest && dumpDetails) {
15470                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15471                }
15472                if (mi == null) {
15473                    mi = new Debug.MemoryInfo();
15474                }
15475                if (dumpDetails || (!brief && !oomOnly)) {
15476                    Debug.getMemoryInfo(pid, mi);
15477                    hasSwapPss = mi.hasSwappedOutPss;
15478                } else {
15479                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15480                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15481                }
15482                if (dumpDetails) {
15483                    if (localOnly) {
15484                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15485                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15486                        if (isCheckinRequest) {
15487                            pw.println();
15488                        }
15489                    } else {
15490                        try {
15491                            pw.flush();
15492                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15493                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15494                        } catch (RemoteException e) {
15495                            if (!isCheckinRequest) {
15496                                pw.println("Got RemoteException!");
15497                                pw.flush();
15498                            }
15499                        }
15500                    }
15501                }
15502
15503                final long myTotalPss = mi.getTotalPss();
15504                final long myTotalUss = mi.getTotalUss();
15505                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15506
15507                synchronized (this) {
15508                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15509                        // Record this for posterity if the process has been stable.
15510                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15511                    }
15512                }
15513
15514                if (!isCheckinRequest && mi != null) {
15515                    totalPss += myTotalPss;
15516                    totalSwapPss += myTotalSwapPss;
15517                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15518                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15519                            myTotalSwapPss, pid, hasActivities);
15520                    procMems.add(pssItem);
15521                    procMemsMap.put(pid, pssItem);
15522
15523                    nativePss += mi.nativePss;
15524                    nativeSwapPss += mi.nativeSwappedOutPss;
15525                    dalvikPss += mi.dalvikPss;
15526                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15527                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15528                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15529                        dalvikSubitemSwapPss[j] +=
15530                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15531                    }
15532                    otherPss += mi.otherPss;
15533                    otherSwapPss += mi.otherSwappedOutPss;
15534                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15535                        long mem = mi.getOtherPss(j);
15536                        miscPss[j] += mem;
15537                        otherPss -= mem;
15538                        mem = mi.getOtherSwappedOutPss(j);
15539                        miscSwapPss[j] += mem;
15540                        otherSwapPss -= mem;
15541                    }
15542
15543                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15544                        cachedPss += myTotalPss;
15545                        cachedSwapPss += myTotalSwapPss;
15546                    }
15547
15548                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15549                        if (oomIndex == (oomPss.length - 1)
15550                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15551                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15552                            oomPss[oomIndex] += myTotalPss;
15553                            oomSwapPss[oomIndex] += myTotalSwapPss;
15554                            if (oomProcs[oomIndex] == null) {
15555                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15556                            }
15557                            oomProcs[oomIndex].add(pssItem);
15558                            break;
15559                        }
15560                    }
15561                }
15562            }
15563        }
15564
15565        long nativeProcTotalPss = 0;
15566
15567        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15568            // If we are showing aggregations, also look for native processes to
15569            // include so that our aggregations are more accurate.
15570            updateCpuStatsNow();
15571            mi = null;
15572            synchronized (mProcessCpuTracker) {
15573                final int N = mProcessCpuTracker.countStats();
15574                for (int i=0; i<N; i++) {
15575                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15576                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15577                        if (mi == null) {
15578                            mi = new Debug.MemoryInfo();
15579                        }
15580                        if (!brief && !oomOnly) {
15581                            Debug.getMemoryInfo(st.pid, mi);
15582                        } else {
15583                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15584                            mi.nativePrivateDirty = (int)tmpLong[0];
15585                        }
15586
15587                        final long myTotalPss = mi.getTotalPss();
15588                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15589                        totalPss += myTotalPss;
15590                        nativeProcTotalPss += myTotalPss;
15591
15592                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15593                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15594                        procMems.add(pssItem);
15595
15596                        nativePss += mi.nativePss;
15597                        nativeSwapPss += mi.nativeSwappedOutPss;
15598                        dalvikPss += mi.dalvikPss;
15599                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15600                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15601                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15602                            dalvikSubitemSwapPss[j] +=
15603                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15604                        }
15605                        otherPss += mi.otherPss;
15606                        otherSwapPss += mi.otherSwappedOutPss;
15607                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15608                            long mem = mi.getOtherPss(j);
15609                            miscPss[j] += mem;
15610                            otherPss -= mem;
15611                            mem = mi.getOtherSwappedOutPss(j);
15612                            miscSwapPss[j] += mem;
15613                            otherSwapPss -= mem;
15614                        }
15615                        oomPss[0] += myTotalPss;
15616                        oomSwapPss[0] += myTotalSwapPss;
15617                        if (oomProcs[0] == null) {
15618                            oomProcs[0] = new ArrayList<MemItem>();
15619                        }
15620                        oomProcs[0].add(pssItem);
15621                    }
15622                }
15623            }
15624
15625            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15626
15627            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15628            final MemItem dalvikItem =
15629                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15630            if (dalvikSubitemPss.length > 0) {
15631                dalvikItem.subitems = new ArrayList<MemItem>();
15632                for (int j=0; j<dalvikSubitemPss.length; j++) {
15633                    final String name = Debug.MemoryInfo.getOtherLabel(
15634                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15635                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15636                                    dalvikSubitemSwapPss[j], j));
15637                }
15638            }
15639            catMems.add(dalvikItem);
15640            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15641            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15642                String label = Debug.MemoryInfo.getOtherLabel(j);
15643                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15644            }
15645
15646            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15647            for (int j=0; j<oomPss.length; j++) {
15648                if (oomPss[j] != 0) {
15649                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15650                            : DUMP_MEM_OOM_LABEL[j];
15651                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15652                            DUMP_MEM_OOM_ADJ[j]);
15653                    item.subitems = oomProcs[j];
15654                    oomMems.add(item);
15655                }
15656            }
15657
15658            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15659            if (!brief && !oomOnly && !isCompact) {
15660                pw.println();
15661                pw.println("Total PSS by process:");
15662                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15663                pw.println();
15664            }
15665            if (!isCompact) {
15666                pw.println("Total PSS by OOM adjustment:");
15667            }
15668            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15669            if (!brief && !oomOnly) {
15670                PrintWriter out = categoryPw != null ? categoryPw : pw;
15671                if (!isCompact) {
15672                    out.println();
15673                    out.println("Total PSS by category:");
15674                }
15675                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15676            }
15677            if (!isCompact) {
15678                pw.println();
15679            }
15680            MemInfoReader memInfo = new MemInfoReader();
15681            memInfo.readMemInfo();
15682            if (nativeProcTotalPss > 0) {
15683                synchronized (this) {
15684                    final long cachedKb = memInfo.getCachedSizeKb();
15685                    final long freeKb = memInfo.getFreeSizeKb();
15686                    final long zramKb = memInfo.getZramTotalSizeKb();
15687                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15688                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15689                            kernelKb*1024, nativeProcTotalPss*1024);
15690                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15691                            nativeProcTotalPss);
15692                }
15693            }
15694            if (!brief) {
15695                if (!isCompact) {
15696                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15697                    pw.print(" (status ");
15698                    switch (mLastMemoryLevel) {
15699                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15700                            pw.println("normal)");
15701                            break;
15702                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15703                            pw.println("moderate)");
15704                            break;
15705                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15706                            pw.println("low)");
15707                            break;
15708                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15709                            pw.println("critical)");
15710                            break;
15711                        default:
15712                            pw.print(mLastMemoryLevel);
15713                            pw.println(")");
15714                            break;
15715                    }
15716                    pw.print(" Free RAM: ");
15717                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15718                            + memInfo.getFreeSizeKb()));
15719                    pw.print(" (");
15720                    pw.print(stringifyKBSize(cachedPss));
15721                    pw.print(" cached pss + ");
15722                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15723                    pw.print(" cached kernel + ");
15724                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15725                    pw.println(" free)");
15726                } else {
15727                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15728                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15729                            + memInfo.getFreeSizeKb()); pw.print(",");
15730                    pw.println(totalPss - cachedPss);
15731                }
15732            }
15733            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15734                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15735                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15736            if (!isCompact) {
15737                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15738                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15739                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15740                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15741                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15742            } else {
15743                pw.print("lostram,"); pw.println(lostRAM);
15744            }
15745            if (!brief) {
15746                if (memInfo.getZramTotalSizeKb() != 0) {
15747                    if (!isCompact) {
15748                        pw.print("     ZRAM: ");
15749                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15750                                pw.print(" physical used for ");
15751                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15752                                        - memInfo.getSwapFreeSizeKb()));
15753                                pw.print(" in swap (");
15754                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15755                                pw.println(" total swap)");
15756                    } else {
15757                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15758                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15759                                pw.println(memInfo.getSwapFreeSizeKb());
15760                    }
15761                }
15762                final long[] ksm = getKsmInfo();
15763                if (!isCompact) {
15764                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15765                            || ksm[KSM_VOLATILE] != 0) {
15766                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15767                                pw.print(" saved from shared ");
15768                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15769                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15770                                pw.print(" unshared; ");
15771                                pw.print(stringifyKBSize(
15772                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15773                    }
15774                    pw.print("   Tuning: ");
15775                    pw.print(ActivityManager.staticGetMemoryClass());
15776                    pw.print(" (large ");
15777                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15778                    pw.print("), oom ");
15779                    pw.print(stringifySize(
15780                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15781                    pw.print(", restore limit ");
15782                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
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                } else {
15791                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15792                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15793                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15794                    pw.print("tuning,");
15795                    pw.print(ActivityManager.staticGetMemoryClass());
15796                    pw.print(',');
15797                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15798                    pw.print(',');
15799                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15800                    if (ActivityManager.isLowRamDeviceStatic()) {
15801                        pw.print(",low-ram");
15802                    }
15803                    if (ActivityManager.isHighEndGfx()) {
15804                        pw.print(",high-end-gfx");
15805                    }
15806                    pw.println();
15807                }
15808            }
15809        }
15810    }
15811
15812    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15813            long memtrack, String name) {
15814        sb.append("  ");
15815        sb.append(ProcessList.makeOomAdjString(oomAdj));
15816        sb.append(' ');
15817        sb.append(ProcessList.makeProcStateString(procState));
15818        sb.append(' ');
15819        ProcessList.appendRamKb(sb, pss);
15820        sb.append(": ");
15821        sb.append(name);
15822        if (memtrack > 0) {
15823            sb.append(" (");
15824            sb.append(stringifyKBSize(memtrack));
15825            sb.append(" memtrack)");
15826        }
15827    }
15828
15829    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15830        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15831        sb.append(" (pid ");
15832        sb.append(mi.pid);
15833        sb.append(") ");
15834        sb.append(mi.adjType);
15835        sb.append('\n');
15836        if (mi.adjReason != null) {
15837            sb.append("                      ");
15838            sb.append(mi.adjReason);
15839            sb.append('\n');
15840        }
15841    }
15842
15843    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15844        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15845        for (int i=0, N=memInfos.size(); i<N; i++) {
15846            ProcessMemInfo mi = memInfos.get(i);
15847            infoMap.put(mi.pid, mi);
15848        }
15849        updateCpuStatsNow();
15850        long[] memtrackTmp = new long[1];
15851        synchronized (mProcessCpuTracker) {
15852            final int N = mProcessCpuTracker.countStats();
15853            for (int i=0; i<N; i++) {
15854                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15855                if (st.vsize > 0) {
15856                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15857                    if (pss > 0) {
15858                        if (infoMap.indexOfKey(st.pid) < 0) {
15859                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15860                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15861                            mi.pss = pss;
15862                            mi.memtrack = memtrackTmp[0];
15863                            memInfos.add(mi);
15864                        }
15865                    }
15866                }
15867            }
15868        }
15869
15870        long totalPss = 0;
15871        long totalMemtrack = 0;
15872        for (int i=0, N=memInfos.size(); i<N; i++) {
15873            ProcessMemInfo mi = memInfos.get(i);
15874            if (mi.pss == 0) {
15875                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15876                mi.memtrack = memtrackTmp[0];
15877            }
15878            totalPss += mi.pss;
15879            totalMemtrack += mi.memtrack;
15880        }
15881        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15882            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15883                if (lhs.oomAdj != rhs.oomAdj) {
15884                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15885                }
15886                if (lhs.pss != rhs.pss) {
15887                    return lhs.pss < rhs.pss ? 1 : -1;
15888                }
15889                return 0;
15890            }
15891        });
15892
15893        StringBuilder tag = new StringBuilder(128);
15894        StringBuilder stack = new StringBuilder(128);
15895        tag.append("Low on memory -- ");
15896        appendMemBucket(tag, totalPss, "total", false);
15897        appendMemBucket(stack, totalPss, "total", true);
15898
15899        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15900        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15901        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15902
15903        boolean firstLine = true;
15904        int lastOomAdj = Integer.MIN_VALUE;
15905        long extraNativeRam = 0;
15906        long extraNativeMemtrack = 0;
15907        long cachedPss = 0;
15908        for (int i=0, N=memInfos.size(); i<N; i++) {
15909            ProcessMemInfo mi = memInfos.get(i);
15910
15911            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15912                cachedPss += mi.pss;
15913            }
15914
15915            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15916                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15917                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15918                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15919                if (lastOomAdj != mi.oomAdj) {
15920                    lastOomAdj = mi.oomAdj;
15921                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15922                        tag.append(" / ");
15923                    }
15924                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15925                        if (firstLine) {
15926                            stack.append(":");
15927                            firstLine = false;
15928                        }
15929                        stack.append("\n\t at ");
15930                    } else {
15931                        stack.append("$");
15932                    }
15933                } else {
15934                    tag.append(" ");
15935                    stack.append("$");
15936                }
15937                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15938                    appendMemBucket(tag, mi.pss, mi.name, false);
15939                }
15940                appendMemBucket(stack, mi.pss, mi.name, true);
15941                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15942                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15943                    stack.append("(");
15944                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15945                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15946                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15947                            stack.append(":");
15948                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15949                        }
15950                    }
15951                    stack.append(")");
15952                }
15953            }
15954
15955            appendMemInfo(fullNativeBuilder, mi);
15956            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15957                // The short form only has native processes that are >= 512K.
15958                if (mi.pss >= 512) {
15959                    appendMemInfo(shortNativeBuilder, mi);
15960                } else {
15961                    extraNativeRam += mi.pss;
15962                    extraNativeMemtrack += mi.memtrack;
15963                }
15964            } else {
15965                // Short form has all other details, but if we have collected RAM
15966                // from smaller native processes let's dump a summary of that.
15967                if (extraNativeRam > 0) {
15968                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15969                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15970                    shortNativeBuilder.append('\n');
15971                    extraNativeRam = 0;
15972                }
15973                appendMemInfo(fullJavaBuilder, mi);
15974            }
15975        }
15976
15977        fullJavaBuilder.append("           ");
15978        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15979        fullJavaBuilder.append(": TOTAL");
15980        if (totalMemtrack > 0) {
15981            fullJavaBuilder.append(" (");
15982            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15983            fullJavaBuilder.append(" memtrack)");
15984        } else {
15985        }
15986        fullJavaBuilder.append("\n");
15987
15988        MemInfoReader memInfo = new MemInfoReader();
15989        memInfo.readMemInfo();
15990        final long[] infos = memInfo.getRawInfo();
15991
15992        StringBuilder memInfoBuilder = new StringBuilder(1024);
15993        Debug.getMemInfo(infos);
15994        memInfoBuilder.append("  MemInfo: ");
15995        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15996        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15997        memInfoBuilder.append(stringifyKBSize(
15998                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15999        memInfoBuilder.append(stringifyKBSize(
16000                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16001        memInfoBuilder.append(stringifyKBSize(
16002                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16003        memInfoBuilder.append("           ");
16004        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16005        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16006        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16007        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16008        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16009            memInfoBuilder.append("  ZRAM: ");
16010            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16011            memInfoBuilder.append(" RAM, ");
16012            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16013            memInfoBuilder.append(" swap total, ");
16014            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16015            memInfoBuilder.append(" swap free\n");
16016        }
16017        final long[] ksm = getKsmInfo();
16018        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16019                || ksm[KSM_VOLATILE] != 0) {
16020            memInfoBuilder.append("  KSM: ");
16021            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16022            memInfoBuilder.append(" saved from shared ");
16023            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16024            memInfoBuilder.append("\n       ");
16025            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16026            memInfoBuilder.append(" unshared; ");
16027            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16028            memInfoBuilder.append(" volatile\n");
16029        }
16030        memInfoBuilder.append("  Free RAM: ");
16031        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16032                + memInfo.getFreeSizeKb()));
16033        memInfoBuilder.append("\n");
16034        memInfoBuilder.append("  Used RAM: ");
16035        memInfoBuilder.append(stringifyKBSize(
16036                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16037        memInfoBuilder.append("\n");
16038        memInfoBuilder.append("  Lost RAM: ");
16039        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16040                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16041                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16042        memInfoBuilder.append("\n");
16043        Slog.i(TAG, "Low on memory:");
16044        Slog.i(TAG, shortNativeBuilder.toString());
16045        Slog.i(TAG, fullJavaBuilder.toString());
16046        Slog.i(TAG, memInfoBuilder.toString());
16047
16048        StringBuilder dropBuilder = new StringBuilder(1024);
16049        /*
16050        StringWriter oomSw = new StringWriter();
16051        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16052        StringWriter catSw = new StringWriter();
16053        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16054        String[] emptyArgs = new String[] { };
16055        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16056        oomPw.flush();
16057        String oomString = oomSw.toString();
16058        */
16059        dropBuilder.append("Low on memory:");
16060        dropBuilder.append(stack);
16061        dropBuilder.append('\n');
16062        dropBuilder.append(fullNativeBuilder);
16063        dropBuilder.append(fullJavaBuilder);
16064        dropBuilder.append('\n');
16065        dropBuilder.append(memInfoBuilder);
16066        dropBuilder.append('\n');
16067        /*
16068        dropBuilder.append(oomString);
16069        dropBuilder.append('\n');
16070        */
16071        StringWriter catSw = new StringWriter();
16072        synchronized (ActivityManagerService.this) {
16073            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16074            String[] emptyArgs = new String[] { };
16075            catPw.println();
16076            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16077            catPw.println();
16078            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16079                    false, false, null);
16080            catPw.println();
16081            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16082            catPw.flush();
16083        }
16084        dropBuilder.append(catSw.toString());
16085        addErrorToDropBox("lowmem", null, "system_server", null,
16086                null, tag.toString(), dropBuilder.toString(), null, null);
16087        //Slog.i(TAG, "Sent to dropbox:");
16088        //Slog.i(TAG, dropBuilder.toString());
16089        synchronized (ActivityManagerService.this) {
16090            long now = SystemClock.uptimeMillis();
16091            if (mLastMemUsageReportTime < now) {
16092                mLastMemUsageReportTime = now;
16093            }
16094        }
16095    }
16096
16097    /**
16098     * Searches array of arguments for the specified string
16099     * @param args array of argument strings
16100     * @param value value to search for
16101     * @return true if the value is contained in the array
16102     */
16103    private static boolean scanArgs(String[] args, String value) {
16104        if (args != null) {
16105            for (String arg : args) {
16106                if (value.equals(arg)) {
16107                    return true;
16108                }
16109            }
16110        }
16111        return false;
16112    }
16113
16114    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16115            ContentProviderRecord cpr, boolean always) {
16116        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16117
16118        if (!inLaunching || always) {
16119            synchronized (cpr) {
16120                cpr.launchingApp = null;
16121                cpr.notifyAll();
16122            }
16123            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16124            String names[] = cpr.info.authority.split(";");
16125            for (int j = 0; j < names.length; j++) {
16126                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16127            }
16128        }
16129
16130        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16131            ContentProviderConnection conn = cpr.connections.get(i);
16132            if (conn.waiting) {
16133                // If this connection is waiting for the provider, then we don't
16134                // need to mess with its process unless we are always removing
16135                // or for some reason the provider is not currently launching.
16136                if (inLaunching && !always) {
16137                    continue;
16138                }
16139            }
16140            ProcessRecord capp = conn.client;
16141            conn.dead = true;
16142            if (conn.stableCount > 0) {
16143                if (!capp.persistent && capp.thread != null
16144                        && capp.pid != 0
16145                        && capp.pid != MY_PID) {
16146                    capp.kill("depends on provider "
16147                            + cpr.name.flattenToShortString()
16148                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16149                }
16150            } else if (capp.thread != null && conn.provider.provider != null) {
16151                try {
16152                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16153                } catch (RemoteException e) {
16154                }
16155                // In the protocol here, we don't expect the client to correctly
16156                // clean up this connection, we'll just remove it.
16157                cpr.connections.remove(i);
16158                if (conn.client.conProviders.remove(conn)) {
16159                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16160                }
16161            }
16162        }
16163
16164        if (inLaunching && always) {
16165            mLaunchingProviders.remove(cpr);
16166        }
16167        return inLaunching;
16168    }
16169
16170    /**
16171     * Main code for cleaning up a process when it has gone away.  This is
16172     * called both as a result of the process dying, or directly when stopping
16173     * a process when running in single process mode.
16174     *
16175     * @return Returns true if the given process has been restarted, so the
16176     * app that was passed in must remain on the process lists.
16177     */
16178    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16179            boolean restarting, boolean allowRestart, int index) {
16180        if (index >= 0) {
16181            removeLruProcessLocked(app);
16182            ProcessList.remove(app.pid);
16183        }
16184
16185        mProcessesToGc.remove(app);
16186        mPendingPssProcesses.remove(app);
16187
16188        // Dismiss any open dialogs.
16189        if (app.crashDialog != null && !app.forceCrashReport) {
16190            app.crashDialog.dismiss();
16191            app.crashDialog = null;
16192        }
16193        if (app.anrDialog != null) {
16194            app.anrDialog.dismiss();
16195            app.anrDialog = null;
16196        }
16197        if (app.waitDialog != null) {
16198            app.waitDialog.dismiss();
16199            app.waitDialog = null;
16200        }
16201
16202        app.crashing = false;
16203        app.notResponding = false;
16204
16205        app.resetPackageList(mProcessStats);
16206        app.unlinkDeathRecipient();
16207        app.makeInactive(mProcessStats);
16208        app.waitingToKill = null;
16209        app.forcingToForeground = null;
16210        updateProcessForegroundLocked(app, false, false);
16211        app.foregroundActivities = false;
16212        app.hasShownUi = false;
16213        app.treatLikeActivity = false;
16214        app.hasAboveClient = false;
16215        app.hasClientActivities = false;
16216
16217        mServices.killServicesLocked(app, allowRestart);
16218
16219        boolean restart = false;
16220
16221        // Remove published content providers.
16222        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16223            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16224            final boolean always = app.bad || !allowRestart;
16225            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16226            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16227                // We left the provider in the launching list, need to
16228                // restart it.
16229                restart = true;
16230            }
16231
16232            cpr.provider = null;
16233            cpr.proc = null;
16234        }
16235        app.pubProviders.clear();
16236
16237        // Take care of any launching providers waiting for this process.
16238        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16239            restart = true;
16240        }
16241
16242        // Unregister from connected content providers.
16243        if (!app.conProviders.isEmpty()) {
16244            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16245                ContentProviderConnection conn = app.conProviders.get(i);
16246                conn.provider.connections.remove(conn);
16247                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16248                        conn.provider.name);
16249            }
16250            app.conProviders.clear();
16251        }
16252
16253        // At this point there may be remaining entries in mLaunchingProviders
16254        // where we were the only one waiting, so they are no longer of use.
16255        // Look for these and clean up if found.
16256        // XXX Commented out for now.  Trying to figure out a way to reproduce
16257        // the actual situation to identify what is actually going on.
16258        if (false) {
16259            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16260                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16261                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16262                    synchronized (cpr) {
16263                        cpr.launchingApp = null;
16264                        cpr.notifyAll();
16265                    }
16266                }
16267            }
16268        }
16269
16270        skipCurrentReceiverLocked(app);
16271
16272        // Unregister any receivers.
16273        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16274            removeReceiverLocked(app.receivers.valueAt(i));
16275        }
16276        app.receivers.clear();
16277
16278        // If the app is undergoing backup, tell the backup manager about it
16279        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16280            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16281                    + mBackupTarget.appInfo + " died during backup");
16282            try {
16283                IBackupManager bm = IBackupManager.Stub.asInterface(
16284                        ServiceManager.getService(Context.BACKUP_SERVICE));
16285                bm.agentDisconnected(app.info.packageName);
16286            } catch (RemoteException e) {
16287                // can't happen; backup manager is local
16288            }
16289        }
16290
16291        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16292            ProcessChangeItem item = mPendingProcessChanges.get(i);
16293            if (item.pid == app.pid) {
16294                mPendingProcessChanges.remove(i);
16295                mAvailProcessChanges.add(item);
16296            }
16297        }
16298        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16299                null).sendToTarget();
16300
16301        // If the caller is restarting this app, then leave it in its
16302        // current lists and let the caller take care of it.
16303        if (restarting) {
16304            return false;
16305        }
16306
16307        if (!app.persistent || app.isolated) {
16308            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16309                    "Removing non-persistent process during cleanup: " + app);
16310            removeProcessNameLocked(app.processName, app.uid);
16311            if (mHeavyWeightProcess == app) {
16312                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16313                        mHeavyWeightProcess.userId, 0));
16314                mHeavyWeightProcess = null;
16315            }
16316        } else if (!app.removed) {
16317            // This app is persistent, so we need to keep its record around.
16318            // If it is not already on the pending app list, add it there
16319            // and start a new process for it.
16320            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16321                mPersistentStartingProcesses.add(app);
16322                restart = true;
16323            }
16324        }
16325        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16326                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16327        mProcessesOnHold.remove(app);
16328
16329        if (app == mHomeProcess) {
16330            mHomeProcess = null;
16331        }
16332        if (app == mPreviousProcess) {
16333            mPreviousProcess = null;
16334        }
16335
16336        if (restart && !app.isolated) {
16337            // We have components that still need to be running in the
16338            // process, so re-launch it.
16339            if (index < 0) {
16340                ProcessList.remove(app.pid);
16341            }
16342            addProcessNameLocked(app);
16343            startProcessLocked(app, "restart", app.processName);
16344            return true;
16345        } else if (app.pid > 0 && app.pid != MY_PID) {
16346            // Goodbye!
16347            boolean removed;
16348            synchronized (mPidsSelfLocked) {
16349                mPidsSelfLocked.remove(app.pid);
16350                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16351            }
16352            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16353            if (app.isolated) {
16354                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16355            }
16356            app.setPid(0);
16357        }
16358        return false;
16359    }
16360
16361    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16362        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16363            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16364            if (cpr.launchingApp == app) {
16365                return true;
16366            }
16367        }
16368        return false;
16369    }
16370
16371    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16372        // Look through the content providers we are waiting to have launched,
16373        // and if any run in this process then either schedule a restart of
16374        // the process or kill the client waiting for it if this process has
16375        // gone bad.
16376        boolean restart = false;
16377        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16378            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16379            if (cpr.launchingApp == app) {
16380                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16381                    restart = true;
16382                } else {
16383                    removeDyingProviderLocked(app, cpr, true);
16384                }
16385            }
16386        }
16387        return restart;
16388    }
16389
16390    // =========================================================
16391    // SERVICES
16392    // =========================================================
16393
16394    @Override
16395    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16396            int flags) {
16397        enforceNotIsolatedCaller("getServices");
16398        synchronized (this) {
16399            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16400        }
16401    }
16402
16403    @Override
16404    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16405        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16406        synchronized (this) {
16407            return mServices.getRunningServiceControlPanelLocked(name);
16408        }
16409    }
16410
16411    @Override
16412    public ComponentName startService(IApplicationThread caller, Intent service,
16413            String resolvedType, String callingPackage, int userId)
16414            throws TransactionTooLargeException {
16415        enforceNotIsolatedCaller("startService");
16416        // Refuse possible leaked file descriptors
16417        if (service != null && service.hasFileDescriptors() == true) {
16418            throw new IllegalArgumentException("File descriptors passed in Intent");
16419        }
16420
16421        if (callingPackage == null) {
16422            throw new IllegalArgumentException("callingPackage cannot be null");
16423        }
16424
16425        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16426                "startService: " + service + " type=" + resolvedType);
16427        synchronized(this) {
16428            final int callingPid = Binder.getCallingPid();
16429            final int callingUid = Binder.getCallingUid();
16430            final long origId = Binder.clearCallingIdentity();
16431            ComponentName res = mServices.startServiceLocked(caller, service,
16432                    resolvedType, callingPid, callingUid, callingPackage, userId);
16433            Binder.restoreCallingIdentity(origId);
16434            return res;
16435        }
16436    }
16437
16438    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16439            String callingPackage, int userId)
16440            throws TransactionTooLargeException {
16441        synchronized(this) {
16442            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16443                    "startServiceInPackage: " + service + " type=" + resolvedType);
16444            final long origId = Binder.clearCallingIdentity();
16445            ComponentName res = mServices.startServiceLocked(null, service,
16446                    resolvedType, -1, uid, callingPackage, userId);
16447            Binder.restoreCallingIdentity(origId);
16448            return res;
16449        }
16450    }
16451
16452    @Override
16453    public int stopService(IApplicationThread caller, Intent service,
16454            String resolvedType, int userId) {
16455        enforceNotIsolatedCaller("stopService");
16456        // Refuse possible leaked file descriptors
16457        if (service != null && service.hasFileDescriptors() == true) {
16458            throw new IllegalArgumentException("File descriptors passed in Intent");
16459        }
16460
16461        synchronized(this) {
16462            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16463        }
16464    }
16465
16466    @Override
16467    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16468        enforceNotIsolatedCaller("peekService");
16469        // Refuse possible leaked file descriptors
16470        if (service != null && service.hasFileDescriptors() == true) {
16471            throw new IllegalArgumentException("File descriptors passed in Intent");
16472        }
16473
16474        if (callingPackage == null) {
16475            throw new IllegalArgumentException("callingPackage cannot be null");
16476        }
16477
16478        synchronized(this) {
16479            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16480        }
16481    }
16482
16483    @Override
16484    public boolean stopServiceToken(ComponentName className, IBinder token,
16485            int startId) {
16486        synchronized(this) {
16487            return mServices.stopServiceTokenLocked(className, token, startId);
16488        }
16489    }
16490
16491    @Override
16492    public void setServiceForeground(ComponentName className, IBinder token,
16493            int id, Notification notification, int flags) {
16494        synchronized(this) {
16495            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16496        }
16497    }
16498
16499    @Override
16500    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16501            boolean requireFull, String name, String callerPackage) {
16502        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16503                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16504    }
16505
16506    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16507            String className, int flags) {
16508        boolean result = false;
16509        // For apps that don't have pre-defined UIDs, check for permission
16510        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16511            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16512                if (ActivityManager.checkUidPermission(
16513                        INTERACT_ACROSS_USERS,
16514                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16515                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16516                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16517                            + " requests FLAG_SINGLE_USER, but app does not hold "
16518                            + INTERACT_ACROSS_USERS;
16519                    Slog.w(TAG, msg);
16520                    throw new SecurityException(msg);
16521                }
16522                // Permission passed
16523                result = true;
16524            }
16525        } else if ("system".equals(componentProcessName)) {
16526            result = true;
16527        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16528            // Phone app and persistent apps are allowed to export singleuser providers.
16529            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16530                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16531        }
16532        if (DEBUG_MU) Slog.v(TAG_MU,
16533                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16534                + Integer.toHexString(flags) + ") = " + result);
16535        return result;
16536    }
16537
16538    /**
16539     * Checks to see if the caller is in the same app as the singleton
16540     * component, or the component is in a special app. It allows special apps
16541     * to export singleton components but prevents exporting singleton
16542     * components for regular apps.
16543     */
16544    boolean isValidSingletonCall(int callingUid, int componentUid) {
16545        int componentAppId = UserHandle.getAppId(componentUid);
16546        return UserHandle.isSameApp(callingUid, componentUid)
16547                || componentAppId == Process.SYSTEM_UID
16548                || componentAppId == Process.PHONE_UID
16549                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16550                        == PackageManager.PERMISSION_GRANTED;
16551    }
16552
16553    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16554            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16555            int userId) throws TransactionTooLargeException {
16556        enforceNotIsolatedCaller("bindService");
16557
16558        // Refuse possible leaked file descriptors
16559        if (service != null && service.hasFileDescriptors() == true) {
16560            throw new IllegalArgumentException("File descriptors passed in Intent");
16561        }
16562
16563        if (callingPackage == null) {
16564            throw new IllegalArgumentException("callingPackage cannot be null");
16565        }
16566
16567        synchronized(this) {
16568            return mServices.bindServiceLocked(caller, token, service,
16569                    resolvedType, connection, flags, callingPackage, userId);
16570        }
16571    }
16572
16573    public boolean unbindService(IServiceConnection connection) {
16574        synchronized (this) {
16575            return mServices.unbindServiceLocked(connection);
16576        }
16577    }
16578
16579    public void publishService(IBinder token, Intent intent, IBinder service) {
16580        // Refuse possible leaked file descriptors
16581        if (intent != null && intent.hasFileDescriptors() == true) {
16582            throw new IllegalArgumentException("File descriptors passed in Intent");
16583        }
16584
16585        synchronized(this) {
16586            if (!(token instanceof ServiceRecord)) {
16587                throw new IllegalArgumentException("Invalid service token");
16588            }
16589            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16590        }
16591    }
16592
16593    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16594        // Refuse possible leaked file descriptors
16595        if (intent != null && intent.hasFileDescriptors() == true) {
16596            throw new IllegalArgumentException("File descriptors passed in Intent");
16597        }
16598
16599        synchronized(this) {
16600            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16601        }
16602    }
16603
16604    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16605        synchronized(this) {
16606            if (!(token instanceof ServiceRecord)) {
16607                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16608                throw new IllegalArgumentException("Invalid service token");
16609            }
16610            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16611        }
16612    }
16613
16614    // =========================================================
16615    // BACKUP AND RESTORE
16616    // =========================================================
16617
16618    // Cause the target app to be launched if necessary and its backup agent
16619    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16620    // activity manager to announce its creation.
16621    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16622        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16623                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16624        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16625
16626        synchronized(this) {
16627            // !!! TODO: currently no check here that we're already bound
16628            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16629            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16630            synchronized (stats) {
16631                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16632            }
16633
16634            // Backup agent is now in use, its package can't be stopped.
16635            try {
16636                AppGlobals.getPackageManager().setPackageStoppedState(
16637                        app.packageName, false, UserHandle.getUserId(app.uid));
16638            } catch (RemoteException e) {
16639            } catch (IllegalArgumentException e) {
16640                Slog.w(TAG, "Failed trying to unstop package "
16641                        + app.packageName + ": " + e);
16642            }
16643
16644            BackupRecord r = new BackupRecord(ss, app, backupMode);
16645            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16646                    ? new ComponentName(app.packageName, app.backupAgentName)
16647                    : new ComponentName("android", "FullBackupAgent");
16648            // startProcessLocked() returns existing proc's record if it's already running
16649            ProcessRecord proc = startProcessLocked(app.processName, app,
16650                    false, 0, "backup", hostingName, false, false, false);
16651            if (proc == null) {
16652                Slog.e(TAG, "Unable to start backup agent process " + r);
16653                return false;
16654            }
16655
16656            r.app = proc;
16657            mBackupTarget = r;
16658            mBackupAppName = app.packageName;
16659
16660            // Try not to kill the process during backup
16661            updateOomAdjLocked(proc);
16662
16663            // If the process is already attached, schedule the creation of the backup agent now.
16664            // If it is not yet live, this will be done when it attaches to the framework.
16665            if (proc.thread != null) {
16666                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16667                try {
16668                    proc.thread.scheduleCreateBackupAgent(app,
16669                            compatibilityInfoForPackageLocked(app), backupMode);
16670                } catch (RemoteException e) {
16671                    // Will time out on the backup manager side
16672                }
16673            } else {
16674                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16675            }
16676            // Invariants: at this point, the target app process exists and the application
16677            // is either already running or in the process of coming up.  mBackupTarget and
16678            // mBackupAppName describe the app, so that when it binds back to the AM we
16679            // know that it's scheduled for a backup-agent operation.
16680        }
16681
16682        return true;
16683    }
16684
16685    @Override
16686    public void clearPendingBackup() {
16687        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16688        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16689
16690        synchronized (this) {
16691            mBackupTarget = null;
16692            mBackupAppName = null;
16693        }
16694    }
16695
16696    // A backup agent has just come up
16697    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16698        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16699                + " = " + agent);
16700
16701        synchronized(this) {
16702            if (!agentPackageName.equals(mBackupAppName)) {
16703                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16704                return;
16705            }
16706        }
16707
16708        long oldIdent = Binder.clearCallingIdentity();
16709        try {
16710            IBackupManager bm = IBackupManager.Stub.asInterface(
16711                    ServiceManager.getService(Context.BACKUP_SERVICE));
16712            bm.agentConnected(agentPackageName, agent);
16713        } catch (RemoteException e) {
16714            // can't happen; the backup manager service is local
16715        } catch (Exception e) {
16716            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16717            e.printStackTrace();
16718        } finally {
16719            Binder.restoreCallingIdentity(oldIdent);
16720        }
16721    }
16722
16723    // done with this agent
16724    public void unbindBackupAgent(ApplicationInfo appInfo) {
16725        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16726        if (appInfo == null) {
16727            Slog.w(TAG, "unbind backup agent for null app");
16728            return;
16729        }
16730
16731        synchronized(this) {
16732            try {
16733                if (mBackupAppName == null) {
16734                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16735                    return;
16736                }
16737
16738                if (!mBackupAppName.equals(appInfo.packageName)) {
16739                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16740                    return;
16741                }
16742
16743                // Not backing this app up any more; reset its OOM adjustment
16744                final ProcessRecord proc = mBackupTarget.app;
16745                updateOomAdjLocked(proc);
16746
16747                // If the app crashed during backup, 'thread' will be null here
16748                if (proc.thread != null) {
16749                    try {
16750                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16751                                compatibilityInfoForPackageLocked(appInfo));
16752                    } catch (Exception e) {
16753                        Slog.e(TAG, "Exception when unbinding backup agent:");
16754                        e.printStackTrace();
16755                    }
16756                }
16757            } finally {
16758                mBackupTarget = null;
16759                mBackupAppName = null;
16760            }
16761        }
16762    }
16763    // =========================================================
16764    // BROADCASTS
16765    // =========================================================
16766
16767    boolean isPendingBroadcastProcessLocked(int pid) {
16768        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16769                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16770    }
16771
16772    void skipPendingBroadcastLocked(int pid) {
16773            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16774            for (BroadcastQueue queue : mBroadcastQueues) {
16775                queue.skipPendingBroadcastLocked(pid);
16776            }
16777    }
16778
16779    // The app just attached; send any pending broadcasts that it should receive
16780    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16781        boolean didSomething = false;
16782        for (BroadcastQueue queue : mBroadcastQueues) {
16783            didSomething |= queue.sendPendingBroadcastsLocked(app);
16784        }
16785        return didSomething;
16786    }
16787
16788    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16789            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16790        enforceNotIsolatedCaller("registerReceiver");
16791        ArrayList<Intent> stickyIntents = null;
16792        ProcessRecord callerApp = null;
16793        int callingUid;
16794        int callingPid;
16795        synchronized(this) {
16796            if (caller != null) {
16797                callerApp = getRecordForAppLocked(caller);
16798                if (callerApp == null) {
16799                    throw new SecurityException(
16800                            "Unable to find app for caller " + caller
16801                            + " (pid=" + Binder.getCallingPid()
16802                            + ") when registering receiver " + receiver);
16803                }
16804                if (callerApp.info.uid != Process.SYSTEM_UID &&
16805                        !callerApp.pkgList.containsKey(callerPackage) &&
16806                        !"android".equals(callerPackage)) {
16807                    throw new SecurityException("Given caller package " + callerPackage
16808                            + " is not running in process " + callerApp);
16809                }
16810                callingUid = callerApp.info.uid;
16811                callingPid = callerApp.pid;
16812            } else {
16813                callerPackage = null;
16814                callingUid = Binder.getCallingUid();
16815                callingPid = Binder.getCallingPid();
16816            }
16817
16818            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16819                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16820
16821            Iterator<String> actions = filter.actionsIterator();
16822            if (actions == null) {
16823                ArrayList<String> noAction = new ArrayList<String>(1);
16824                noAction.add(null);
16825                actions = noAction.iterator();
16826            }
16827
16828            // Collect stickies of users
16829            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16830            while (actions.hasNext()) {
16831                String action = actions.next();
16832                for (int id : userIds) {
16833                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16834                    if (stickies != null) {
16835                        ArrayList<Intent> intents = stickies.get(action);
16836                        if (intents != null) {
16837                            if (stickyIntents == null) {
16838                                stickyIntents = new ArrayList<Intent>();
16839                            }
16840                            stickyIntents.addAll(intents);
16841                        }
16842                    }
16843                }
16844            }
16845        }
16846
16847        ArrayList<Intent> allSticky = null;
16848        if (stickyIntents != null) {
16849            final ContentResolver resolver = mContext.getContentResolver();
16850            // Look for any matching sticky broadcasts...
16851            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16852                Intent intent = stickyIntents.get(i);
16853                // If intent has scheme "content", it will need to acccess
16854                // provider that needs to lock mProviderMap in ActivityThread
16855                // and also it may need to wait application response, so we
16856                // cannot lock ActivityManagerService here.
16857                if (filter.match(resolver, intent, true, TAG) >= 0) {
16858                    if (allSticky == null) {
16859                        allSticky = new ArrayList<Intent>();
16860                    }
16861                    allSticky.add(intent);
16862                }
16863            }
16864        }
16865
16866        // The first sticky in the list is returned directly back to the client.
16867        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16868        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16869        if (receiver == null) {
16870            return sticky;
16871        }
16872
16873        synchronized (this) {
16874            if (callerApp != null && (callerApp.thread == null
16875                    || callerApp.thread.asBinder() != caller.asBinder())) {
16876                // Original caller already died
16877                return null;
16878            }
16879            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16880            if (rl == null) {
16881                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16882                        userId, receiver);
16883                if (rl.app != null) {
16884                    rl.app.receivers.add(rl);
16885                } else {
16886                    try {
16887                        receiver.asBinder().linkToDeath(rl, 0);
16888                    } catch (RemoteException e) {
16889                        return sticky;
16890                    }
16891                    rl.linkedToDeath = true;
16892                }
16893                mRegisteredReceivers.put(receiver.asBinder(), rl);
16894            } else if (rl.uid != callingUid) {
16895                throw new IllegalArgumentException(
16896                        "Receiver requested to register for uid " + callingUid
16897                        + " was previously registered for uid " + rl.uid);
16898            } else if (rl.pid != callingPid) {
16899                throw new IllegalArgumentException(
16900                        "Receiver requested to register for pid " + callingPid
16901                        + " was previously registered for pid " + rl.pid);
16902            } else if (rl.userId != userId) {
16903                throw new IllegalArgumentException(
16904                        "Receiver requested to register for user " + userId
16905                        + " was previously registered for user " + rl.userId);
16906            }
16907            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16908                    permission, callingUid, userId);
16909            rl.add(bf);
16910            if (!bf.debugCheck()) {
16911                Slog.w(TAG, "==> For Dynamic broadcast");
16912            }
16913            mReceiverResolver.addFilter(bf);
16914
16915            // Enqueue broadcasts for all existing stickies that match
16916            // this filter.
16917            if (allSticky != null) {
16918                ArrayList receivers = new ArrayList();
16919                receivers.add(bf);
16920
16921                final int stickyCount = allSticky.size();
16922                for (int i = 0; i < stickyCount; i++) {
16923                    Intent intent = allSticky.get(i);
16924                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16925                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16926                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16927                            null, 0, null, null, false, true, true, -1);
16928                    queue.enqueueParallelBroadcastLocked(r);
16929                    queue.scheduleBroadcastsLocked();
16930                }
16931            }
16932
16933            return sticky;
16934        }
16935    }
16936
16937    public void unregisterReceiver(IIntentReceiver receiver) {
16938        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16939
16940        final long origId = Binder.clearCallingIdentity();
16941        try {
16942            boolean doTrim = false;
16943
16944            synchronized(this) {
16945                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16946                if (rl != null) {
16947                    final BroadcastRecord r = rl.curBroadcast;
16948                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16949                        final boolean doNext = r.queue.finishReceiverLocked(
16950                                r, r.resultCode, r.resultData, r.resultExtras,
16951                                r.resultAbort, false);
16952                        if (doNext) {
16953                            doTrim = true;
16954                            r.queue.processNextBroadcast(false);
16955                        }
16956                    }
16957
16958                    if (rl.app != null) {
16959                        rl.app.receivers.remove(rl);
16960                    }
16961                    removeReceiverLocked(rl);
16962                    if (rl.linkedToDeath) {
16963                        rl.linkedToDeath = false;
16964                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16965                    }
16966                }
16967            }
16968
16969            // If we actually concluded any broadcasts, we might now be able
16970            // to trim the recipients' apps from our working set
16971            if (doTrim) {
16972                trimApplications();
16973                return;
16974            }
16975
16976        } finally {
16977            Binder.restoreCallingIdentity(origId);
16978        }
16979    }
16980
16981    void removeReceiverLocked(ReceiverList rl) {
16982        mRegisteredReceivers.remove(rl.receiver.asBinder());
16983        for (int i = rl.size() - 1; i >= 0; i--) {
16984            mReceiverResolver.removeFilter(rl.get(i));
16985        }
16986    }
16987
16988    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16989        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16990            ProcessRecord r = mLruProcesses.get(i);
16991            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16992                try {
16993                    r.thread.dispatchPackageBroadcast(cmd, packages);
16994                } catch (RemoteException ex) {
16995                }
16996            }
16997        }
16998    }
16999
17000    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17001            int callingUid, int[] users) {
17002        // TODO: come back and remove this assumption to triage all broadcasts
17003        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17004
17005        List<ResolveInfo> receivers = null;
17006        try {
17007            HashSet<ComponentName> singleUserReceivers = null;
17008            boolean scannedFirstReceivers = false;
17009            for (int user : users) {
17010                // Skip users that have Shell restrictions, with exception of always permitted
17011                // Shell broadcasts
17012                if (callingUid == Process.SHELL_UID
17013                        && mUserController.hasUserRestriction(
17014                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17015                        && !isPermittedShellBroadcast(intent)) {
17016                    continue;
17017                }
17018                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17019                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17020                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17021                    // If this is not the system user, we need to check for
17022                    // any receivers that should be filtered out.
17023                    for (int i=0; i<newReceivers.size(); i++) {
17024                        ResolveInfo ri = newReceivers.get(i);
17025                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17026                            newReceivers.remove(i);
17027                            i--;
17028                        }
17029                    }
17030                }
17031                if (newReceivers != null && newReceivers.size() == 0) {
17032                    newReceivers = null;
17033                }
17034                if (receivers == null) {
17035                    receivers = newReceivers;
17036                } else if (newReceivers != null) {
17037                    // We need to concatenate the additional receivers
17038                    // found with what we have do far.  This would be easy,
17039                    // but we also need to de-dup any receivers that are
17040                    // singleUser.
17041                    if (!scannedFirstReceivers) {
17042                        // Collect any single user receivers we had already retrieved.
17043                        scannedFirstReceivers = true;
17044                        for (int i=0; i<receivers.size(); i++) {
17045                            ResolveInfo ri = receivers.get(i);
17046                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17047                                ComponentName cn = new ComponentName(
17048                                        ri.activityInfo.packageName, ri.activityInfo.name);
17049                                if (singleUserReceivers == null) {
17050                                    singleUserReceivers = new HashSet<ComponentName>();
17051                                }
17052                                singleUserReceivers.add(cn);
17053                            }
17054                        }
17055                    }
17056                    // Add the new results to the existing results, tracking
17057                    // and de-dupping single user receivers.
17058                    for (int i=0; i<newReceivers.size(); i++) {
17059                        ResolveInfo ri = newReceivers.get(i);
17060                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17061                            ComponentName cn = new ComponentName(
17062                                    ri.activityInfo.packageName, ri.activityInfo.name);
17063                            if (singleUserReceivers == null) {
17064                                singleUserReceivers = new HashSet<ComponentName>();
17065                            }
17066                            if (!singleUserReceivers.contains(cn)) {
17067                                singleUserReceivers.add(cn);
17068                                receivers.add(ri);
17069                            }
17070                        } else {
17071                            receivers.add(ri);
17072                        }
17073                    }
17074                }
17075            }
17076        } catch (RemoteException ex) {
17077            // pm is in same process, this will never happen.
17078        }
17079        return receivers;
17080    }
17081
17082    private boolean isPermittedShellBroadcast(Intent intent) {
17083        // remote bugreport should always be allowed to be taken
17084        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17085    }
17086
17087    final int broadcastIntentLocked(ProcessRecord callerApp,
17088            String callerPackage, Intent intent, String resolvedType,
17089            IIntentReceiver resultTo, int resultCode, String resultData,
17090            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17091            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17092        intent = new Intent(intent);
17093
17094        // By default broadcasts do not go to stopped apps.
17095        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17096
17097        // If we have not finished booting, don't allow this to launch new processes.
17098        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17099            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17100        }
17101
17102        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17103                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17104                + " ordered=" + ordered + " userid=" + userId);
17105        if ((resultTo != null) && !ordered) {
17106            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17107        }
17108
17109        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17110                ALLOW_NON_FULL, "broadcast", callerPackage);
17111
17112        // Make sure that the user who is receiving this broadcast is running.
17113        // If not, we will just skip it. Make an exception for shutdown broadcasts
17114        // and upgrade steps.
17115
17116        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17117            if ((callingUid != Process.SYSTEM_UID
17118                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17119                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17120                Slog.w(TAG, "Skipping broadcast of " + intent
17121                        + ": user " + userId + " is stopped");
17122                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17123            }
17124        }
17125
17126        BroadcastOptions brOptions = null;
17127        if (bOptions != null) {
17128            brOptions = new BroadcastOptions(bOptions);
17129            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17130                // See if the caller is allowed to do this.  Note we are checking against
17131                // the actual real caller (not whoever provided the operation as say a
17132                // PendingIntent), because that who is actually supplied the arguments.
17133                if (checkComponentPermission(
17134                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17135                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17136                        != PackageManager.PERMISSION_GRANTED) {
17137                    String msg = "Permission Denial: " + intent.getAction()
17138                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17139                            + ", uid=" + callingUid + ")"
17140                            + " requires "
17141                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17142                    Slog.w(TAG, msg);
17143                    throw new SecurityException(msg);
17144                }
17145            }
17146        }
17147
17148        // Verify that protected broadcasts are only being sent by system code,
17149        // and that system code is only sending protected broadcasts.
17150        final String action = intent.getAction();
17151        final boolean isProtectedBroadcast;
17152        try {
17153            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17154        } catch (RemoteException e) {
17155            Slog.w(TAG, "Remote exception", e);
17156            return ActivityManager.BROADCAST_SUCCESS;
17157        }
17158
17159        final boolean isCallerSystem;
17160        switch (UserHandle.getAppId(callingUid)) {
17161            case Process.ROOT_UID:
17162            case Process.SYSTEM_UID:
17163            case Process.PHONE_UID:
17164            case Process.BLUETOOTH_UID:
17165            case Process.NFC_UID:
17166                isCallerSystem = true;
17167                break;
17168            default:
17169                isCallerSystem = (callerApp != null) && callerApp.persistent;
17170                break;
17171        }
17172
17173        if (isCallerSystem) {
17174            if (isProtectedBroadcast
17175                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17176                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17177                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17178                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17179                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17180                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17181                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17182                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17183                // Broadcast is either protected, or it's a public action that
17184                // we've relaxed, so it's fine for system internals to send.
17185            } else {
17186                // The vast majority of broadcasts sent from system internals
17187                // should be protected to avoid security holes, so yell loudly
17188                // to ensure we examine these cases.
17189                Log.wtf(TAG, "Sending non-protected broadcast " + action
17190                        + " from system", new Throwable());
17191            }
17192
17193        } else {
17194            if (isProtectedBroadcast) {
17195                String msg = "Permission Denial: not allowed to send broadcast "
17196                        + action + " from pid="
17197                        + callingPid + ", uid=" + callingUid;
17198                Slog.w(TAG, msg);
17199                throw new SecurityException(msg);
17200
17201            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17202                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17203                // Special case for compatibility: we don't want apps to send this,
17204                // but historically it has not been protected and apps may be using it
17205                // to poke their own app widget.  So, instead of making it protected,
17206                // just limit it to the caller.
17207                if (callerPackage == null) {
17208                    String msg = "Permission Denial: not allowed to send broadcast "
17209                            + action + " from unknown caller.";
17210                    Slog.w(TAG, msg);
17211                    throw new SecurityException(msg);
17212                } else if (intent.getComponent() != null) {
17213                    // They are good enough to send to an explicit component...  verify
17214                    // it is being sent to the calling app.
17215                    if (!intent.getComponent().getPackageName().equals(
17216                            callerPackage)) {
17217                        String msg = "Permission Denial: not allowed to send broadcast "
17218                                + action + " to "
17219                                + intent.getComponent().getPackageName() + " from "
17220                                + callerPackage;
17221                        Slog.w(TAG, msg);
17222                        throw new SecurityException(msg);
17223                    }
17224                } else {
17225                    // Limit broadcast to their own package.
17226                    intent.setPackage(callerPackage);
17227                }
17228            }
17229        }
17230
17231        if (action != null) {
17232            switch (action) {
17233                case Intent.ACTION_UID_REMOVED:
17234                case Intent.ACTION_PACKAGE_REMOVED:
17235                case Intent.ACTION_PACKAGE_CHANGED:
17236                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17237                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17238                case Intent.ACTION_PACKAGES_SUSPENDED:
17239                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17240                    // Handle special intents: if this broadcast is from the package
17241                    // manager about a package being removed, we need to remove all of
17242                    // its activities from the history stack.
17243                    if (checkComponentPermission(
17244                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17245                            callingPid, callingUid, -1, true)
17246                            != PackageManager.PERMISSION_GRANTED) {
17247                        String msg = "Permission Denial: " + intent.getAction()
17248                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17249                                + ", uid=" + callingUid + ")"
17250                                + " requires "
17251                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17252                        Slog.w(TAG, msg);
17253                        throw new SecurityException(msg);
17254                    }
17255                    switch (action) {
17256                        case Intent.ACTION_UID_REMOVED:
17257                            final Bundle intentExtras = intent.getExtras();
17258                            final int uid = intentExtras != null
17259                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17260                            if (uid >= 0) {
17261                                mBatteryStatsService.removeUid(uid);
17262                                mAppOpsService.uidRemoved(uid);
17263                            }
17264                            break;
17265                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17266                            // If resources are unavailable just force stop all those packages
17267                            // and flush the attribute cache as well.
17268                            String list[] =
17269                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17270                            if (list != null && list.length > 0) {
17271                                for (int i = 0; i < list.length; i++) {
17272                                    forceStopPackageLocked(list[i], -1, false, true, true,
17273                                            false, false, userId, "storage unmount");
17274                                }
17275                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17276                                sendPackageBroadcastLocked(
17277                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17278                                        userId);
17279                            }
17280                            break;
17281                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17282                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17283                            break;
17284                        case Intent.ACTION_PACKAGE_REMOVED:
17285                        case Intent.ACTION_PACKAGE_CHANGED:
17286                            Uri data = intent.getData();
17287                            String ssp;
17288                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17289                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17290                                final boolean replacing =
17291                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17292                                final boolean killProcess =
17293                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17294                                final boolean fullUninstall = removed && !replacing;
17295                                if (killProcess) {
17296                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17297                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17298                                            false, true, true, false, fullUninstall, userId,
17299                                            removed ? "pkg removed" : "pkg changed");
17300                                }
17301                                if (removed) {
17302                                    final int cmd = killProcess
17303                                            ? IApplicationThread.PACKAGE_REMOVED
17304                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17305                                    sendPackageBroadcastLocked(cmd,
17306                                            new String[] {ssp}, userId);
17307                                    if (fullUninstall) {
17308                                        mAppOpsService.packageRemoved(
17309                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17310
17311                                        // Remove all permissions granted from/to this package
17312                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17313
17314                                        removeTasksByPackageNameLocked(ssp, userId);
17315                                        mBatteryStatsService.notePackageUninstalled(ssp);
17316                                    }
17317                                } else {
17318                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17319                                            intent.getStringArrayExtra(
17320                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17321                                }
17322                            }
17323                            break;
17324                        case Intent.ACTION_PACKAGES_SUSPENDED:
17325                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17326                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17327                                    intent.getAction());
17328                            final String[] packageNames = intent.getStringArrayExtra(
17329                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17330                            final int userHandle = intent.getIntExtra(
17331                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17332
17333                            synchronized(ActivityManagerService.this) {
17334                                mRecentTasks.onPackagesSuspendedChanged(
17335                                        packageNames, suspended, userHandle);
17336                            }
17337                            break;
17338                    }
17339                    break;
17340                case Intent.ACTION_PACKAGE_REPLACED:
17341                {
17342                    final Uri data = intent.getData();
17343                    final String ssp;
17344                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17345                        final ApplicationInfo aInfo =
17346                                getPackageManagerInternalLocked().getApplicationInfo(
17347                                        ssp,
17348                                        userId);
17349                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17350                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17351                                new String[] {ssp}, userId);
17352                    }
17353                    break;
17354                }
17355                case Intent.ACTION_PACKAGE_ADDED:
17356                {
17357                    // Special case for adding a package: by default turn on compatibility mode.
17358                    Uri data = intent.getData();
17359                    String ssp;
17360                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17361                        final boolean replacing =
17362                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17363                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17364
17365                        try {
17366                            ApplicationInfo ai = AppGlobals.getPackageManager().
17367                                    getApplicationInfo(ssp, 0, 0);
17368                            mBatteryStatsService.notePackageInstalled(ssp,
17369                                    ai != null ? ai.versionCode : 0);
17370                        } catch (RemoteException e) {
17371                        }
17372                    }
17373                    break;
17374                }
17375                case Intent.ACTION_TIMEZONE_CHANGED:
17376                    // If this is the time zone changed action, queue up a message that will reset
17377                    // the timezone of all currently running processes. This message will get
17378                    // queued up before the broadcast happens.
17379                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17380                    break;
17381                case Intent.ACTION_TIME_CHANGED:
17382                    // If the user set the time, let all running processes know.
17383                    final int is24Hour =
17384                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17385                                    : 0;
17386                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17387                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17388                    synchronized (stats) {
17389                        stats.noteCurrentTimeChangedLocked();
17390                    }
17391                    break;
17392                case Intent.ACTION_CLEAR_DNS_CACHE:
17393                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17394                    break;
17395                case Proxy.PROXY_CHANGE_ACTION:
17396                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17397                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17398                    break;
17399                case android.hardware.Camera.ACTION_NEW_PICTURE:
17400                case android.hardware.Camera.ACTION_NEW_VIDEO:
17401                    // These broadcasts are no longer allowed by the system, since they can
17402                    // cause significant thrashing at a crictical point (using the camera).
17403                    // Apps should use JobScehduler to monitor for media provider changes.
17404                    Slog.w(TAG, action + " no longer allowed; dropping from "
17405                            + UserHandle.formatUid(callingUid));
17406                    // Lie; we don't want to crash the app.
17407                    return ActivityManager.BROADCAST_SUCCESS;
17408            }
17409        }
17410
17411        // Add to the sticky list if requested.
17412        if (sticky) {
17413            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17414                    callingPid, callingUid)
17415                    != PackageManager.PERMISSION_GRANTED) {
17416                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17417                        + callingPid + ", uid=" + callingUid
17418                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17419                Slog.w(TAG, msg);
17420                throw new SecurityException(msg);
17421            }
17422            if (requiredPermissions != null && requiredPermissions.length > 0) {
17423                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17424                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17425                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17426            }
17427            if (intent.getComponent() != null) {
17428                throw new SecurityException(
17429                        "Sticky broadcasts can't target a specific component");
17430            }
17431            // We use userId directly here, since the "all" target is maintained
17432            // as a separate set of sticky broadcasts.
17433            if (userId != UserHandle.USER_ALL) {
17434                // But first, if this is not a broadcast to all users, then
17435                // make sure it doesn't conflict with an existing broadcast to
17436                // all users.
17437                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17438                        UserHandle.USER_ALL);
17439                if (stickies != null) {
17440                    ArrayList<Intent> list = stickies.get(intent.getAction());
17441                    if (list != null) {
17442                        int N = list.size();
17443                        int i;
17444                        for (i=0; i<N; i++) {
17445                            if (intent.filterEquals(list.get(i))) {
17446                                throw new IllegalArgumentException(
17447                                        "Sticky broadcast " + intent + " for user "
17448                                        + userId + " conflicts with existing global broadcast");
17449                            }
17450                        }
17451                    }
17452                }
17453            }
17454            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17455            if (stickies == null) {
17456                stickies = new ArrayMap<>();
17457                mStickyBroadcasts.put(userId, stickies);
17458            }
17459            ArrayList<Intent> list = stickies.get(intent.getAction());
17460            if (list == null) {
17461                list = new ArrayList<>();
17462                stickies.put(intent.getAction(), list);
17463            }
17464            final int stickiesCount = list.size();
17465            int i;
17466            for (i = 0; i < stickiesCount; i++) {
17467                if (intent.filterEquals(list.get(i))) {
17468                    // This sticky already exists, replace it.
17469                    list.set(i, new Intent(intent));
17470                    break;
17471                }
17472            }
17473            if (i >= stickiesCount) {
17474                list.add(new Intent(intent));
17475            }
17476        }
17477
17478        int[] users;
17479        if (userId == UserHandle.USER_ALL) {
17480            // Caller wants broadcast to go to all started users.
17481            users = mUserController.getStartedUserArrayLocked();
17482        } else {
17483            // Caller wants broadcast to go to one specific user.
17484            users = new int[] {userId};
17485        }
17486
17487        // Figure out who all will receive this broadcast.
17488        List receivers = null;
17489        List<BroadcastFilter> registeredReceivers = null;
17490        // Need to resolve the intent to interested receivers...
17491        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17492                 == 0) {
17493            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17494        }
17495        if (intent.getComponent() == null) {
17496            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17497                // Query one target user at a time, excluding shell-restricted users
17498                for (int i = 0; i < users.length; i++) {
17499                    if (mUserController.hasUserRestriction(
17500                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17501                        continue;
17502                    }
17503                    List<BroadcastFilter> registeredReceiversForUser =
17504                            mReceiverResolver.queryIntent(intent,
17505                                    resolvedType, false, users[i]);
17506                    if (registeredReceivers == null) {
17507                        registeredReceivers = registeredReceiversForUser;
17508                    } else if (registeredReceiversForUser != null) {
17509                        registeredReceivers.addAll(registeredReceiversForUser);
17510                    }
17511                }
17512            } else {
17513                registeredReceivers = mReceiverResolver.queryIntent(intent,
17514                        resolvedType, false, userId);
17515            }
17516        }
17517
17518        final boolean replacePending =
17519                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17520
17521        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17522                + " replacePending=" + replacePending);
17523
17524        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17525        if (!ordered && NR > 0) {
17526            // If we are not serializing this broadcast, then send the
17527            // registered receivers separately so they don't wait for the
17528            // components to be launched.
17529            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17530            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17531                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17532                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17533                    resultExtras, ordered, sticky, false, userId);
17534            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17535            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17536            if (!replaced) {
17537                queue.enqueueParallelBroadcastLocked(r);
17538                queue.scheduleBroadcastsLocked();
17539            }
17540            registeredReceivers = null;
17541            NR = 0;
17542        }
17543
17544        // Merge into one list.
17545        int ir = 0;
17546        if (receivers != null) {
17547            // A special case for PACKAGE_ADDED: do not allow the package
17548            // being added to see this broadcast.  This prevents them from
17549            // using this as a back door to get run as soon as they are
17550            // installed.  Maybe in the future we want to have a special install
17551            // broadcast or such for apps, but we'd like to deliberately make
17552            // this decision.
17553            String skipPackages[] = null;
17554            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17555                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17556                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17557                Uri data = intent.getData();
17558                if (data != null) {
17559                    String pkgName = data.getSchemeSpecificPart();
17560                    if (pkgName != null) {
17561                        skipPackages = new String[] { pkgName };
17562                    }
17563                }
17564            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17565                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17566            }
17567            if (skipPackages != null && (skipPackages.length > 0)) {
17568                for (String skipPackage : skipPackages) {
17569                    if (skipPackage != null) {
17570                        int NT = receivers.size();
17571                        for (int it=0; it<NT; it++) {
17572                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17573                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17574                                receivers.remove(it);
17575                                it--;
17576                                NT--;
17577                            }
17578                        }
17579                    }
17580                }
17581            }
17582
17583            int NT = receivers != null ? receivers.size() : 0;
17584            int it = 0;
17585            ResolveInfo curt = null;
17586            BroadcastFilter curr = null;
17587            while (it < NT && ir < NR) {
17588                if (curt == null) {
17589                    curt = (ResolveInfo)receivers.get(it);
17590                }
17591                if (curr == null) {
17592                    curr = registeredReceivers.get(ir);
17593                }
17594                if (curr.getPriority() >= curt.priority) {
17595                    // Insert this broadcast record into the final list.
17596                    receivers.add(it, curr);
17597                    ir++;
17598                    curr = null;
17599                    it++;
17600                    NT++;
17601                } else {
17602                    // Skip to the next ResolveInfo in the final list.
17603                    it++;
17604                    curt = null;
17605                }
17606            }
17607        }
17608        while (ir < NR) {
17609            if (receivers == null) {
17610                receivers = new ArrayList();
17611            }
17612            receivers.add(registeredReceivers.get(ir));
17613            ir++;
17614        }
17615
17616        if ((receivers != null && receivers.size() > 0)
17617                || resultTo != null) {
17618            BroadcastQueue queue = broadcastQueueForIntent(intent);
17619            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17620                    callerPackage, callingPid, callingUid, resolvedType,
17621                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17622                    resultData, resultExtras, ordered, sticky, false, userId);
17623
17624            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17625                    + ": prev had " + queue.mOrderedBroadcasts.size());
17626            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17627                    "Enqueueing broadcast " + r.intent.getAction());
17628
17629            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17630            if (!replaced) {
17631                queue.enqueueOrderedBroadcastLocked(r);
17632                queue.scheduleBroadcastsLocked();
17633            }
17634        }
17635
17636        return ActivityManager.BROADCAST_SUCCESS;
17637    }
17638
17639    final Intent verifyBroadcastLocked(Intent intent) {
17640        // Refuse possible leaked file descriptors
17641        if (intent != null && intent.hasFileDescriptors() == true) {
17642            throw new IllegalArgumentException("File descriptors passed in Intent");
17643        }
17644
17645        int flags = intent.getFlags();
17646
17647        if (!mProcessesReady) {
17648            // if the caller really truly claims to know what they're doing, go
17649            // ahead and allow the broadcast without launching any receivers
17650            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17651                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17652            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17653                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17654                        + " before boot completion");
17655                throw new IllegalStateException("Cannot broadcast before boot completed");
17656            }
17657        }
17658
17659        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17660            throw new IllegalArgumentException(
17661                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17662        }
17663
17664        return intent;
17665    }
17666
17667    public final int broadcastIntent(IApplicationThread caller,
17668            Intent intent, String resolvedType, IIntentReceiver resultTo,
17669            int resultCode, String resultData, Bundle resultExtras,
17670            String[] requiredPermissions, int appOp, Bundle bOptions,
17671            boolean serialized, boolean sticky, int userId) {
17672        enforceNotIsolatedCaller("broadcastIntent");
17673        synchronized(this) {
17674            intent = verifyBroadcastLocked(intent);
17675
17676            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17677            final int callingPid = Binder.getCallingPid();
17678            final int callingUid = Binder.getCallingUid();
17679            final long origId = Binder.clearCallingIdentity();
17680            int res = broadcastIntentLocked(callerApp,
17681                    callerApp != null ? callerApp.info.packageName : null,
17682                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17683                    requiredPermissions, appOp, bOptions, serialized, sticky,
17684                    callingPid, callingUid, userId);
17685            Binder.restoreCallingIdentity(origId);
17686            return res;
17687        }
17688    }
17689
17690
17691    int broadcastIntentInPackage(String packageName, int uid,
17692            Intent intent, String resolvedType, IIntentReceiver resultTo,
17693            int resultCode, String resultData, Bundle resultExtras,
17694            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17695            int userId) {
17696        synchronized(this) {
17697            intent = verifyBroadcastLocked(intent);
17698
17699            final long origId = Binder.clearCallingIdentity();
17700            String[] requiredPermissions = requiredPermission == null ? null
17701                    : new String[] {requiredPermission};
17702            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17703                    resultTo, resultCode, resultData, resultExtras,
17704                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17705                    sticky, -1, uid, userId);
17706            Binder.restoreCallingIdentity(origId);
17707            return res;
17708        }
17709    }
17710
17711    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17712        // Refuse possible leaked file descriptors
17713        if (intent != null && intent.hasFileDescriptors() == true) {
17714            throw new IllegalArgumentException("File descriptors passed in Intent");
17715        }
17716
17717        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17718                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17719
17720        synchronized(this) {
17721            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17722                    != PackageManager.PERMISSION_GRANTED) {
17723                String msg = "Permission Denial: unbroadcastIntent() from pid="
17724                        + Binder.getCallingPid()
17725                        + ", uid=" + Binder.getCallingUid()
17726                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17727                Slog.w(TAG, msg);
17728                throw new SecurityException(msg);
17729            }
17730            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17731            if (stickies != null) {
17732                ArrayList<Intent> list = stickies.get(intent.getAction());
17733                if (list != null) {
17734                    int N = list.size();
17735                    int i;
17736                    for (i=0; i<N; i++) {
17737                        if (intent.filterEquals(list.get(i))) {
17738                            list.remove(i);
17739                            break;
17740                        }
17741                    }
17742                    if (list.size() <= 0) {
17743                        stickies.remove(intent.getAction());
17744                    }
17745                }
17746                if (stickies.size() <= 0) {
17747                    mStickyBroadcasts.remove(userId);
17748                }
17749            }
17750        }
17751    }
17752
17753    void backgroundServicesFinishedLocked(int userId) {
17754        for (BroadcastQueue queue : mBroadcastQueues) {
17755            queue.backgroundServicesFinishedLocked(userId);
17756        }
17757    }
17758
17759    public void finishReceiver(IBinder who, int resultCode, String resultData,
17760            Bundle resultExtras, boolean resultAbort, int flags) {
17761        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17762
17763        // Refuse possible leaked file descriptors
17764        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17765            throw new IllegalArgumentException("File descriptors passed in Bundle");
17766        }
17767
17768        final long origId = Binder.clearCallingIdentity();
17769        try {
17770            boolean doNext = false;
17771            BroadcastRecord r;
17772
17773            synchronized(this) {
17774                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17775                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17776                r = queue.getMatchingOrderedReceiver(who);
17777                if (r != null) {
17778                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17779                        resultData, resultExtras, resultAbort, true);
17780                }
17781            }
17782
17783            if (doNext) {
17784                r.queue.processNextBroadcast(false);
17785            }
17786            trimApplications();
17787        } finally {
17788            Binder.restoreCallingIdentity(origId);
17789        }
17790    }
17791
17792    // =========================================================
17793    // INSTRUMENTATION
17794    // =========================================================
17795
17796    public boolean startInstrumentation(ComponentName className,
17797            String profileFile, int flags, Bundle arguments,
17798            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17799            int userId, String abiOverride) {
17800        enforceNotIsolatedCaller("startInstrumentation");
17801        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17802                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17803        // Refuse possible leaked file descriptors
17804        if (arguments != null && arguments.hasFileDescriptors()) {
17805            throw new IllegalArgumentException("File descriptors passed in Bundle");
17806        }
17807
17808        synchronized(this) {
17809            InstrumentationInfo ii = null;
17810            ApplicationInfo ai = null;
17811            try {
17812                ii = mContext.getPackageManager().getInstrumentationInfo(
17813                    className, STOCK_PM_FLAGS);
17814                ai = AppGlobals.getPackageManager().getApplicationInfo(
17815                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17816            } catch (PackageManager.NameNotFoundException e) {
17817            } catch (RemoteException e) {
17818            }
17819            if (ii == null) {
17820                reportStartInstrumentationFailureLocked(watcher, className,
17821                        "Unable to find instrumentation info for: " + className);
17822                return false;
17823            }
17824            if (ai == null) {
17825                reportStartInstrumentationFailureLocked(watcher, className,
17826                        "Unable to find instrumentation target package: " + ii.targetPackage);
17827                return false;
17828            }
17829            if (!ai.hasCode()) {
17830                reportStartInstrumentationFailureLocked(watcher, className,
17831                        "Instrumentation target has no code: " + ii.targetPackage);
17832                return false;
17833            }
17834
17835            int match = mContext.getPackageManager().checkSignatures(
17836                    ii.targetPackage, ii.packageName);
17837            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17838                String msg = "Permission Denial: starting instrumentation "
17839                        + className + " from pid="
17840                        + Binder.getCallingPid()
17841                        + ", uid=" + Binder.getCallingPid()
17842                        + " not allowed because package " + ii.packageName
17843                        + " does not have a signature matching the target "
17844                        + ii.targetPackage;
17845                reportStartInstrumentationFailureLocked(watcher, className, msg);
17846                throw new SecurityException(msg);
17847            }
17848
17849            final long origId = Binder.clearCallingIdentity();
17850            // Instrumentation can kill and relaunch even persistent processes
17851            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17852                    "start instr");
17853            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17854            app.instrumentationClass = className;
17855            app.instrumentationInfo = ai;
17856            app.instrumentationProfileFile = profileFile;
17857            app.instrumentationArguments = arguments;
17858            app.instrumentationWatcher = watcher;
17859            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17860            app.instrumentationResultClass = className;
17861            Binder.restoreCallingIdentity(origId);
17862        }
17863
17864        return true;
17865    }
17866
17867    /**
17868     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17869     * error to the logs, but if somebody is watching, send the report there too.  This enables
17870     * the "am" command to report errors with more information.
17871     *
17872     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17873     * @param cn The component name of the instrumentation.
17874     * @param report The error report.
17875     */
17876    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17877            ComponentName cn, String report) {
17878        Slog.w(TAG, report);
17879        if (watcher != null) {
17880            Bundle results = new Bundle();
17881            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17882            results.putString("Error", report);
17883            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17884        }
17885    }
17886
17887    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17888        if (app.instrumentationWatcher != null) {
17889            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17890                    app.instrumentationClass, resultCode, results);
17891        }
17892
17893        // Can't call out of the system process with a lock held, so post a message.
17894        if (app.instrumentationUiAutomationConnection != null) {
17895            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17896                    app.instrumentationUiAutomationConnection).sendToTarget();
17897        }
17898
17899        app.instrumentationWatcher = null;
17900        app.instrumentationUiAutomationConnection = null;
17901        app.instrumentationClass = null;
17902        app.instrumentationInfo = null;
17903        app.instrumentationProfileFile = null;
17904        app.instrumentationArguments = null;
17905
17906        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17907                "finished inst");
17908    }
17909
17910    public void finishInstrumentation(IApplicationThread target,
17911            int resultCode, Bundle results) {
17912        int userId = UserHandle.getCallingUserId();
17913        // Refuse possible leaked file descriptors
17914        if (results != null && results.hasFileDescriptors()) {
17915            throw new IllegalArgumentException("File descriptors passed in Intent");
17916        }
17917
17918        synchronized(this) {
17919            ProcessRecord app = getRecordForAppLocked(target);
17920            if (app == null) {
17921                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17922                return;
17923            }
17924            final long origId = Binder.clearCallingIdentity();
17925            finishInstrumentationLocked(app, resultCode, results);
17926            Binder.restoreCallingIdentity(origId);
17927        }
17928    }
17929
17930    // =========================================================
17931    // CONFIGURATION
17932    // =========================================================
17933
17934    public ConfigurationInfo getDeviceConfigurationInfo() {
17935        ConfigurationInfo config = new ConfigurationInfo();
17936        synchronized (this) {
17937            config.reqTouchScreen = mConfiguration.touchscreen;
17938            config.reqKeyboardType = mConfiguration.keyboard;
17939            config.reqNavigation = mConfiguration.navigation;
17940            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17941                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17942                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17943            }
17944            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17945                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17946                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17947            }
17948            config.reqGlEsVersion = GL_ES_VERSION;
17949        }
17950        return config;
17951    }
17952
17953    ActivityStack getFocusedStack() {
17954        return mStackSupervisor.getFocusedStack();
17955    }
17956
17957    @Override
17958    public int getFocusedStackId() throws RemoteException {
17959        ActivityStack focusedStack = getFocusedStack();
17960        if (focusedStack != null) {
17961            return focusedStack.getStackId();
17962        }
17963        return -1;
17964    }
17965
17966    public Configuration getConfiguration() {
17967        Configuration ci;
17968        synchronized(this) {
17969            ci = new Configuration(mConfiguration);
17970            ci.userSetLocale = false;
17971        }
17972        return ci;
17973    }
17974
17975    @Override
17976    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17977        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17978        synchronized (this) {
17979            mSuppressResizeConfigChanges = suppress;
17980        }
17981    }
17982
17983    @Override
17984    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17985        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17986        if (fromStackId == HOME_STACK_ID) {
17987            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17988        }
17989        synchronized (this) {
17990            final long origId = Binder.clearCallingIdentity();
17991            try {
17992                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17993            } finally {
17994                Binder.restoreCallingIdentity(origId);
17995            }
17996        }
17997    }
17998
17999    @Override
18000    public void updatePersistentConfiguration(Configuration values) {
18001        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18002                "updateConfiguration()");
18003        enforceWriteSettingsPermission("updateConfiguration()");
18004        if (values == null) {
18005            throw new NullPointerException("Configuration must not be null");
18006        }
18007
18008        int userId = UserHandle.getCallingUserId();
18009
18010        synchronized(this) {
18011            final long origId = Binder.clearCallingIdentity();
18012            updateConfigurationLocked(values, null, false, true, userId);
18013            Binder.restoreCallingIdentity(origId);
18014        }
18015    }
18016
18017    private void updateFontScaleIfNeeded() {
18018        final int currentUserId;
18019        synchronized(this) {
18020            currentUserId = mUserController.getCurrentUserIdLocked();
18021        }
18022        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18023                FONT_SCALE, 1.0f, currentUserId);
18024        if (mConfiguration.fontScale != scaleFactor) {
18025            final Configuration configuration = mWindowManager.computeNewConfiguration();
18026            configuration.fontScale = scaleFactor;
18027            updatePersistentConfiguration(configuration);
18028        }
18029    }
18030
18031    private void enforceWriteSettingsPermission(String func) {
18032        int uid = Binder.getCallingUid();
18033        if (uid == Process.ROOT_UID) {
18034            return;
18035        }
18036
18037        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18038                Settings.getPackageNameForUid(mContext, uid), false)) {
18039            return;
18040        }
18041
18042        String msg = "Permission Denial: " + func + " from pid="
18043                + Binder.getCallingPid()
18044                + ", uid=" + uid
18045                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18046        Slog.w(TAG, msg);
18047        throw new SecurityException(msg);
18048    }
18049
18050    public void updateConfiguration(Configuration values) {
18051        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18052                "updateConfiguration()");
18053
18054        synchronized(this) {
18055            if (values == null && mWindowManager != null) {
18056                // sentinel: fetch the current configuration from the window manager
18057                values = mWindowManager.computeNewConfiguration();
18058            }
18059
18060            if (mWindowManager != null) {
18061                mProcessList.applyDisplaySize(mWindowManager);
18062            }
18063
18064            final long origId = Binder.clearCallingIdentity();
18065            if (values != null) {
18066                Settings.System.clearConfiguration(values);
18067            }
18068            updateConfigurationLocked(values, null, false);
18069            Binder.restoreCallingIdentity(origId);
18070        }
18071    }
18072
18073    void updateUserConfigurationLocked() {
18074        Configuration configuration = new Configuration(mConfiguration);
18075        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18076                mUserController.getCurrentUserIdLocked());
18077        updateConfigurationLocked(configuration, null, false);
18078    }
18079
18080    boolean updateConfigurationLocked(Configuration values,
18081            ActivityRecord starting, boolean initLocale) {
18082        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18083        return updateConfigurationLocked(values, starting, initLocale, false,
18084                UserHandle.USER_NULL);
18085    }
18086
18087    // To cache the list of supported system locales
18088    private String[] mSupportedSystemLocales = null;
18089
18090    /**
18091     * Do either or both things: (1) change the current configuration, and (2)
18092     * make sure the given activity is running with the (now) current
18093     * configuration.  Returns true if the activity has been left running, or
18094     * false if <var>starting</var> is being destroyed to match the new
18095     * configuration.
18096     *
18097     * @param userId is only used when persistent parameter is set to true to persist configuration
18098     *               for that particular user
18099     */
18100    private boolean updateConfigurationLocked(Configuration values,
18101            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18102        int changes = 0;
18103
18104        if (mWindowManager != null) {
18105            mWindowManager.deferSurfaceLayout();
18106        }
18107        if (values != null) {
18108            Configuration newConfig = new Configuration(mConfiguration);
18109            changes = newConfig.updateFrom(values);
18110            if (changes != 0) {
18111                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18112                        "Updating configuration to: " + values);
18113
18114                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18115
18116                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18117                    final Locale locale;
18118                    if (values.getLocales().size() == 1) {
18119                        // This is an optimization to avoid the JNI call when the result of
18120                        // getFirstMatch() does not depend on the supported locales.
18121                        locale = values.getLocales().get(0);
18122                    } else {
18123                        if (mSupportedSystemLocales == null) {
18124                            mSupportedSystemLocales =
18125                                    Resources.getSystem().getAssets().getLocales();
18126                        }
18127                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18128                    }
18129                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18130                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18131                            locale));
18132                }
18133
18134                mConfigurationSeq++;
18135                if (mConfigurationSeq <= 0) {
18136                    mConfigurationSeq = 1;
18137                }
18138                newConfig.seq = mConfigurationSeq;
18139                mConfiguration = newConfig;
18140                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18141                mUsageStatsService.reportConfigurationChange(newConfig,
18142                        mUserController.getCurrentUserIdLocked());
18143                //mUsageStatsService.noteStartConfig(newConfig);
18144
18145                final Configuration configCopy = new Configuration(mConfiguration);
18146
18147                // TODO: If our config changes, should we auto dismiss any currently
18148                // showing dialogs?
18149                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18150
18151                AttributeCache ac = AttributeCache.instance();
18152                if (ac != null) {
18153                    ac.updateConfiguration(configCopy);
18154                }
18155
18156                // Make sure all resources in our process are updated
18157                // right now, so that anyone who is going to retrieve
18158                // resource values after we return will be sure to get
18159                // the new ones.  This is especially important during
18160                // boot, where the first config change needs to guarantee
18161                // all resources have that config before following boot
18162                // code is executed.
18163                mSystemThread.applyConfigurationToResources(configCopy);
18164
18165                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18166                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18167                    msg.obj = new Configuration(configCopy);
18168                    msg.arg1 = userId;
18169                    mHandler.sendMessage(msg);
18170                }
18171
18172                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18173                if (isDensityChange) {
18174                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18175                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18176                }
18177
18178                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18179                    ProcessRecord app = mLruProcesses.get(i);
18180                    try {
18181                        if (app.thread != null) {
18182                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18183                                    + app.processName + " new config " + mConfiguration);
18184                            app.thread.scheduleConfigurationChanged(configCopy);
18185                        }
18186                    } catch (Exception e) {
18187                    }
18188                }
18189                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18190                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18191                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18192                        | Intent.FLAG_RECEIVER_FOREGROUND);
18193                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18194                        null, AppOpsManager.OP_NONE, null, false, false,
18195                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18196                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18197                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18198                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18199                    if (!mProcessesReady) {
18200                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18201                    }
18202                    broadcastIntentLocked(null, null, intent,
18203                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18204                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18205                }
18206            }
18207            // Update the configuration with WM first and check if any of the stacks need to be
18208            // resized due to the configuration change. If so, resize the stacks now and do any
18209            // relaunches if necessary. This way we don't need to relaunch again below in
18210            // ensureActivityConfigurationLocked().
18211            if (mWindowManager != null) {
18212                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18213                if (resizedStacks != null) {
18214                    for (int stackId : resizedStacks) {
18215                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18216                        mStackSupervisor.resizeStackLocked(
18217                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18218                    }
18219                }
18220            }
18221        }
18222
18223        boolean kept = true;
18224        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18225        // mainStack is null during startup.
18226        if (mainStack != null) {
18227            if (changes != 0 && starting == null) {
18228                // If the configuration changed, and the caller is not already
18229                // in the process of starting an activity, then find the top
18230                // activity to check if its configuration needs to change.
18231                starting = mainStack.topRunningActivityLocked();
18232            }
18233
18234            if (starting != null) {
18235                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18236                // And we need to make sure at this point that all other activities
18237                // are made visible with the correct configuration.
18238                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18239                        !PRESERVE_WINDOWS);
18240            }
18241        }
18242        if (mWindowManager != null) {
18243            mWindowManager.continueSurfaceLayout();
18244        }
18245        return kept;
18246    }
18247
18248    /**
18249     * Decide based on the configuration whether we should shouw the ANR,
18250     * crash, etc dialogs.  The idea is that if there is no affordnace to
18251     * press the on-screen buttons, we shouldn't show the dialog.
18252     *
18253     * A thought: SystemUI might also want to get told about this, the Power
18254     * dialog / global actions also might want different behaviors.
18255     */
18256    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18257        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18258                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18259                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18260        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18261                                    == Configuration.UI_MODE_TYPE_CAR);
18262        return inputMethodExists && uiIsNotCarType && !inVrMode;
18263    }
18264
18265    @Override
18266    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18267        synchronized (this) {
18268            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18269            if (srec != null) {
18270                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18271            }
18272        }
18273        return false;
18274    }
18275
18276    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18277            Intent resultData) {
18278
18279        synchronized (this) {
18280            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18281            if (r != null) {
18282                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18283            }
18284            return false;
18285        }
18286    }
18287
18288    public int getLaunchedFromUid(IBinder activityToken) {
18289        ActivityRecord srec;
18290        synchronized (this) {
18291            srec = ActivityRecord.forTokenLocked(activityToken);
18292        }
18293        if (srec == null) {
18294            return -1;
18295        }
18296        return srec.launchedFromUid;
18297    }
18298
18299    public String getLaunchedFromPackage(IBinder activityToken) {
18300        ActivityRecord srec;
18301        synchronized (this) {
18302            srec = ActivityRecord.forTokenLocked(activityToken);
18303        }
18304        if (srec == null) {
18305            return null;
18306        }
18307        return srec.launchedFromPackage;
18308    }
18309
18310    // =========================================================
18311    // LIFETIME MANAGEMENT
18312    // =========================================================
18313
18314    // Returns which broadcast queue the app is the current [or imminent] receiver
18315    // on, or 'null' if the app is not an active broadcast recipient.
18316    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18317        BroadcastRecord r = app.curReceiver;
18318        if (r != null) {
18319            return r.queue;
18320        }
18321
18322        // It's not the current receiver, but it might be starting up to become one
18323        synchronized (this) {
18324            for (BroadcastQueue queue : mBroadcastQueues) {
18325                r = queue.mPendingBroadcast;
18326                if (r != null && r.curApp == app) {
18327                    // found it; report which queue it's in
18328                    return queue;
18329                }
18330            }
18331        }
18332
18333        return null;
18334    }
18335
18336    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18337            int targetUid, ComponentName targetComponent, String targetProcess) {
18338        if (!mTrackingAssociations) {
18339            return null;
18340        }
18341        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18342                = mAssociations.get(targetUid);
18343        if (components == null) {
18344            components = new ArrayMap<>();
18345            mAssociations.put(targetUid, components);
18346        }
18347        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18348        if (sourceUids == null) {
18349            sourceUids = new SparseArray<>();
18350            components.put(targetComponent, sourceUids);
18351        }
18352        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18353        if (sourceProcesses == null) {
18354            sourceProcesses = new ArrayMap<>();
18355            sourceUids.put(sourceUid, sourceProcesses);
18356        }
18357        Association ass = sourceProcesses.get(sourceProcess);
18358        if (ass == null) {
18359            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18360                    targetProcess);
18361            sourceProcesses.put(sourceProcess, ass);
18362        }
18363        ass.mCount++;
18364        ass.mNesting++;
18365        if (ass.mNesting == 1) {
18366            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18367            ass.mLastState = sourceState;
18368        }
18369        return ass;
18370    }
18371
18372    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18373            ComponentName targetComponent) {
18374        if (!mTrackingAssociations) {
18375            return;
18376        }
18377        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18378                = mAssociations.get(targetUid);
18379        if (components == null) {
18380            return;
18381        }
18382        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18383        if (sourceUids == null) {
18384            return;
18385        }
18386        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18387        if (sourceProcesses == null) {
18388            return;
18389        }
18390        Association ass = sourceProcesses.get(sourceProcess);
18391        if (ass == null || ass.mNesting <= 0) {
18392            return;
18393        }
18394        ass.mNesting--;
18395        if (ass.mNesting == 0) {
18396            long uptime = SystemClock.uptimeMillis();
18397            ass.mTime += uptime - ass.mStartTime;
18398            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18399                    += uptime - ass.mLastStateUptime;
18400            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18401        }
18402    }
18403
18404    private void noteUidProcessState(final int uid, final int state) {
18405        mBatteryStatsService.noteUidProcessState(uid, state);
18406        if (mTrackingAssociations) {
18407            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18408                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18409                        = mAssociations.valueAt(i1);
18410                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18411                    SparseArray<ArrayMap<String, Association>> sourceUids
18412                            = targetComponents.valueAt(i2);
18413                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18414                    if (sourceProcesses != null) {
18415                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18416                            Association ass = sourceProcesses.valueAt(i4);
18417                            if (ass.mNesting >= 1) {
18418                                // currently associated
18419                                long uptime = SystemClock.uptimeMillis();
18420                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18421                                        += uptime - ass.mLastStateUptime;
18422                                ass.mLastState = state;
18423                                ass.mLastStateUptime = uptime;
18424                            }
18425                        }
18426                    }
18427                }
18428            }
18429        }
18430    }
18431
18432    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18433            boolean doingAll, long now) {
18434        if (mAdjSeq == app.adjSeq) {
18435            // This adjustment has already been computed.
18436            return app.curRawAdj;
18437        }
18438
18439        if (app.thread == null) {
18440            app.adjSeq = mAdjSeq;
18441            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18442            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18443            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18444        }
18445
18446        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18447        app.adjSource = null;
18448        app.adjTarget = null;
18449        app.empty = false;
18450        app.cached = false;
18451
18452        final int activitiesSize = app.activities.size();
18453
18454        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18455            // The max adjustment doesn't allow this app to be anything
18456            // below foreground, so it is not worth doing work for it.
18457            app.adjType = "fixed";
18458            app.adjSeq = mAdjSeq;
18459            app.curRawAdj = app.maxAdj;
18460            app.foregroundActivities = false;
18461            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18462            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18463            // System processes can do UI, and when they do we want to have
18464            // them trim their memory after the user leaves the UI.  To
18465            // facilitate this, here we need to determine whether or not it
18466            // is currently showing UI.
18467            app.systemNoUi = true;
18468            if (app == TOP_APP) {
18469                app.systemNoUi = false;
18470            } else if (activitiesSize > 0) {
18471                for (int j = 0; j < activitiesSize; j++) {
18472                    final ActivityRecord r = app.activities.get(j);
18473                    if (r.visible) {
18474                        app.systemNoUi = false;
18475                    }
18476                }
18477            }
18478            if (!app.systemNoUi) {
18479                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18480            }
18481            return (app.curAdj=app.maxAdj);
18482        }
18483
18484        app.systemNoUi = false;
18485
18486        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18487
18488        // Determine the importance of the process, starting with most
18489        // important to least, and assign an appropriate OOM adjustment.
18490        int adj;
18491        int schedGroup;
18492        int procState;
18493        boolean foregroundActivities = false;
18494        BroadcastQueue queue;
18495        if (app == TOP_APP) {
18496            // The last app on the list is the foreground app.
18497            adj = ProcessList.FOREGROUND_APP_ADJ;
18498            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18499            app.adjType = "top-activity";
18500            foregroundActivities = true;
18501            procState = PROCESS_STATE_CUR_TOP;
18502        } else if (app.instrumentationClass != null) {
18503            // Don't want to kill running instrumentation.
18504            adj = ProcessList.FOREGROUND_APP_ADJ;
18505            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18506            app.adjType = "instrumentation";
18507            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18508        } else if ((queue = isReceivingBroadcast(app)) != null) {
18509            // An app that is currently receiving a broadcast also
18510            // counts as being in the foreground for OOM killer purposes.
18511            // It's placed in a sched group based on the nature of the
18512            // broadcast as reflected by which queue it's active in.
18513            adj = ProcessList.FOREGROUND_APP_ADJ;
18514            schedGroup = (queue == mFgBroadcastQueue)
18515                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18516            app.adjType = "broadcast";
18517            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18518        } else if (app.executingServices.size() > 0) {
18519            // An app that is currently executing a service callback also
18520            // counts as being in the foreground.
18521            adj = ProcessList.FOREGROUND_APP_ADJ;
18522            schedGroup = app.execServicesFg ?
18523                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18524            app.adjType = "exec-service";
18525            procState = ActivityManager.PROCESS_STATE_SERVICE;
18526            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18527        } else {
18528            // As far as we know the process is empty.  We may change our mind later.
18529            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18530            // At this point we don't actually know the adjustment.  Use the cached adj
18531            // value that the caller wants us to.
18532            adj = cachedAdj;
18533            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18534            app.cached = true;
18535            app.empty = true;
18536            app.adjType = "cch-empty";
18537        }
18538
18539        // Examine all activities if not already foreground.
18540        if (!foregroundActivities && activitiesSize > 0) {
18541            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18542            for (int j = 0; j < activitiesSize; j++) {
18543                final ActivityRecord r = app.activities.get(j);
18544                if (r.app != app) {
18545                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18546                            + " instead of expected " + app);
18547                    if (r.app == null || (r.app.uid == app.uid)) {
18548                        // Only fix things up when they look sane
18549                        r.app = app;
18550                    } else {
18551                        continue;
18552                    }
18553                }
18554                if (r.visible) {
18555                    // App has a visible activity; only upgrade adjustment.
18556                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18557                        adj = ProcessList.VISIBLE_APP_ADJ;
18558                        app.adjType = "visible";
18559                    }
18560                    if (procState > PROCESS_STATE_CUR_TOP) {
18561                        procState = PROCESS_STATE_CUR_TOP;
18562                    }
18563                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18564                    app.cached = false;
18565                    app.empty = false;
18566                    foregroundActivities = true;
18567                    if (r.task != null && minLayer > 0) {
18568                        final int layer = r.task.mLayerRank;
18569                        if (layer >= 0 && minLayer > layer) {
18570                            minLayer = layer;
18571                        }
18572                    }
18573                    break;
18574                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18575                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18576                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18577                        app.adjType = "pausing";
18578                    }
18579                    if (procState > PROCESS_STATE_CUR_TOP) {
18580                        procState = PROCESS_STATE_CUR_TOP;
18581                    }
18582                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18583                    app.cached = false;
18584                    app.empty = false;
18585                    foregroundActivities = true;
18586                } else if (r.state == ActivityState.STOPPING) {
18587                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18588                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18589                        app.adjType = "stopping";
18590                    }
18591                    // For the process state, we will at this point consider the
18592                    // process to be cached.  It will be cached either as an activity
18593                    // or empty depending on whether the activity is finishing.  We do
18594                    // this so that we can treat the process as cached for purposes of
18595                    // memory trimming (determing current memory level, trim command to
18596                    // send to process) since there can be an arbitrary number of stopping
18597                    // processes and they should soon all go into the cached state.
18598                    if (!r.finishing) {
18599                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18600                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18601                        }
18602                    }
18603                    app.cached = false;
18604                    app.empty = false;
18605                    foregroundActivities = true;
18606                } else {
18607                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18608                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18609                        app.adjType = "cch-act";
18610                    }
18611                }
18612            }
18613            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18614                adj += minLayer;
18615            }
18616        }
18617
18618        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18619                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18620            if (app.foregroundServices) {
18621                // The user is aware of this app, so make it visible.
18622                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18623                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18624                app.cached = false;
18625                app.adjType = "fg-service";
18626                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18627            } else if (app.forcingToForeground != null) {
18628                // The user is aware of this app, so make it visible.
18629                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18630                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18631                app.cached = false;
18632                app.adjType = "force-fg";
18633                app.adjSource = app.forcingToForeground;
18634                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18635            }
18636        }
18637
18638        if (app == mHeavyWeightProcess) {
18639            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18640                // We don't want to kill the current heavy-weight process.
18641                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18642                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18643                app.cached = false;
18644                app.adjType = "heavy";
18645            }
18646            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18647                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18648            }
18649        }
18650
18651        if (app == mHomeProcess) {
18652            if (adj > ProcessList.HOME_APP_ADJ) {
18653                // This process is hosting what we currently consider to be the
18654                // home app, so we don't want to let it go into the background.
18655                adj = ProcessList.HOME_APP_ADJ;
18656                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18657                app.cached = false;
18658                app.adjType = "home";
18659            }
18660            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18661                procState = ActivityManager.PROCESS_STATE_HOME;
18662            }
18663        }
18664
18665        if (app == mPreviousProcess && app.activities.size() > 0) {
18666            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18667                // This was the previous process that showed UI to the user.
18668                // We want to try to keep it around more aggressively, to give
18669                // a good experience around switching between two apps.
18670                adj = ProcessList.PREVIOUS_APP_ADJ;
18671                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18672                app.cached = false;
18673                app.adjType = "previous";
18674            }
18675            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18676                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18677            }
18678        }
18679
18680        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18681                + " reason=" + app.adjType);
18682
18683        // By default, we use the computed adjustment.  It may be changed if
18684        // there are applications dependent on our services or providers, but
18685        // this gives us a baseline and makes sure we don't get into an
18686        // infinite recursion.
18687        app.adjSeq = mAdjSeq;
18688        app.curRawAdj = adj;
18689        app.hasStartedServices = false;
18690
18691        if (mBackupTarget != null && app == mBackupTarget.app) {
18692            // If possible we want to avoid killing apps while they're being backed up
18693            if (adj > ProcessList.BACKUP_APP_ADJ) {
18694                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18695                adj = ProcessList.BACKUP_APP_ADJ;
18696                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18697                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18698                }
18699                app.adjType = "backup";
18700                app.cached = false;
18701            }
18702            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18703                procState = ActivityManager.PROCESS_STATE_BACKUP;
18704            }
18705        }
18706
18707        boolean mayBeTop = false;
18708
18709        for (int is = app.services.size()-1;
18710                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18711                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18712                        || procState > ActivityManager.PROCESS_STATE_TOP);
18713                is--) {
18714            ServiceRecord s = app.services.valueAt(is);
18715            if (s.startRequested) {
18716                app.hasStartedServices = true;
18717                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18718                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18719                }
18720                if (app.hasShownUi && app != mHomeProcess) {
18721                    // If this process has shown some UI, let it immediately
18722                    // go to the LRU list because it may be pretty heavy with
18723                    // UI stuff.  We'll tag it with a label just to help
18724                    // debug and understand what is going on.
18725                    if (adj > ProcessList.SERVICE_ADJ) {
18726                        app.adjType = "cch-started-ui-services";
18727                    }
18728                } else {
18729                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18730                        // This service has seen some activity within
18731                        // recent memory, so we will keep its process ahead
18732                        // of the background processes.
18733                        if (adj > ProcessList.SERVICE_ADJ) {
18734                            adj = ProcessList.SERVICE_ADJ;
18735                            app.adjType = "started-services";
18736                            app.cached = false;
18737                        }
18738                    }
18739                    // If we have let the service slide into the background
18740                    // state, still have some text describing what it is doing
18741                    // even though the service no longer has an impact.
18742                    if (adj > ProcessList.SERVICE_ADJ) {
18743                        app.adjType = "cch-started-services";
18744                    }
18745                }
18746            }
18747            for (int conni = s.connections.size()-1;
18748                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18749                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18750                            || procState > ActivityManager.PROCESS_STATE_TOP);
18751                    conni--) {
18752                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18753                for (int i = 0;
18754                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18755                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18756                                || procState > ActivityManager.PROCESS_STATE_TOP);
18757                        i++) {
18758                    // XXX should compute this based on the max of
18759                    // all connected clients.
18760                    ConnectionRecord cr = clist.get(i);
18761                    if (cr.binding.client == app) {
18762                        // Binding to ourself is not interesting.
18763                        continue;
18764                    }
18765                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18766                        ProcessRecord client = cr.binding.client;
18767                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18768                                TOP_APP, doingAll, now);
18769                        int clientProcState = client.curProcState;
18770                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18771                            // If the other app is cached for any reason, for purposes here
18772                            // we are going to consider it empty.  The specific cached state
18773                            // doesn't propagate except under certain conditions.
18774                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18775                        }
18776                        String adjType = null;
18777                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18778                            // Not doing bind OOM management, so treat
18779                            // this guy more like a started service.
18780                            if (app.hasShownUi && app != mHomeProcess) {
18781                                // If this process has shown some UI, let it immediately
18782                                // go to the LRU list because it may be pretty heavy with
18783                                // UI stuff.  We'll tag it with a label just to help
18784                                // debug and understand what is going on.
18785                                if (adj > clientAdj) {
18786                                    adjType = "cch-bound-ui-services";
18787                                }
18788                                app.cached = false;
18789                                clientAdj = adj;
18790                                clientProcState = procState;
18791                            } else {
18792                                if (now >= (s.lastActivity
18793                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18794                                    // This service has not seen activity within
18795                                    // recent memory, so allow it to drop to the
18796                                    // LRU list if there is no other reason to keep
18797                                    // it around.  We'll also tag it with a label just
18798                                    // to help debug and undertand what is going on.
18799                                    if (adj > clientAdj) {
18800                                        adjType = "cch-bound-services";
18801                                    }
18802                                    clientAdj = adj;
18803                                }
18804                            }
18805                        }
18806                        if (adj > clientAdj) {
18807                            // If this process has recently shown UI, and
18808                            // the process that is binding to it is less
18809                            // important than being visible, then we don't
18810                            // care about the binding as much as we care
18811                            // about letting this process get into the LRU
18812                            // list to be killed and restarted if needed for
18813                            // memory.
18814                            if (app.hasShownUi && app != mHomeProcess
18815                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18816                                adjType = "cch-bound-ui-services";
18817                            } else {
18818                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18819                                        |Context.BIND_IMPORTANT)) != 0) {
18820                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18821                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18822                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18823                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18824                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18825                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18826                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18827                                    adj = clientAdj;
18828                                } else {
18829                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18830                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18831                                    }
18832                                }
18833                                if (!client.cached) {
18834                                    app.cached = false;
18835                                }
18836                                adjType = "service";
18837                            }
18838                        }
18839                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18840                            // This will treat important bound services identically to
18841                            // the top app, which may behave differently than generic
18842                            // foreground work.
18843                            if (client.curSchedGroup > schedGroup) {
18844                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18845                                    schedGroup = client.curSchedGroup;
18846                                } else {
18847                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18848                                }
18849                            }
18850                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18851                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18852                                    // Special handling of clients who are in the top state.
18853                                    // We *may* want to consider this process to be in the
18854                                    // top state as well, but only if there is not another
18855                                    // reason for it to be running.  Being on the top is a
18856                                    // special state, meaning you are specifically running
18857                                    // for the current top app.  If the process is already
18858                                    // running in the background for some other reason, it
18859                                    // is more important to continue considering it to be
18860                                    // in the background state.
18861                                    mayBeTop = true;
18862                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18863                                } else {
18864                                    // Special handling for above-top states (persistent
18865                                    // processes).  These should not bring the current process
18866                                    // into the top state, since they are not on top.  Instead
18867                                    // give them the best state after that.
18868                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18869                                        clientProcState =
18870                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18871                                    } else if (mWakefulness
18872                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18873                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18874                                                    != 0) {
18875                                        clientProcState =
18876                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18877                                    } else {
18878                                        clientProcState =
18879                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18880                                    }
18881                                }
18882                            }
18883                        } else {
18884                            if (clientProcState <
18885                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18886                                clientProcState =
18887                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18888                            }
18889                        }
18890                        if (procState > clientProcState) {
18891                            procState = clientProcState;
18892                        }
18893                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18894                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18895                            app.pendingUiClean = true;
18896                        }
18897                        if (adjType != null) {
18898                            app.adjType = adjType;
18899                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18900                                    .REASON_SERVICE_IN_USE;
18901                            app.adjSource = cr.binding.client;
18902                            app.adjSourceProcState = clientProcState;
18903                            app.adjTarget = s.name;
18904                        }
18905                    }
18906                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18907                        app.treatLikeActivity = true;
18908                    }
18909                    final ActivityRecord a = cr.activity;
18910                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18911                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18912                            (a.visible || a.state == ActivityState.RESUMED ||
18913                             a.state == ActivityState.PAUSING)) {
18914                            adj = ProcessList.FOREGROUND_APP_ADJ;
18915                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18916                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18917                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18918                                } else {
18919                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18920                                }
18921                            }
18922                            app.cached = false;
18923                            app.adjType = "service";
18924                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18925                                    .REASON_SERVICE_IN_USE;
18926                            app.adjSource = a;
18927                            app.adjSourceProcState = procState;
18928                            app.adjTarget = s.name;
18929                        }
18930                    }
18931                }
18932            }
18933        }
18934
18935        for (int provi = app.pubProviders.size()-1;
18936                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18937                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18938                        || procState > ActivityManager.PROCESS_STATE_TOP);
18939                provi--) {
18940            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18941            for (int i = cpr.connections.size()-1;
18942                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18943                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18944                            || procState > ActivityManager.PROCESS_STATE_TOP);
18945                    i--) {
18946                ContentProviderConnection conn = cpr.connections.get(i);
18947                ProcessRecord client = conn.client;
18948                if (client == app) {
18949                    // Being our own client is not interesting.
18950                    continue;
18951                }
18952                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18953                int clientProcState = client.curProcState;
18954                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18955                    // If the other app is cached for any reason, for purposes here
18956                    // we are going to consider it empty.
18957                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18958                }
18959                if (adj > clientAdj) {
18960                    if (app.hasShownUi && app != mHomeProcess
18961                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18962                        app.adjType = "cch-ui-provider";
18963                    } else {
18964                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18965                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18966                        app.adjType = "provider";
18967                    }
18968                    app.cached &= client.cached;
18969                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18970                            .REASON_PROVIDER_IN_USE;
18971                    app.adjSource = client;
18972                    app.adjSourceProcState = clientProcState;
18973                    app.adjTarget = cpr.name;
18974                }
18975                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18976                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18977                        // Special handling of clients who are in the top state.
18978                        // We *may* want to consider this process to be in the
18979                        // top state as well, but only if there is not another
18980                        // reason for it to be running.  Being on the top is a
18981                        // special state, meaning you are specifically running
18982                        // for the current top app.  If the process is already
18983                        // running in the background for some other reason, it
18984                        // is more important to continue considering it to be
18985                        // in the background state.
18986                        mayBeTop = true;
18987                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18988                    } else {
18989                        // Special handling for above-top states (persistent
18990                        // processes).  These should not bring the current process
18991                        // into the top state, since they are not on top.  Instead
18992                        // give them the best state after that.
18993                        clientProcState =
18994                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18995                    }
18996                }
18997                if (procState > clientProcState) {
18998                    procState = clientProcState;
18999                }
19000                if (client.curSchedGroup > schedGroup) {
19001                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19002                }
19003            }
19004            // If the provider has external (non-framework) process
19005            // dependencies, ensure that its adjustment is at least
19006            // FOREGROUND_APP_ADJ.
19007            if (cpr.hasExternalProcessHandles()) {
19008                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19009                    adj = ProcessList.FOREGROUND_APP_ADJ;
19010                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19011                    app.cached = false;
19012                    app.adjType = "provider";
19013                    app.adjTarget = cpr.name;
19014                }
19015                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19016                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19017                }
19018            }
19019        }
19020
19021        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19022            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19023                adj = ProcessList.PREVIOUS_APP_ADJ;
19024                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19025                app.cached = false;
19026                app.adjType = "provider";
19027            }
19028            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19029                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19030            }
19031        }
19032
19033        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19034            // A client of one of our services or providers is in the top state.  We
19035            // *may* want to be in the top state, but not if we are already running in
19036            // the background for some other reason.  For the decision here, we are going
19037            // to pick out a few specific states that we want to remain in when a client
19038            // is top (states that tend to be longer-term) and otherwise allow it to go
19039            // to the top state.
19040            switch (procState) {
19041                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19042                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19043                case ActivityManager.PROCESS_STATE_SERVICE:
19044                    // These all are longer-term states, so pull them up to the top
19045                    // of the background states, but not all the way to the top state.
19046                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19047                    break;
19048                default:
19049                    // Otherwise, top is a better choice, so take it.
19050                    procState = ActivityManager.PROCESS_STATE_TOP;
19051                    break;
19052            }
19053        }
19054
19055        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19056            if (app.hasClientActivities) {
19057                // This is a cached process, but with client activities.  Mark it so.
19058                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19059                app.adjType = "cch-client-act";
19060            } else if (app.treatLikeActivity) {
19061                // This is a cached process, but somebody wants us to treat it like it has
19062                // an activity, okay!
19063                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19064                app.adjType = "cch-as-act";
19065            }
19066        }
19067
19068        if (adj == ProcessList.SERVICE_ADJ) {
19069            if (doingAll) {
19070                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19071                mNewNumServiceProcs++;
19072                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19073                if (!app.serviceb) {
19074                    // This service isn't far enough down on the LRU list to
19075                    // normally be a B service, but if we are low on RAM and it
19076                    // is large we want to force it down since we would prefer to
19077                    // keep launcher over it.
19078                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19079                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19080                        app.serviceHighRam = true;
19081                        app.serviceb = true;
19082                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19083                    } else {
19084                        mNewNumAServiceProcs++;
19085                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19086                    }
19087                } else {
19088                    app.serviceHighRam = false;
19089                }
19090            }
19091            if (app.serviceb) {
19092                adj = ProcessList.SERVICE_B_ADJ;
19093            }
19094        }
19095
19096        app.curRawAdj = adj;
19097
19098        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19099        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19100        if (adj > app.maxAdj) {
19101            adj = app.maxAdj;
19102            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19103                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19104            }
19105        }
19106
19107        // Do final modification to adj.  Everything we do between here and applying
19108        // the final setAdj must be done in this function, because we will also use
19109        // it when computing the final cached adj later.  Note that we don't need to
19110        // worry about this for max adj above, since max adj will always be used to
19111        // keep it out of the cached vaues.
19112        app.curAdj = app.modifyRawOomAdj(adj);
19113        app.curSchedGroup = schedGroup;
19114        app.curProcState = procState;
19115        app.foregroundActivities = foregroundActivities;
19116
19117        return app.curRawAdj;
19118    }
19119
19120    /**
19121     * Record new PSS sample for a process.
19122     */
19123    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19124            long now) {
19125        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19126                swapPss * 1024);
19127        proc.lastPssTime = now;
19128        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19129        if (DEBUG_PSS) Slog.d(TAG_PSS,
19130                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19131                + " state=" + ProcessList.makeProcStateString(procState));
19132        if (proc.initialIdlePss == 0) {
19133            proc.initialIdlePss = pss;
19134        }
19135        proc.lastPss = pss;
19136        proc.lastSwapPss = swapPss;
19137        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19138            proc.lastCachedPss = pss;
19139            proc.lastCachedSwapPss = swapPss;
19140        }
19141
19142        final SparseArray<Pair<Long, String>> watchUids
19143                = mMemWatchProcesses.getMap().get(proc.processName);
19144        Long check = null;
19145        if (watchUids != null) {
19146            Pair<Long, String> val = watchUids.get(proc.uid);
19147            if (val == null) {
19148                val = watchUids.get(0);
19149            }
19150            if (val != null) {
19151                check = val.first;
19152            }
19153        }
19154        if (check != null) {
19155            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19156                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19157                if (!isDebuggable) {
19158                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19159                        isDebuggable = true;
19160                    }
19161                }
19162                if (isDebuggable) {
19163                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19164                    final ProcessRecord myProc = proc;
19165                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19166                    mMemWatchDumpProcName = proc.processName;
19167                    mMemWatchDumpFile = heapdumpFile.toString();
19168                    mMemWatchDumpPid = proc.pid;
19169                    mMemWatchDumpUid = proc.uid;
19170                    BackgroundThread.getHandler().post(new Runnable() {
19171                        @Override
19172                        public void run() {
19173                            revokeUriPermission(ActivityThread.currentActivityThread()
19174                                            .getApplicationThread(),
19175                                    DumpHeapActivity.JAVA_URI,
19176                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19177                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19178                                    UserHandle.myUserId());
19179                            ParcelFileDescriptor fd = null;
19180                            try {
19181                                heapdumpFile.delete();
19182                                fd = ParcelFileDescriptor.open(heapdumpFile,
19183                                        ParcelFileDescriptor.MODE_CREATE |
19184                                                ParcelFileDescriptor.MODE_TRUNCATE |
19185                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19186                                                ParcelFileDescriptor.MODE_APPEND);
19187                                IApplicationThread thread = myProc.thread;
19188                                if (thread != null) {
19189                                    try {
19190                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19191                                                "Requesting dump heap from "
19192                                                + myProc + " to " + heapdumpFile);
19193                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19194                                    } catch (RemoteException e) {
19195                                    }
19196                                }
19197                            } catch (FileNotFoundException e) {
19198                                e.printStackTrace();
19199                            } finally {
19200                                if (fd != null) {
19201                                    try {
19202                                        fd.close();
19203                                    } catch (IOException e) {
19204                                    }
19205                                }
19206                            }
19207                        }
19208                    });
19209                } else {
19210                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19211                            + ", but debugging not enabled");
19212                }
19213            }
19214        }
19215    }
19216
19217    /**
19218     * Schedule PSS collection of a process.
19219     */
19220    void requestPssLocked(ProcessRecord proc, int procState) {
19221        if (mPendingPssProcesses.contains(proc)) {
19222            return;
19223        }
19224        if (mPendingPssProcesses.size() == 0) {
19225            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19226        }
19227        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19228        proc.pssProcState = procState;
19229        mPendingPssProcesses.add(proc);
19230    }
19231
19232    /**
19233     * Schedule PSS collection of all processes.
19234     */
19235    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19236        if (!always) {
19237            if (now < (mLastFullPssTime +
19238                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19239                return;
19240            }
19241        }
19242        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19243        mLastFullPssTime = now;
19244        mFullPssPending = true;
19245        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19246        mPendingPssProcesses.clear();
19247        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19248            ProcessRecord app = mLruProcesses.get(i);
19249            if (app.thread == null
19250                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19251                continue;
19252            }
19253            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19254                app.pssProcState = app.setProcState;
19255                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19256                        mTestPssMode, isSleeping(), now);
19257                mPendingPssProcesses.add(app);
19258            }
19259        }
19260        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19261    }
19262
19263    public void setTestPssMode(boolean enabled) {
19264        synchronized (this) {
19265            mTestPssMode = enabled;
19266            if (enabled) {
19267                // Whenever we enable the mode, we want to take a snapshot all of current
19268                // process mem use.
19269                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19270            }
19271        }
19272    }
19273
19274    /**
19275     * Ask a given process to GC right now.
19276     */
19277    final void performAppGcLocked(ProcessRecord app) {
19278        try {
19279            app.lastRequestedGc = SystemClock.uptimeMillis();
19280            if (app.thread != null) {
19281                if (app.reportLowMemory) {
19282                    app.reportLowMemory = false;
19283                    app.thread.scheduleLowMemory();
19284                } else {
19285                    app.thread.processInBackground();
19286                }
19287            }
19288        } catch (Exception e) {
19289            // whatever.
19290        }
19291    }
19292
19293    /**
19294     * Returns true if things are idle enough to perform GCs.
19295     */
19296    private final boolean canGcNowLocked() {
19297        boolean processingBroadcasts = false;
19298        for (BroadcastQueue q : mBroadcastQueues) {
19299            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19300                processingBroadcasts = true;
19301            }
19302        }
19303        return !processingBroadcasts
19304                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19305    }
19306
19307    /**
19308     * Perform GCs on all processes that are waiting for it, but only
19309     * if things are idle.
19310     */
19311    final void performAppGcsLocked() {
19312        final int N = mProcessesToGc.size();
19313        if (N <= 0) {
19314            return;
19315        }
19316        if (canGcNowLocked()) {
19317            while (mProcessesToGc.size() > 0) {
19318                ProcessRecord proc = mProcessesToGc.remove(0);
19319                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19320                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19321                            <= SystemClock.uptimeMillis()) {
19322                        // To avoid spamming the system, we will GC processes one
19323                        // at a time, waiting a few seconds between each.
19324                        performAppGcLocked(proc);
19325                        scheduleAppGcsLocked();
19326                        return;
19327                    } else {
19328                        // It hasn't been long enough since we last GCed this
19329                        // process...  put it in the list to wait for its time.
19330                        addProcessToGcListLocked(proc);
19331                        break;
19332                    }
19333                }
19334            }
19335
19336            scheduleAppGcsLocked();
19337        }
19338    }
19339
19340    /**
19341     * If all looks good, perform GCs on all processes waiting for them.
19342     */
19343    final void performAppGcsIfAppropriateLocked() {
19344        if (canGcNowLocked()) {
19345            performAppGcsLocked();
19346            return;
19347        }
19348        // Still not idle, wait some more.
19349        scheduleAppGcsLocked();
19350    }
19351
19352    /**
19353     * Schedule the execution of all pending app GCs.
19354     */
19355    final void scheduleAppGcsLocked() {
19356        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19357
19358        if (mProcessesToGc.size() > 0) {
19359            // Schedule a GC for the time to the next process.
19360            ProcessRecord proc = mProcessesToGc.get(0);
19361            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19362
19363            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19364            long now = SystemClock.uptimeMillis();
19365            if (when < (now+GC_TIMEOUT)) {
19366                when = now + GC_TIMEOUT;
19367            }
19368            mHandler.sendMessageAtTime(msg, when);
19369        }
19370    }
19371
19372    /**
19373     * Add a process to the array of processes waiting to be GCed.  Keeps the
19374     * list in sorted order by the last GC time.  The process can't already be
19375     * on the list.
19376     */
19377    final void addProcessToGcListLocked(ProcessRecord proc) {
19378        boolean added = false;
19379        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19380            if (mProcessesToGc.get(i).lastRequestedGc <
19381                    proc.lastRequestedGc) {
19382                added = true;
19383                mProcessesToGc.add(i+1, proc);
19384                break;
19385            }
19386        }
19387        if (!added) {
19388            mProcessesToGc.add(0, proc);
19389        }
19390    }
19391
19392    /**
19393     * Set up to ask a process to GC itself.  This will either do it
19394     * immediately, or put it on the list of processes to gc the next
19395     * time things are idle.
19396     */
19397    final void scheduleAppGcLocked(ProcessRecord app) {
19398        long now = SystemClock.uptimeMillis();
19399        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19400            return;
19401        }
19402        if (!mProcessesToGc.contains(app)) {
19403            addProcessToGcListLocked(app);
19404            scheduleAppGcsLocked();
19405        }
19406    }
19407
19408    final void checkExcessivePowerUsageLocked(boolean doKills) {
19409        updateCpuStatsNow();
19410
19411        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19412        boolean doWakeKills = doKills;
19413        boolean doCpuKills = doKills;
19414        if (mLastPowerCheckRealtime == 0) {
19415            doWakeKills = false;
19416        }
19417        if (mLastPowerCheckUptime == 0) {
19418            doCpuKills = false;
19419        }
19420        if (stats.isScreenOn()) {
19421            doWakeKills = false;
19422        }
19423        final long curRealtime = SystemClock.elapsedRealtime();
19424        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19425        final long curUptime = SystemClock.uptimeMillis();
19426        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19427        mLastPowerCheckRealtime = curRealtime;
19428        mLastPowerCheckUptime = curUptime;
19429        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19430            doWakeKills = false;
19431        }
19432        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19433            doCpuKills = false;
19434        }
19435        int i = mLruProcesses.size();
19436        while (i > 0) {
19437            i--;
19438            ProcessRecord app = mLruProcesses.get(i);
19439            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19440                long wtime;
19441                synchronized (stats) {
19442                    wtime = stats.getProcessWakeTime(app.info.uid,
19443                            app.pid, curRealtime);
19444                }
19445                long wtimeUsed = wtime - app.lastWakeTime;
19446                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19447                if (DEBUG_POWER) {
19448                    StringBuilder sb = new StringBuilder(128);
19449                    sb.append("Wake for ");
19450                    app.toShortString(sb);
19451                    sb.append(": over ");
19452                    TimeUtils.formatDuration(realtimeSince, sb);
19453                    sb.append(" used ");
19454                    TimeUtils.formatDuration(wtimeUsed, sb);
19455                    sb.append(" (");
19456                    sb.append((wtimeUsed*100)/realtimeSince);
19457                    sb.append("%)");
19458                    Slog.i(TAG_POWER, sb.toString());
19459                    sb.setLength(0);
19460                    sb.append("CPU for ");
19461                    app.toShortString(sb);
19462                    sb.append(": over ");
19463                    TimeUtils.formatDuration(uptimeSince, sb);
19464                    sb.append(" used ");
19465                    TimeUtils.formatDuration(cputimeUsed, sb);
19466                    sb.append(" (");
19467                    sb.append((cputimeUsed*100)/uptimeSince);
19468                    sb.append("%)");
19469                    Slog.i(TAG_POWER, sb.toString());
19470                }
19471                // If a process has held a wake lock for more
19472                // than 50% of the time during this period,
19473                // that sounds bad.  Kill!
19474                if (doWakeKills && realtimeSince > 0
19475                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19476                    synchronized (stats) {
19477                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19478                                realtimeSince, wtimeUsed);
19479                    }
19480                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19481                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19482                } else if (doCpuKills && uptimeSince > 0
19483                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19484                    synchronized (stats) {
19485                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19486                                uptimeSince, cputimeUsed);
19487                    }
19488                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19489                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19490                } else {
19491                    app.lastWakeTime = wtime;
19492                    app.lastCpuTime = app.curCpuTime;
19493                }
19494            }
19495        }
19496    }
19497
19498    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19499            long nowElapsed) {
19500        boolean success = true;
19501
19502        if (app.curRawAdj != app.setRawAdj) {
19503            app.setRawAdj = app.curRawAdj;
19504        }
19505
19506        int changes = 0;
19507
19508        if (app.curAdj != app.setAdj) {
19509            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19510            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19511                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19512                    + app.adjType);
19513            app.setAdj = app.curAdj;
19514        }
19515
19516        if (app.setSchedGroup != app.curSchedGroup) {
19517            app.setSchedGroup = app.curSchedGroup;
19518            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19519                    "Setting sched group of " + app.processName
19520                    + " to " + app.curSchedGroup);
19521            if (app.waitingToKill != null && app.curReceiver == null
19522                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19523                app.kill(app.waitingToKill, true);
19524                success = false;
19525            } else {
19526                int processGroup;
19527                switch (app.curSchedGroup) {
19528                    case ProcessList.SCHED_GROUP_BACKGROUND:
19529                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19530                        break;
19531                    case ProcessList.SCHED_GROUP_TOP_APP:
19532                        processGroup = Process.THREAD_GROUP_TOP_APP;
19533                        break;
19534                    default:
19535                        processGroup = Process.THREAD_GROUP_DEFAULT;
19536                        break;
19537                }
19538                if (true) {
19539                    long oldId = Binder.clearCallingIdentity();
19540                    try {
19541                        Process.setProcessGroup(app.pid, processGroup);
19542                    } catch (Exception e) {
19543                        Slog.w(TAG, "Failed setting process group of " + app.pid
19544                                + " to " + app.curSchedGroup);
19545                        e.printStackTrace();
19546                    } finally {
19547                        Binder.restoreCallingIdentity(oldId);
19548                    }
19549                } else {
19550                    if (app.thread != null) {
19551                        try {
19552                            app.thread.setSchedulingGroup(processGroup);
19553                        } catch (RemoteException e) {
19554                        }
19555                    }
19556                }
19557            }
19558        }
19559        if (app.repForegroundActivities != app.foregroundActivities) {
19560            app.repForegroundActivities = app.foregroundActivities;
19561            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19562        }
19563        if (app.repProcState != app.curProcState) {
19564            app.repProcState = app.curProcState;
19565            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19566            if (app.thread != null) {
19567                try {
19568                    if (false) {
19569                        //RuntimeException h = new RuntimeException("here");
19570                        Slog.i(TAG, "Sending new process state " + app.repProcState
19571                                + " to " + app /*, h*/);
19572                    }
19573                    app.thread.setProcessState(app.repProcState);
19574                } catch (RemoteException e) {
19575                }
19576            }
19577        }
19578        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19579                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19580            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19581                // Experimental code to more aggressively collect pss while
19582                // running test...  the problem is that this tends to collect
19583                // the data right when a process is transitioning between process
19584                // states, which well tend to give noisy data.
19585                long start = SystemClock.uptimeMillis();
19586                long pss = Debug.getPss(app.pid, mTmpLong, null);
19587                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19588                mPendingPssProcesses.remove(app);
19589                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19590                        + " to " + app.curProcState + ": "
19591                        + (SystemClock.uptimeMillis()-start) + "ms");
19592            }
19593            app.lastStateTime = now;
19594            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19595                    mTestPssMode, isSleeping(), now);
19596            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19597                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19598                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19599                    + (app.nextPssTime-now) + ": " + app);
19600        } else {
19601            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19602                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19603                    mTestPssMode)))) {
19604                requestPssLocked(app, app.setProcState);
19605                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19606                        mTestPssMode, isSleeping(), now);
19607            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19608                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19609        }
19610        if (app.setProcState != app.curProcState) {
19611            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19612                    "Proc state change of " + app.processName
19613                            + " to " + app.curProcState);
19614            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19615            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19616            if (setImportant && !curImportant) {
19617                // This app is no longer something we consider important enough to allow to
19618                // use arbitrary amounts of battery power.  Note
19619                // its current wake lock time to later know to kill it if
19620                // it is not behaving well.
19621                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19622                synchronized (stats) {
19623                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19624                            app.pid, nowElapsed);
19625                }
19626                app.lastCpuTime = app.curCpuTime;
19627
19628            }
19629            // Inform UsageStats of important process state change
19630            // Must be called before updating setProcState
19631            maybeUpdateUsageStatsLocked(app, nowElapsed);
19632
19633            app.setProcState = app.curProcState;
19634            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19635                app.notCachedSinceIdle = false;
19636            }
19637            if (!doingAll) {
19638                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19639            } else {
19640                app.procStateChanged = true;
19641            }
19642        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19643                > USAGE_STATS_INTERACTION_INTERVAL) {
19644            // For apps that sit around for a long time in the interactive state, we need
19645            // to report this at least once a day so they don't go idle.
19646            maybeUpdateUsageStatsLocked(app, nowElapsed);
19647        }
19648
19649        if (changes != 0) {
19650            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19651                    "Changes in " + app + ": " + changes);
19652            int i = mPendingProcessChanges.size()-1;
19653            ProcessChangeItem item = null;
19654            while (i >= 0) {
19655                item = mPendingProcessChanges.get(i);
19656                if (item.pid == app.pid) {
19657                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19658                            "Re-using existing item: " + item);
19659                    break;
19660                }
19661                i--;
19662            }
19663            if (i < 0) {
19664                // No existing item in pending changes; need a new one.
19665                final int NA = mAvailProcessChanges.size();
19666                if (NA > 0) {
19667                    item = mAvailProcessChanges.remove(NA-1);
19668                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19669                            "Retrieving available item: " + item);
19670                } else {
19671                    item = new ProcessChangeItem();
19672                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19673                            "Allocating new item: " + item);
19674                }
19675                item.changes = 0;
19676                item.pid = app.pid;
19677                item.uid = app.info.uid;
19678                if (mPendingProcessChanges.size() == 0) {
19679                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19680                            "*** Enqueueing dispatch processes changed!");
19681                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19682                }
19683                mPendingProcessChanges.add(item);
19684            }
19685            item.changes |= changes;
19686            item.processState = app.repProcState;
19687            item.foregroundActivities = app.repForegroundActivities;
19688            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19689                    "Item " + Integer.toHexString(System.identityHashCode(item))
19690                    + " " + app.toShortString() + ": changes=" + item.changes
19691                    + " procState=" + item.processState
19692                    + " foreground=" + item.foregroundActivities
19693                    + " type=" + app.adjType + " source=" + app.adjSource
19694                    + " target=" + app.adjTarget);
19695        }
19696
19697        return success;
19698    }
19699
19700    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19701        final UidRecord.ChangeItem pendingChange;
19702        if (uidRec == null || uidRec.pendingChange == null) {
19703            if (mPendingUidChanges.size() == 0) {
19704                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19705                        "*** Enqueueing dispatch uid changed!");
19706                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19707            }
19708            final int NA = mAvailUidChanges.size();
19709            if (NA > 0) {
19710                pendingChange = mAvailUidChanges.remove(NA-1);
19711                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19712                        "Retrieving available item: " + pendingChange);
19713            } else {
19714                pendingChange = new UidRecord.ChangeItem();
19715                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19716                        "Allocating new item: " + pendingChange);
19717            }
19718            if (uidRec != null) {
19719                uidRec.pendingChange = pendingChange;
19720                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19721                    // If this uid is going away, and we haven't yet reported it is gone,
19722                    // then do so now.
19723                    change = UidRecord.CHANGE_GONE_IDLE;
19724                }
19725            } else if (uid < 0) {
19726                throw new IllegalArgumentException("No UidRecord or uid");
19727            }
19728            pendingChange.uidRecord = uidRec;
19729            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19730            mPendingUidChanges.add(pendingChange);
19731        } else {
19732            pendingChange = uidRec.pendingChange;
19733            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19734                change = UidRecord.CHANGE_GONE_IDLE;
19735            }
19736        }
19737        pendingChange.change = change;
19738        pendingChange.processState = uidRec != null
19739                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19740    }
19741
19742    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19743            String authority) {
19744        if (app == null) return;
19745        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19746            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19747            if (userState == null) return;
19748            final long now = SystemClock.elapsedRealtime();
19749            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19750            if (lastReported == null || lastReported < now - 60 * 1000L) {
19751                mUsageStatsService.reportContentProviderUsage(
19752                        authority, providerPkgName, app.userId);
19753                userState.mProviderLastReportedFg.put(authority, now);
19754            }
19755        }
19756    }
19757
19758    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19759        if (DEBUG_USAGE_STATS) {
19760            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19761                    + "] state changes: old = " + app.setProcState + ", new = "
19762                    + app.curProcState);
19763        }
19764        if (mUsageStatsService == null) {
19765            return;
19766        }
19767        boolean isInteraction;
19768        // To avoid some abuse patterns, we are going to be careful about what we consider
19769        // to be an app interaction.  Being the top activity doesn't count while the display
19770        // is sleeping, nor do short foreground services.
19771        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19772            isInteraction = true;
19773            app.fgInteractionTime = 0;
19774        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19775            if (app.fgInteractionTime == 0) {
19776                app.fgInteractionTime = nowElapsed;
19777                isInteraction = false;
19778            } else {
19779                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19780            }
19781        } else {
19782            isInteraction = app.curProcState
19783                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19784            app.fgInteractionTime = 0;
19785        }
19786        if (isInteraction && (!app.reportedInteraction
19787                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19788            app.interactionEventTime = nowElapsed;
19789            String[] packages = app.getPackageList();
19790            if (packages != null) {
19791                for (int i = 0; i < packages.length; i++) {
19792                    mUsageStatsService.reportEvent(packages[i], app.userId,
19793                            UsageEvents.Event.SYSTEM_INTERACTION);
19794                }
19795            }
19796        }
19797        app.reportedInteraction = isInteraction;
19798        if (!isInteraction) {
19799            app.interactionEventTime = 0;
19800        }
19801    }
19802
19803    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19804        if (proc.thread != null) {
19805            if (proc.baseProcessTracker != null) {
19806                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19807            }
19808        }
19809    }
19810
19811    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19812            ProcessRecord TOP_APP, boolean doingAll, long now) {
19813        if (app.thread == null) {
19814            return false;
19815        }
19816
19817        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19818
19819        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19820    }
19821
19822    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19823            boolean oomAdj) {
19824        if (isForeground != proc.foregroundServices) {
19825            proc.foregroundServices = isForeground;
19826            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19827                    proc.info.uid);
19828            if (isForeground) {
19829                if (curProcs == null) {
19830                    curProcs = new ArrayList<ProcessRecord>();
19831                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19832                }
19833                if (!curProcs.contains(proc)) {
19834                    curProcs.add(proc);
19835                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19836                            proc.info.packageName, proc.info.uid);
19837                }
19838            } else {
19839                if (curProcs != null) {
19840                    if (curProcs.remove(proc)) {
19841                        mBatteryStatsService.noteEvent(
19842                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19843                                proc.info.packageName, proc.info.uid);
19844                        if (curProcs.size() <= 0) {
19845                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19846                        }
19847                    }
19848                }
19849            }
19850            if (oomAdj) {
19851                updateOomAdjLocked();
19852            }
19853        }
19854    }
19855
19856    private final ActivityRecord resumedAppLocked() {
19857        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19858        String pkg;
19859        int uid;
19860        if (act != null) {
19861            pkg = act.packageName;
19862            uid = act.info.applicationInfo.uid;
19863        } else {
19864            pkg = null;
19865            uid = -1;
19866        }
19867        // Has the UID or resumed package name changed?
19868        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19869                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19870            if (mCurResumedPackage != null) {
19871                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19872                        mCurResumedPackage, mCurResumedUid);
19873            }
19874            mCurResumedPackage = pkg;
19875            mCurResumedUid = uid;
19876            if (mCurResumedPackage != null) {
19877                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19878                        mCurResumedPackage, mCurResumedUid);
19879            }
19880        }
19881        return act;
19882    }
19883
19884    final boolean updateOomAdjLocked(ProcessRecord app) {
19885        final ActivityRecord TOP_ACT = resumedAppLocked();
19886        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19887        final boolean wasCached = app.cached;
19888
19889        mAdjSeq++;
19890
19891        // This is the desired cached adjusment we want to tell it to use.
19892        // If our app is currently cached, we know it, and that is it.  Otherwise,
19893        // we don't know it yet, and it needs to now be cached we will then
19894        // need to do a complete oom adj.
19895        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19896                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19897        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19898                SystemClock.uptimeMillis());
19899        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19900            // Changed to/from cached state, so apps after it in the LRU
19901            // list may also be changed.
19902            updateOomAdjLocked();
19903        }
19904        return success;
19905    }
19906
19907    final void updateOomAdjLocked() {
19908        final ActivityRecord TOP_ACT = resumedAppLocked();
19909        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19910        final long now = SystemClock.uptimeMillis();
19911        final long nowElapsed = SystemClock.elapsedRealtime();
19912        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19913        final int N = mLruProcesses.size();
19914
19915        if (false) {
19916            RuntimeException e = new RuntimeException();
19917            e.fillInStackTrace();
19918            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19919        }
19920
19921        // Reset state in all uid records.
19922        for (int i=mActiveUids.size()-1; i>=0; i--) {
19923            final UidRecord uidRec = mActiveUids.valueAt(i);
19924            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19925                    "Starting update of " + uidRec);
19926            uidRec.reset();
19927        }
19928
19929        mStackSupervisor.rankTaskLayersIfNeeded();
19930
19931        mAdjSeq++;
19932        mNewNumServiceProcs = 0;
19933        mNewNumAServiceProcs = 0;
19934
19935        final int emptyProcessLimit;
19936        final int cachedProcessLimit;
19937        if (mProcessLimit <= 0) {
19938            emptyProcessLimit = cachedProcessLimit = 0;
19939        } else if (mProcessLimit == 1) {
19940            emptyProcessLimit = 1;
19941            cachedProcessLimit = 0;
19942        } else {
19943            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19944            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19945        }
19946
19947        // Let's determine how many processes we have running vs.
19948        // how many slots we have for background processes; we may want
19949        // to put multiple processes in a slot of there are enough of
19950        // them.
19951        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19952                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19953        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19954        if (numEmptyProcs > cachedProcessLimit) {
19955            // If there are more empty processes than our limit on cached
19956            // processes, then use the cached process limit for the factor.
19957            // This ensures that the really old empty processes get pushed
19958            // down to the bottom, so if we are running low on memory we will
19959            // have a better chance at keeping around more cached processes
19960            // instead of a gazillion empty processes.
19961            numEmptyProcs = cachedProcessLimit;
19962        }
19963        int emptyFactor = numEmptyProcs/numSlots;
19964        if (emptyFactor < 1) emptyFactor = 1;
19965        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19966        if (cachedFactor < 1) cachedFactor = 1;
19967        int stepCached = 0;
19968        int stepEmpty = 0;
19969        int numCached = 0;
19970        int numEmpty = 0;
19971        int numTrimming = 0;
19972
19973        mNumNonCachedProcs = 0;
19974        mNumCachedHiddenProcs = 0;
19975
19976        // First update the OOM adjustment for each of the
19977        // application processes based on their current state.
19978        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19979        int nextCachedAdj = curCachedAdj+1;
19980        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19981        int nextEmptyAdj = curEmptyAdj+2;
19982        for (int i=N-1; i>=0; i--) {
19983            ProcessRecord app = mLruProcesses.get(i);
19984            if (!app.killedByAm && app.thread != null) {
19985                app.procStateChanged = false;
19986                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19987
19988                // If we haven't yet assigned the final cached adj
19989                // to the process, do that now.
19990                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19991                    switch (app.curProcState) {
19992                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19993                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19994                            // This process is a cached process holding activities...
19995                            // assign it the next cached value for that type, and then
19996                            // step that cached level.
19997                            app.curRawAdj = curCachedAdj;
19998                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19999                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20000                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20001                                    + ")");
20002                            if (curCachedAdj != nextCachedAdj) {
20003                                stepCached++;
20004                                if (stepCached >= cachedFactor) {
20005                                    stepCached = 0;
20006                                    curCachedAdj = nextCachedAdj;
20007                                    nextCachedAdj += 2;
20008                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20009                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20010                                    }
20011                                }
20012                            }
20013                            break;
20014                        default:
20015                            // For everything else, assign next empty cached process
20016                            // level and bump that up.  Note that this means that
20017                            // long-running services that have dropped down to the
20018                            // cached level will be treated as empty (since their process
20019                            // state is still as a service), which is what we want.
20020                            app.curRawAdj = curEmptyAdj;
20021                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20022                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20023                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20024                                    + ")");
20025                            if (curEmptyAdj != nextEmptyAdj) {
20026                                stepEmpty++;
20027                                if (stepEmpty >= emptyFactor) {
20028                                    stepEmpty = 0;
20029                                    curEmptyAdj = nextEmptyAdj;
20030                                    nextEmptyAdj += 2;
20031                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20032                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20033                                    }
20034                                }
20035                            }
20036                            break;
20037                    }
20038                }
20039
20040                applyOomAdjLocked(app, true, now, nowElapsed);
20041
20042                // Count the number of process types.
20043                switch (app.curProcState) {
20044                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20045                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20046                        mNumCachedHiddenProcs++;
20047                        numCached++;
20048                        if (numCached > cachedProcessLimit) {
20049                            app.kill("cached #" + numCached, true);
20050                        }
20051                        break;
20052                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20053                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20054                                && app.lastActivityTime < oldTime) {
20055                            app.kill("empty for "
20056                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20057                                    / 1000) + "s", true);
20058                        } else {
20059                            numEmpty++;
20060                            if (numEmpty > emptyProcessLimit) {
20061                                app.kill("empty #" + numEmpty, true);
20062                            }
20063                        }
20064                        break;
20065                    default:
20066                        mNumNonCachedProcs++;
20067                        break;
20068                }
20069
20070                if (app.isolated && app.services.size() <= 0) {
20071                    // If this is an isolated process, and there are no
20072                    // services running in it, then the process is no longer
20073                    // needed.  We agressively kill these because we can by
20074                    // definition not re-use the same process again, and it is
20075                    // good to avoid having whatever code was running in them
20076                    // left sitting around after no longer needed.
20077                    app.kill("isolated not needed", true);
20078                } else {
20079                    // Keeping this process, update its uid.
20080                    final UidRecord uidRec = app.uidRecord;
20081                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20082                        uidRec.curProcState = app.curProcState;
20083                    }
20084                }
20085
20086                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20087                        && !app.killedByAm) {
20088                    numTrimming++;
20089                }
20090            }
20091        }
20092
20093        mNumServiceProcs = mNewNumServiceProcs;
20094
20095        // Now determine the memory trimming level of background processes.
20096        // Unfortunately we need to start at the back of the list to do this
20097        // properly.  We only do this if the number of background apps we
20098        // are managing to keep around is less than half the maximum we desire;
20099        // if we are keeping a good number around, we'll let them use whatever
20100        // memory they want.
20101        final int numCachedAndEmpty = numCached + numEmpty;
20102        int memFactor;
20103        if (numCached <= ProcessList.TRIM_CACHED_APPS
20104                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20105            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20106                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20107            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20108                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20109            } else {
20110                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20111            }
20112        } else {
20113            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20114        }
20115        // We always allow the memory level to go up (better).  We only allow it to go
20116        // down if we are in a state where that is allowed, *and* the total number of processes
20117        // has gone down since last time.
20118        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20119                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20120                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20121        if (memFactor > mLastMemoryLevel) {
20122            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20123                memFactor = mLastMemoryLevel;
20124                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20125            }
20126        }
20127        if (memFactor != mLastMemoryLevel) {
20128            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20129        }
20130        mLastMemoryLevel = memFactor;
20131        mLastNumProcesses = mLruProcesses.size();
20132        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20133        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20134        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20135            if (mLowRamStartTime == 0) {
20136                mLowRamStartTime = now;
20137            }
20138            int step = 0;
20139            int fgTrimLevel;
20140            switch (memFactor) {
20141                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20142                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20143                    break;
20144                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20145                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20146                    break;
20147                default:
20148                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20149                    break;
20150            }
20151            int factor = numTrimming/3;
20152            int minFactor = 2;
20153            if (mHomeProcess != null) minFactor++;
20154            if (mPreviousProcess != null) minFactor++;
20155            if (factor < minFactor) factor = minFactor;
20156            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20157            for (int i=N-1; i>=0; i--) {
20158                ProcessRecord app = mLruProcesses.get(i);
20159                if (allChanged || app.procStateChanged) {
20160                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20161                    app.procStateChanged = false;
20162                }
20163                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20164                        && !app.killedByAm) {
20165                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20166                        try {
20167                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20168                                    "Trimming memory of " + app.processName + " to " + curLevel);
20169                            app.thread.scheduleTrimMemory(curLevel);
20170                        } catch (RemoteException e) {
20171                        }
20172                        if (false) {
20173                            // For now we won't do this; our memory trimming seems
20174                            // to be good enough at this point that destroying
20175                            // activities causes more harm than good.
20176                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20177                                    && app != mHomeProcess && app != mPreviousProcess) {
20178                                // Need to do this on its own message because the stack may not
20179                                // be in a consistent state at this point.
20180                                // For these apps we will also finish their activities
20181                                // to help them free memory.
20182                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20183                            }
20184                        }
20185                    }
20186                    app.trimMemoryLevel = curLevel;
20187                    step++;
20188                    if (step >= factor) {
20189                        step = 0;
20190                        switch (curLevel) {
20191                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20192                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20193                                break;
20194                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20195                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20196                                break;
20197                        }
20198                    }
20199                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20200                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20201                            && app.thread != null) {
20202                        try {
20203                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20204                                    "Trimming memory of heavy-weight " + app.processName
20205                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20206                            app.thread.scheduleTrimMemory(
20207                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20208                        } catch (RemoteException e) {
20209                        }
20210                    }
20211                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20212                } else {
20213                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20214                            || app.systemNoUi) && app.pendingUiClean) {
20215                        // If this application is now in the background and it
20216                        // had done UI, then give it the special trim level to
20217                        // have it free UI resources.
20218                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20219                        if (app.trimMemoryLevel < level && app.thread != null) {
20220                            try {
20221                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20222                                        "Trimming memory of bg-ui " + app.processName
20223                                        + " to " + level);
20224                                app.thread.scheduleTrimMemory(level);
20225                            } catch (RemoteException e) {
20226                            }
20227                        }
20228                        app.pendingUiClean = false;
20229                    }
20230                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20231                        try {
20232                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20233                                    "Trimming memory of fg " + app.processName
20234                                    + " to " + fgTrimLevel);
20235                            app.thread.scheduleTrimMemory(fgTrimLevel);
20236                        } catch (RemoteException e) {
20237                        }
20238                    }
20239                    app.trimMemoryLevel = fgTrimLevel;
20240                }
20241            }
20242        } else {
20243            if (mLowRamStartTime != 0) {
20244                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20245                mLowRamStartTime = 0;
20246            }
20247            for (int i=N-1; i>=0; i--) {
20248                ProcessRecord app = mLruProcesses.get(i);
20249                if (allChanged || app.procStateChanged) {
20250                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20251                    app.procStateChanged = false;
20252                }
20253                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20254                        || app.systemNoUi) && app.pendingUiClean) {
20255                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20256                            && app.thread != null) {
20257                        try {
20258                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20259                                    "Trimming memory of ui hidden " + app.processName
20260                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20261                            app.thread.scheduleTrimMemory(
20262                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20263                        } catch (RemoteException e) {
20264                        }
20265                    }
20266                    app.pendingUiClean = false;
20267                }
20268                app.trimMemoryLevel = 0;
20269            }
20270        }
20271
20272        if (mAlwaysFinishActivities) {
20273            // Need to do this on its own message because the stack may not
20274            // be in a consistent state at this point.
20275            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20276        }
20277
20278        if (allChanged) {
20279            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20280        }
20281
20282        // Update from any uid changes.
20283        for (int i=mActiveUids.size()-1; i>=0; i--) {
20284            final UidRecord uidRec = mActiveUids.valueAt(i);
20285            int uidChange = UidRecord.CHANGE_PROCSTATE;
20286            if (uidRec.setProcState != uidRec.curProcState) {
20287                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20288                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20289                        + " to " + uidRec.curProcState);
20290                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20291                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20292                        uidRec.lastBackgroundTime = nowElapsed;
20293                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20294                            // Note: the background settle time is in elapsed realtime, while
20295                            // the handler time base is uptime.  All this means is that we may
20296                            // stop background uids later than we had intended, but that only
20297                            // happens because the device was sleeping so we are okay anyway.
20298                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20299                        }
20300                    }
20301                } else {
20302                    if (uidRec.idle) {
20303                        uidChange = UidRecord.CHANGE_ACTIVE;
20304                        uidRec.idle = false;
20305                    }
20306                    uidRec.lastBackgroundTime = 0;
20307                }
20308                uidRec.setProcState = uidRec.curProcState;
20309                enqueueUidChangeLocked(uidRec, -1, uidChange);
20310                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20311            }
20312        }
20313
20314        if (mProcessStats.shouldWriteNowLocked(now)) {
20315            mHandler.post(new Runnable() {
20316                @Override public void run() {
20317                    synchronized (ActivityManagerService.this) {
20318                        mProcessStats.writeStateAsyncLocked();
20319                    }
20320                }
20321            });
20322        }
20323
20324        if (DEBUG_OOM_ADJ) {
20325            final long duration = SystemClock.uptimeMillis() - now;
20326            if (false) {
20327                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20328                        new RuntimeException("here").fillInStackTrace());
20329            } else {
20330                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20331            }
20332        }
20333    }
20334
20335    final void idleUids() {
20336        synchronized (this) {
20337            final long nowElapsed = SystemClock.elapsedRealtime();
20338            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20339            long nextTime = 0;
20340            for (int i=mActiveUids.size()-1; i>=0; i--) {
20341                final UidRecord uidRec = mActiveUids.valueAt(i);
20342                final long bgTime = uidRec.lastBackgroundTime;
20343                if (bgTime > 0 && !uidRec.idle) {
20344                    if (bgTime <= maxBgTime) {
20345                        uidRec.idle = true;
20346                        doStopUidLocked(uidRec.uid, uidRec);
20347                    } else {
20348                        if (nextTime == 0 || nextTime > bgTime) {
20349                            nextTime = bgTime;
20350                        }
20351                    }
20352                }
20353            }
20354            if (nextTime > 0) {
20355                mHandler.removeMessages(IDLE_UIDS_MSG);
20356                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20357                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20358            }
20359        }
20360    }
20361
20362    final void runInBackgroundDisabled(int uid) {
20363        synchronized (this) {
20364            UidRecord uidRec = mActiveUids.get(uid);
20365            if (uidRec != null) {
20366                // This uid is actually running...  should it be considered background now?
20367                if (uidRec.idle) {
20368                    doStopUidLocked(uidRec.uid, uidRec);
20369                }
20370            } else {
20371                // This uid isn't actually running...  still send a report about it being "stopped".
20372                doStopUidLocked(uid, null);
20373            }
20374        }
20375    }
20376
20377    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20378        mServices.stopInBackgroundLocked(uid);
20379        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20380    }
20381
20382    final void trimApplications() {
20383        synchronized (this) {
20384            int i;
20385
20386            // First remove any unused application processes whose package
20387            // has been removed.
20388            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20389                final ProcessRecord app = mRemovedProcesses.get(i);
20390                if (app.activities.size() == 0
20391                        && app.curReceiver == null && app.services.size() == 0) {
20392                    Slog.i(
20393                        TAG, "Exiting empty application process "
20394                        + app.processName + " ("
20395                        + (app.thread != null ? app.thread.asBinder() : null)
20396                        + ")\n");
20397                    if (app.pid > 0 && app.pid != MY_PID) {
20398                        app.kill("empty", false);
20399                    } else {
20400                        try {
20401                            app.thread.scheduleExit();
20402                        } catch (Exception e) {
20403                            // Ignore exceptions.
20404                        }
20405                    }
20406                    cleanUpApplicationRecordLocked(app, false, true, -1);
20407                    mRemovedProcesses.remove(i);
20408
20409                    if (app.persistent) {
20410                        addAppLocked(app.info, false, null /* ABI override */);
20411                    }
20412                }
20413            }
20414
20415            // Now update the oom adj for all processes.
20416            updateOomAdjLocked();
20417        }
20418    }
20419
20420    /** This method sends the specified signal to each of the persistent apps */
20421    public void signalPersistentProcesses(int sig) throws RemoteException {
20422        if (sig != Process.SIGNAL_USR1) {
20423            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20424        }
20425
20426        synchronized (this) {
20427            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20428                    != PackageManager.PERMISSION_GRANTED) {
20429                throw new SecurityException("Requires permission "
20430                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20431            }
20432
20433            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20434                ProcessRecord r = mLruProcesses.get(i);
20435                if (r.thread != null && r.persistent) {
20436                    Process.sendSignal(r.pid, sig);
20437                }
20438            }
20439        }
20440    }
20441
20442    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20443        if (proc == null || proc == mProfileProc) {
20444            proc = mProfileProc;
20445            profileType = mProfileType;
20446            clearProfilerLocked();
20447        }
20448        if (proc == null) {
20449            return;
20450        }
20451        try {
20452            proc.thread.profilerControl(false, null, profileType);
20453        } catch (RemoteException e) {
20454            throw new IllegalStateException("Process disappeared");
20455        }
20456    }
20457
20458    private void clearProfilerLocked() {
20459        if (mProfileFd != null) {
20460            try {
20461                mProfileFd.close();
20462            } catch (IOException e) {
20463            }
20464        }
20465        mProfileApp = null;
20466        mProfileProc = null;
20467        mProfileFile = null;
20468        mProfileType = 0;
20469        mAutoStopProfiler = false;
20470        mSamplingInterval = 0;
20471    }
20472
20473    public boolean profileControl(String process, int userId, boolean start,
20474            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20475
20476        try {
20477            synchronized (this) {
20478                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20479                // its own permission.
20480                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20481                        != PackageManager.PERMISSION_GRANTED) {
20482                    throw new SecurityException("Requires permission "
20483                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20484                }
20485
20486                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20487                    throw new IllegalArgumentException("null profile info or fd");
20488                }
20489
20490                ProcessRecord proc = null;
20491                if (process != null) {
20492                    proc = findProcessLocked(process, userId, "profileControl");
20493                }
20494
20495                if (start && (proc == null || proc.thread == null)) {
20496                    throw new IllegalArgumentException("Unknown process: " + process);
20497                }
20498
20499                if (start) {
20500                    stopProfilerLocked(null, 0);
20501                    setProfileApp(proc.info, proc.processName, profilerInfo);
20502                    mProfileProc = proc;
20503                    mProfileType = profileType;
20504                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20505                    try {
20506                        fd = fd.dup();
20507                    } catch (IOException e) {
20508                        fd = null;
20509                    }
20510                    profilerInfo.profileFd = fd;
20511                    proc.thread.profilerControl(start, profilerInfo, profileType);
20512                    fd = null;
20513                    mProfileFd = null;
20514                } else {
20515                    stopProfilerLocked(proc, profileType);
20516                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20517                        try {
20518                            profilerInfo.profileFd.close();
20519                        } catch (IOException e) {
20520                        }
20521                    }
20522                }
20523
20524                return true;
20525            }
20526        } catch (RemoteException e) {
20527            throw new IllegalStateException("Process disappeared");
20528        } finally {
20529            if (profilerInfo != null && profilerInfo.profileFd != null) {
20530                try {
20531                    profilerInfo.profileFd.close();
20532                } catch (IOException e) {
20533                }
20534            }
20535        }
20536    }
20537
20538    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20539        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20540                userId, true, ALLOW_FULL_ONLY, callName, null);
20541        ProcessRecord proc = null;
20542        try {
20543            int pid = Integer.parseInt(process);
20544            synchronized (mPidsSelfLocked) {
20545                proc = mPidsSelfLocked.get(pid);
20546            }
20547        } catch (NumberFormatException e) {
20548        }
20549
20550        if (proc == null) {
20551            ArrayMap<String, SparseArray<ProcessRecord>> all
20552                    = mProcessNames.getMap();
20553            SparseArray<ProcessRecord> procs = all.get(process);
20554            if (procs != null && procs.size() > 0) {
20555                proc = procs.valueAt(0);
20556                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20557                    for (int i=1; i<procs.size(); i++) {
20558                        ProcessRecord thisProc = procs.valueAt(i);
20559                        if (thisProc.userId == userId) {
20560                            proc = thisProc;
20561                            break;
20562                        }
20563                    }
20564                }
20565            }
20566        }
20567
20568        return proc;
20569    }
20570
20571    public boolean dumpHeap(String process, int userId, boolean managed,
20572            String path, ParcelFileDescriptor fd) throws RemoteException {
20573
20574        try {
20575            synchronized (this) {
20576                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20577                // its own permission (same as profileControl).
20578                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20579                        != PackageManager.PERMISSION_GRANTED) {
20580                    throw new SecurityException("Requires permission "
20581                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20582                }
20583
20584                if (fd == null) {
20585                    throw new IllegalArgumentException("null fd");
20586                }
20587
20588                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20589                if (proc == null || proc.thread == null) {
20590                    throw new IllegalArgumentException("Unknown process: " + process);
20591                }
20592
20593                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20594                if (!isDebuggable) {
20595                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20596                        throw new SecurityException("Process not debuggable: " + proc);
20597                    }
20598                }
20599
20600                proc.thread.dumpHeap(managed, path, fd);
20601                fd = null;
20602                return true;
20603            }
20604        } catch (RemoteException e) {
20605            throw new IllegalStateException("Process disappeared");
20606        } finally {
20607            if (fd != null) {
20608                try {
20609                    fd.close();
20610                } catch (IOException e) {
20611                }
20612            }
20613        }
20614    }
20615
20616    @Override
20617    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20618            String reportPackage) {
20619        if (processName != null) {
20620            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20621                    "setDumpHeapDebugLimit()");
20622        } else {
20623            synchronized (mPidsSelfLocked) {
20624                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20625                if (proc == null) {
20626                    throw new SecurityException("No process found for calling pid "
20627                            + Binder.getCallingPid());
20628                }
20629                if (!Build.IS_DEBUGGABLE
20630                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20631                    throw new SecurityException("Not running a debuggable build");
20632                }
20633                processName = proc.processName;
20634                uid = proc.uid;
20635                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20636                    throw new SecurityException("Package " + reportPackage + " is not running in "
20637                            + proc);
20638                }
20639            }
20640        }
20641        synchronized (this) {
20642            if (maxMemSize > 0) {
20643                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20644            } else {
20645                if (uid != 0) {
20646                    mMemWatchProcesses.remove(processName, uid);
20647                } else {
20648                    mMemWatchProcesses.getMap().remove(processName);
20649                }
20650            }
20651        }
20652    }
20653
20654    @Override
20655    public void dumpHeapFinished(String path) {
20656        synchronized (this) {
20657            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20658                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20659                        + " does not match last pid " + mMemWatchDumpPid);
20660                return;
20661            }
20662            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20663                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20664                        + " does not match last path " + mMemWatchDumpFile);
20665                return;
20666            }
20667            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20668            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20669        }
20670    }
20671
20672    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20673    public void monitor() {
20674        synchronized (this) { }
20675    }
20676
20677    void onCoreSettingsChange(Bundle settings) {
20678        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20679            ProcessRecord processRecord = mLruProcesses.get(i);
20680            try {
20681                if (processRecord.thread != null) {
20682                    processRecord.thread.setCoreSettings(settings);
20683                }
20684            } catch (RemoteException re) {
20685                /* ignore */
20686            }
20687        }
20688    }
20689
20690    // Multi-user methods
20691
20692    /**
20693     * Start user, if its not already running, but don't bring it to foreground.
20694     */
20695    @Override
20696    public boolean startUserInBackground(final int userId) {
20697        return mUserController.startUser(userId, /* foreground */ false);
20698    }
20699
20700    @Override
20701    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20702        return mUserController.unlockUser(userId, token, secret, listener);
20703    }
20704
20705    @Override
20706    public boolean switchUser(final int targetUserId) {
20707        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20708        UserInfo currentUserInfo;
20709        UserInfo targetUserInfo;
20710        synchronized (this) {
20711            int currentUserId = mUserController.getCurrentUserIdLocked();
20712            currentUserInfo = mUserController.getUserInfo(currentUserId);
20713            targetUserInfo = mUserController.getUserInfo(targetUserId);
20714            if (targetUserInfo == null) {
20715                Slog.w(TAG, "No user info for user #" + targetUserId);
20716                return false;
20717            }
20718            if (!targetUserInfo.supportsSwitchTo()) {
20719                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20720                return false;
20721            }
20722            if (targetUserInfo.isManagedProfile()) {
20723                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20724                return false;
20725            }
20726            mUserController.setTargetUserIdLocked(targetUserId);
20727        }
20728        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20729        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20730        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20731        return true;
20732    }
20733
20734    void scheduleStartProfilesLocked() {
20735        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20736            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20737                    DateUtils.SECOND_IN_MILLIS);
20738        }
20739    }
20740
20741    @Override
20742    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20743        return mUserController.stopUser(userId, force, callback);
20744    }
20745
20746    @Override
20747    public UserInfo getCurrentUser() {
20748        return mUserController.getCurrentUser();
20749    }
20750
20751    @Override
20752    public boolean isUserRunning(int userId, int flags) {
20753        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20754                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20755            String msg = "Permission Denial: isUserRunning() from pid="
20756                    + Binder.getCallingPid()
20757                    + ", uid=" + Binder.getCallingUid()
20758                    + " requires " + INTERACT_ACROSS_USERS;
20759            Slog.w(TAG, msg);
20760            throw new SecurityException(msg);
20761        }
20762        synchronized (this) {
20763            return mUserController.isUserRunningLocked(userId, flags);
20764        }
20765    }
20766
20767    @Override
20768    public int[] getRunningUserIds() {
20769        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20770                != PackageManager.PERMISSION_GRANTED) {
20771            String msg = "Permission Denial: isUserRunning() from pid="
20772                    + Binder.getCallingPid()
20773                    + ", uid=" + Binder.getCallingUid()
20774                    + " requires " + INTERACT_ACROSS_USERS;
20775            Slog.w(TAG, msg);
20776            throw new SecurityException(msg);
20777        }
20778        synchronized (this) {
20779            return mUserController.getStartedUserArrayLocked();
20780        }
20781    }
20782
20783    @Override
20784    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20785        mUserController.registerUserSwitchObserver(observer);
20786    }
20787
20788    @Override
20789    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20790        mUserController.unregisterUserSwitchObserver(observer);
20791    }
20792
20793    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20794        if (info == null) return null;
20795        ApplicationInfo newInfo = new ApplicationInfo(info);
20796        newInfo.initForUser(userId);
20797        return newInfo;
20798    }
20799
20800    public boolean isUserStopped(int userId) {
20801        synchronized (this) {
20802            return mUserController.getStartedUserStateLocked(userId) == null;
20803        }
20804    }
20805
20806    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20807        if (aInfo == null
20808                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20809            return aInfo;
20810        }
20811
20812        ActivityInfo info = new ActivityInfo(aInfo);
20813        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20814        return info;
20815    }
20816
20817    private boolean processSanityChecksLocked(ProcessRecord process) {
20818        if (process == null || process.thread == null) {
20819            return false;
20820        }
20821
20822        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20823        if (!isDebuggable) {
20824            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20825                return false;
20826            }
20827        }
20828
20829        return true;
20830    }
20831
20832    public boolean startBinderTracking() throws RemoteException {
20833        synchronized (this) {
20834            mBinderTransactionTrackingEnabled = true;
20835            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20836            // permission (same as profileControl).
20837            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20838                    != PackageManager.PERMISSION_GRANTED) {
20839                throw new SecurityException("Requires permission "
20840                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20841            }
20842
20843            for (int i = 0; i < mLruProcesses.size(); i++) {
20844                ProcessRecord process = mLruProcesses.get(i);
20845                if (!processSanityChecksLocked(process)) {
20846                    continue;
20847                }
20848                try {
20849                    process.thread.startBinderTracking();
20850                } catch (RemoteException e) {
20851                    Log.v(TAG, "Process disappared");
20852                }
20853            }
20854            return true;
20855        }
20856    }
20857
20858    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20859        try {
20860            synchronized (this) {
20861                mBinderTransactionTrackingEnabled = false;
20862                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20863                // permission (same as profileControl).
20864                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20865                        != PackageManager.PERMISSION_GRANTED) {
20866                    throw new SecurityException("Requires permission "
20867                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20868                }
20869
20870                if (fd == null) {
20871                    throw new IllegalArgumentException("null fd");
20872                }
20873
20874                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20875                pw.println("Binder transaction traces for all processes.\n");
20876                for (ProcessRecord process : mLruProcesses) {
20877                    if (!processSanityChecksLocked(process)) {
20878                        continue;
20879                    }
20880
20881                    pw.println("Traces for process: " + process.processName);
20882                    pw.flush();
20883                    try {
20884                        TransferPipe tp = new TransferPipe();
20885                        try {
20886                            process.thread.stopBinderTrackingAndDump(
20887                                    tp.getWriteFd().getFileDescriptor());
20888                            tp.go(fd.getFileDescriptor());
20889                        } finally {
20890                            tp.kill();
20891                        }
20892                    } catch (IOException e) {
20893                        pw.println("Failure while dumping IPC traces from " + process +
20894                                ".  Exception: " + e);
20895                        pw.flush();
20896                    } catch (RemoteException e) {
20897                        pw.println("Got a RemoteException while dumping IPC traces from " +
20898                                process + ".  Exception: " + e);
20899                        pw.flush();
20900                    }
20901                }
20902                fd = null;
20903                return true;
20904            }
20905        } finally {
20906            if (fd != null) {
20907                try {
20908                    fd.close();
20909                } catch (IOException e) {
20910                }
20911            }
20912        }
20913    }
20914
20915    private final class LocalService extends ActivityManagerInternal {
20916        @Override
20917        public void onWakefulnessChanged(int wakefulness) {
20918            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20919        }
20920
20921        @Override
20922        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20923                String processName, String abiOverride, int uid, Runnable crashHandler) {
20924            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20925                    processName, abiOverride, uid, crashHandler);
20926        }
20927
20928        @Override
20929        public SleepToken acquireSleepToken(String tag) {
20930            Preconditions.checkNotNull(tag);
20931
20932            synchronized (ActivityManagerService.this) {
20933                SleepTokenImpl token = new SleepTokenImpl(tag);
20934                mSleepTokens.add(token);
20935                updateSleepIfNeededLocked();
20936                applyVrModeIfNeededLocked(mFocusedActivity, false);
20937                return token;
20938            }
20939        }
20940
20941        @Override
20942        public ComponentName getHomeActivityForUser(int userId) {
20943            synchronized (ActivityManagerService.this) {
20944                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20945                return homeActivity == null ? null : homeActivity.realActivity;
20946            }
20947        }
20948
20949        @Override
20950        public void onUserRemoved(int userId) {
20951            synchronized (ActivityManagerService.this) {
20952                ActivityManagerService.this.onUserStoppedLocked(userId);
20953            }
20954        }
20955
20956        @Override
20957        public void onLocalVoiceInteractionStarted(IBinder activity,
20958                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20959            synchronized (ActivityManagerService.this) {
20960                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20961                        voiceSession, voiceInteractor);
20962            }
20963        }
20964
20965        @Override
20966        public void notifyStartingWindowDrawn() {
20967            synchronized (ActivityManagerService.this) {
20968                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20969            }
20970        }
20971
20972        @Override
20973        public void notifyAppTransitionStarting(int reason) {
20974            synchronized (ActivityManagerService.this) {
20975                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20976            }
20977        }
20978
20979        @Override
20980        public void notifyAppTransitionFinished() {
20981            synchronized (ActivityManagerService.this) {
20982                mStackSupervisor.notifyAppTransitionDone();
20983            }
20984        }
20985
20986        @Override
20987        public void notifyAppTransitionCancelled() {
20988            synchronized (ActivityManagerService.this) {
20989                mStackSupervisor.notifyAppTransitionDone();
20990            }
20991        }
20992
20993        @Override
20994        public List<IBinder> getTopVisibleActivities() {
20995            synchronized (ActivityManagerService.this) {
20996                return mStackSupervisor.getTopVisibleActivities();
20997            }
20998        }
20999
21000        @Override
21001        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21002            synchronized (ActivityManagerService.this) {
21003                mStackSupervisor.setDockedStackMinimized(minimized);
21004            }
21005        }
21006
21007        @Override
21008        public void killForegroundAppsForUser(int userHandle) {
21009            synchronized (ActivityManagerService.this) {
21010                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21011                final int NP = mProcessNames.getMap().size();
21012                for (int ip = 0; ip < NP; ip++) {
21013                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21014                    final int NA = apps.size();
21015                    for (int ia = 0; ia < NA; ia++) {
21016                        final ProcessRecord app = apps.valueAt(ia);
21017                        if (app.persistent) {
21018                            // We don't kill persistent processes.
21019                            continue;
21020                        }
21021                        if (app.removed) {
21022                            procs.add(app);
21023                        } else if (app.userId == userHandle && app.foregroundActivities) {
21024                            app.removed = true;
21025                            procs.add(app);
21026                        }
21027                    }
21028                }
21029
21030                final int N = procs.size();
21031                for (int i = 0; i < N; i++) {
21032                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21033                }
21034            }
21035        }
21036    }
21037
21038    private final class SleepTokenImpl extends SleepToken {
21039        private final String mTag;
21040        private final long mAcquireTime;
21041
21042        public SleepTokenImpl(String tag) {
21043            mTag = tag;
21044            mAcquireTime = SystemClock.uptimeMillis();
21045        }
21046
21047        @Override
21048        public void release() {
21049            synchronized (ActivityManagerService.this) {
21050                if (mSleepTokens.remove(this)) {
21051                    updateSleepIfNeededLocked();
21052                }
21053            }
21054        }
21055
21056        @Override
21057        public String toString() {
21058            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21059        }
21060    }
21061
21062    /**
21063     * An implementation of IAppTask, that allows an app to manage its own tasks via
21064     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21065     * only the process that calls getAppTasks() can call the AppTask methods.
21066     */
21067    class AppTaskImpl extends IAppTask.Stub {
21068        private int mTaskId;
21069        private int mCallingUid;
21070
21071        public AppTaskImpl(int taskId, int callingUid) {
21072            mTaskId = taskId;
21073            mCallingUid = callingUid;
21074        }
21075
21076        private void checkCaller() {
21077            if (mCallingUid != Binder.getCallingUid()) {
21078                throw new SecurityException("Caller " + mCallingUid
21079                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21080            }
21081        }
21082
21083        @Override
21084        public void finishAndRemoveTask() {
21085            checkCaller();
21086
21087            synchronized (ActivityManagerService.this) {
21088                long origId = Binder.clearCallingIdentity();
21089                try {
21090                    // We remove the task from recents to preserve backwards
21091                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21092                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21093                    }
21094                } finally {
21095                    Binder.restoreCallingIdentity(origId);
21096                }
21097            }
21098        }
21099
21100        @Override
21101        public ActivityManager.RecentTaskInfo getTaskInfo() {
21102            checkCaller();
21103
21104            synchronized (ActivityManagerService.this) {
21105                long origId = Binder.clearCallingIdentity();
21106                try {
21107                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21108                    if (tr == null) {
21109                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21110                    }
21111                    return createRecentTaskInfoFromTaskRecord(tr);
21112                } finally {
21113                    Binder.restoreCallingIdentity(origId);
21114                }
21115            }
21116        }
21117
21118        @Override
21119        public void moveToFront() {
21120            checkCaller();
21121            // Will bring task to front if it already has a root activity.
21122            final long origId = Binder.clearCallingIdentity();
21123            try {
21124                synchronized (this) {
21125                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21126                }
21127            } finally {
21128                Binder.restoreCallingIdentity(origId);
21129            }
21130        }
21131
21132        @Override
21133        public int startActivity(IBinder whoThread, String callingPackage,
21134                Intent intent, String resolvedType, Bundle bOptions) {
21135            checkCaller();
21136
21137            int callingUser = UserHandle.getCallingUserId();
21138            TaskRecord tr;
21139            IApplicationThread appThread;
21140            synchronized (ActivityManagerService.this) {
21141                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21142                if (tr == null) {
21143                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21144                }
21145                appThread = ApplicationThreadNative.asInterface(whoThread);
21146                if (appThread == null) {
21147                    throw new IllegalArgumentException("Bad app thread " + appThread);
21148                }
21149            }
21150            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21151                    resolvedType, null, null, null, null, 0, 0, null, null,
21152                    null, bOptions, false, callingUser, null, tr);
21153        }
21154
21155        @Override
21156        public void setExcludeFromRecents(boolean exclude) {
21157            checkCaller();
21158
21159            synchronized (ActivityManagerService.this) {
21160                long origId = Binder.clearCallingIdentity();
21161                try {
21162                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21163                    if (tr == null) {
21164                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21165                    }
21166                    Intent intent = tr.getBaseIntent();
21167                    if (exclude) {
21168                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21169                    } else {
21170                        intent.setFlags(intent.getFlags()
21171                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21172                    }
21173                } finally {
21174                    Binder.restoreCallingIdentity(origId);
21175                }
21176            }
21177        }
21178    }
21179
21180    /**
21181     * Kill processes for the user with id userId and that depend on the package named packageName
21182     */
21183    @Override
21184    public void killPackageDependents(String packageName, int userId) {
21185        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21186        if (packageName == null) {
21187            throw new NullPointerException(
21188                    "Cannot kill the dependents of a package without its name.");
21189        }
21190
21191        long callingId = Binder.clearCallingIdentity();
21192        IPackageManager pm = AppGlobals.getPackageManager();
21193        int pkgUid = -1;
21194        try {
21195            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21196        } catch (RemoteException e) {
21197        }
21198        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21199            throw new IllegalArgumentException(
21200                    "Cannot kill dependents of non-existing package " + packageName);
21201        }
21202        try {
21203            synchronized(this) {
21204                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21205                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21206                        "dep: " + packageName);
21207            }
21208        } finally {
21209            Binder.restoreCallingIdentity(callingId);
21210        }
21211    }
21212}
21213