ActivityManagerService.java revision ea05cd57f5b2b26650276a7ff03053e7cb78c538
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.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
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.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
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.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1517
1518    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1519    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1520    static final int FIRST_COMPAT_MODE_MSG = 300;
1521    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1522
1523    static ServiceThread sKillThread = null;
1524    static KillHandler sKillHandler = null;
1525
1526    CompatModeDialog mCompatModeDialog;
1527    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1528    long mLastMemUsageReportTime = 0;
1529
1530    /**
1531     * Flag whether the current user is a "monkey", i.e. whether
1532     * the UI is driven by a UI automation tool.
1533     */
1534    private boolean mUserIsMonkey;
1535
1536    /** Flag whether the device has a Recents UI */
1537    boolean mHasRecents;
1538
1539    /** The dimensions of the thumbnails in the Recents UI. */
1540    int mThumbnailWidth;
1541    int mThumbnailHeight;
1542    float mFullscreenThumbnailScale;
1543
1544    final ServiceThread mHandlerThread;
1545    final MainHandler mHandler;
1546    final UiHandler mUiHandler;
1547
1548    PackageManagerInternal mPackageManagerInt;
1549
1550    // VoiceInteraction session ID that changes for each new request except when
1551    // being called for multiwindow assist in a single session.
1552    private int mViSessionId = 1000;
1553
1554    final class KillHandler extends Handler {
1555        static final int KILL_PROCESS_GROUP_MSG = 4000;
1556
1557        public KillHandler(Looper looper) {
1558            super(looper, null, true);
1559        }
1560
1561        @Override
1562        public void handleMessage(Message msg) {
1563            switch (msg.what) {
1564                case KILL_PROCESS_GROUP_MSG:
1565                {
1566                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1567                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1568                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1569                }
1570                break;
1571
1572                default:
1573                    super.handleMessage(msg);
1574            }
1575        }
1576    }
1577
1578    final class UiHandler extends Handler {
1579        public UiHandler() {
1580            super(com.android.server.UiThread.get().getLooper(), null, true);
1581        }
1582
1583        @Override
1584        public void handleMessage(Message msg) {
1585            switch (msg.what) {
1586            case SHOW_ERROR_UI_MSG: {
1587                mAppErrors.handleShowAppErrorUi(msg);
1588                ensureBootCompleted();
1589            } break;
1590            case SHOW_NOT_RESPONDING_UI_MSG: {
1591                mAppErrors.handleShowAnrUi(msg);
1592                ensureBootCompleted();
1593            } break;
1594            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1595                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1596                synchronized (ActivityManagerService.this) {
1597                    ProcessRecord proc = (ProcessRecord) data.get("app");
1598                    if (proc == null) {
1599                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1600                        break;
1601                    }
1602                    if (proc.crashDialog != null) {
1603                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1604                        return;
1605                    }
1606                    AppErrorResult res = (AppErrorResult) data.get("result");
1607                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1608                        Dialog d = new StrictModeViolationDialog(mContext,
1609                                ActivityManagerService.this, res, proc);
1610                        d.show();
1611                        proc.crashDialog = d;
1612                    } else {
1613                        // The device is asleep, so just pretend that the user
1614                        // saw a crash dialog and hit "force quit".
1615                        res.set(0);
1616                    }
1617                }
1618                ensureBootCompleted();
1619            } break;
1620            case SHOW_FACTORY_ERROR_UI_MSG: {
1621                Dialog d = new FactoryErrorDialog(
1622                    mContext, msg.getData().getCharSequence("msg"));
1623                d.show();
1624                ensureBootCompleted();
1625            } break;
1626            case WAIT_FOR_DEBUGGER_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ProcessRecord app = (ProcessRecord)msg.obj;
1629                    if (msg.arg1 != 0) {
1630                        if (!app.waitedForDebugger) {
1631                            Dialog d = new AppWaitingForDebuggerDialog(
1632                                    ActivityManagerService.this,
1633                                    mContext, app);
1634                            app.waitDialog = d;
1635                            app.waitedForDebugger = true;
1636                            d.show();
1637                        }
1638                    } else {
1639                        if (app.waitDialog != null) {
1640                            app.waitDialog.dismiss();
1641                            app.waitDialog = null;
1642                        }
1643                    }
1644                }
1645            } break;
1646            case SHOW_UID_ERROR_UI_MSG: {
1647                if (mShowDialogs) {
1648                    AlertDialog d = new BaseErrorDialog(mContext);
1649                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1650                    d.setCancelable(false);
1651                    d.setTitle(mContext.getText(R.string.android_system_label));
1652                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1653                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1654                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1655                    d.show();
1656                }
1657            } break;
1658            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1659                if (mShowDialogs) {
1660                    AlertDialog d = new BaseErrorDialog(mContext);
1661                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1662                    d.setCancelable(false);
1663                    d.setTitle(mContext.getText(R.string.android_system_label));
1664                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1665                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1666                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1667                    d.show();
1668                }
1669            } break;
1670            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1671                synchronized (ActivityManagerService.this) {
1672                    ActivityRecord ar = (ActivityRecord) msg.obj;
1673                    if (mCompatModeDialog != null) {
1674                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1675                                ar.info.applicationInfo.packageName)) {
1676                            return;
1677                        }
1678                        mCompatModeDialog.dismiss();
1679                        mCompatModeDialog = null;
1680                    }
1681                    if (ar != null && false) {
1682                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1683                                ar.packageName)) {
1684                            int mode = mCompatModePackages.computeCompatModeLocked(
1685                                    ar.info.applicationInfo);
1686                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1687                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1688                                mCompatModeDialog = new CompatModeDialog(
1689                                        ActivityManagerService.this, mContext,
1690                                        ar.info.applicationInfo);
1691                                mCompatModeDialog.show();
1692                            }
1693                        }
1694                    }
1695                }
1696                break;
1697            }
1698            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1701                    if (mUnsupportedDisplaySizeDialog != null) {
1702                        mUnsupportedDisplaySizeDialog.dismiss();
1703                        mUnsupportedDisplaySizeDialog = null;
1704                    }
1705                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1706                            ar.packageName)) {
1707                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1708                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1709                        mUnsupportedDisplaySizeDialog.show();
1710                    }
1711                }
1712                break;
1713            }
1714            case START_USER_SWITCH_UI_MSG: {
1715                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1716                break;
1717            }
1718            case DISMISS_DIALOG_UI_MSG: {
1719                final Dialog d = (Dialog) msg.obj;
1720                d.dismiss();
1721                break;
1722            }
1723            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1724                dispatchProcessesChanged();
1725                break;
1726            }
1727            case DISPATCH_PROCESS_DIED_UI_MSG: {
1728                final int pid = msg.arg1;
1729                final int uid = msg.arg2;
1730                dispatchProcessDied(pid, uid);
1731                break;
1732            }
1733            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1734                dispatchUidsChanged();
1735            } break;
1736            }
1737        }
1738    }
1739
1740    final class MainHandler extends Handler {
1741        public MainHandler(Looper looper) {
1742            super(looper, null, true);
1743        }
1744
1745        @Override
1746        public void handleMessage(Message msg) {
1747            switch (msg.what) {
1748            case UPDATE_CONFIGURATION_MSG: {
1749                final ContentResolver resolver = mContext.getContentResolver();
1750                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1751                        msg.arg1);
1752            } break;
1753            case GC_BACKGROUND_PROCESSES_MSG: {
1754                synchronized (ActivityManagerService.this) {
1755                    performAppGcsIfAppropriateLocked();
1756                }
1757            } break;
1758            case SERVICE_TIMEOUT_MSG: {
1759                if (mDidDexOpt) {
1760                    mDidDexOpt = false;
1761                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1762                    nmsg.obj = msg.obj;
1763                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1764                    return;
1765                }
1766                mServices.serviceTimeout((ProcessRecord)msg.obj);
1767            } break;
1768            case UPDATE_TIME_ZONE: {
1769                synchronized (ActivityManagerService.this) {
1770                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1771                        ProcessRecord r = mLruProcesses.get(i);
1772                        if (r.thread != null) {
1773                            try {
1774                                r.thread.updateTimeZone();
1775                            } catch (RemoteException ex) {
1776                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1777                            }
1778                        }
1779                    }
1780                }
1781            } break;
1782            case CLEAR_DNS_CACHE_MSG: {
1783                synchronized (ActivityManagerService.this) {
1784                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1785                        ProcessRecord r = mLruProcesses.get(i);
1786                        if (r.thread != null) {
1787                            try {
1788                                r.thread.clearDnsCache();
1789                            } catch (RemoteException ex) {
1790                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1791                            }
1792                        }
1793                    }
1794                }
1795            } break;
1796            case UPDATE_HTTP_PROXY_MSG: {
1797                ProxyInfo proxy = (ProxyInfo)msg.obj;
1798                String host = "";
1799                String port = "";
1800                String exclList = "";
1801                Uri pacFileUrl = Uri.EMPTY;
1802                if (proxy != null) {
1803                    host = proxy.getHost();
1804                    port = Integer.toString(proxy.getPort());
1805                    exclList = proxy.getExclusionListAsString();
1806                    pacFileUrl = proxy.getPacFileUrl();
1807                }
1808                synchronized (ActivityManagerService.this) {
1809                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1810                        ProcessRecord r = mLruProcesses.get(i);
1811                        if (r.thread != null) {
1812                            try {
1813                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1814                            } catch (RemoteException ex) {
1815                                Slog.w(TAG, "Failed to update http proxy for: " +
1816                                        r.info.processName);
1817                            }
1818                        }
1819                    }
1820                }
1821            } break;
1822            case PROC_START_TIMEOUT_MSG: {
1823                if (mDidDexOpt) {
1824                    mDidDexOpt = false;
1825                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1826                    nmsg.obj = msg.obj;
1827                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1828                    return;
1829                }
1830                ProcessRecord app = (ProcessRecord)msg.obj;
1831                synchronized (ActivityManagerService.this) {
1832                    processStartTimedOutLocked(app);
1833                }
1834            } break;
1835            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1836                ProcessRecord app = (ProcessRecord)msg.obj;
1837                synchronized (ActivityManagerService.this) {
1838                    processContentProviderPublishTimedOutLocked(app);
1839                }
1840            } break;
1841            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1842                synchronized (ActivityManagerService.this) {
1843                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1844                }
1845            } break;
1846            case KILL_APPLICATION_MSG: {
1847                synchronized (ActivityManagerService.this) {
1848                    int appid = msg.arg1;
1849                    boolean restart = (msg.arg2 == 1);
1850                    Bundle bundle = (Bundle)msg.obj;
1851                    String pkg = bundle.getString("pkg");
1852                    String reason = bundle.getString("reason");
1853                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1854                            false, UserHandle.USER_ALL, reason);
1855                }
1856            } break;
1857            case FINALIZE_PENDING_INTENT_MSG: {
1858                ((PendingIntentRecord)msg.obj).completeFinalize();
1859            } break;
1860            case POST_HEAVY_NOTIFICATION_MSG: {
1861                INotificationManager inm = NotificationManager.getService();
1862                if (inm == null) {
1863                    return;
1864                }
1865
1866                ActivityRecord root = (ActivityRecord)msg.obj;
1867                ProcessRecord process = root.app;
1868                if (process == null) {
1869                    return;
1870                }
1871
1872                try {
1873                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1874                    String text = mContext.getString(R.string.heavy_weight_notification,
1875                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1876                    Notification notification = new Notification.Builder(context)
1877                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1878                            .setWhen(0)
1879                            .setOngoing(true)
1880                            .setTicker(text)
1881                            .setColor(mContext.getColor(
1882                                    com.android.internal.R.color.system_notification_accent_color))
1883                            .setContentTitle(text)
1884                            .setContentText(
1885                                    mContext.getText(R.string.heavy_weight_notification_detail))
1886                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1887                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1888                                    new UserHandle(root.userId)))
1889                            .build();
1890                    try {
1891                        int[] outId = new int[1];
1892                        inm.enqueueNotificationWithTag("android", "android", null,
1893                                R.string.heavy_weight_notification,
1894                                notification, outId, root.userId);
1895                    } catch (RuntimeException e) {
1896                        Slog.w(ActivityManagerService.TAG,
1897                                "Error showing notification for heavy-weight app", e);
1898                    } catch (RemoteException e) {
1899                    }
1900                } catch (NameNotFoundException e) {
1901                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1902                }
1903            } break;
1904            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1905                INotificationManager inm = NotificationManager.getService();
1906                if (inm == null) {
1907                    return;
1908                }
1909                try {
1910                    inm.cancelNotificationWithTag("android", null,
1911                            R.string.heavy_weight_notification,  msg.arg1);
1912                } catch (RuntimeException e) {
1913                    Slog.w(ActivityManagerService.TAG,
1914                            "Error canceling notification for service", e);
1915                } catch (RemoteException e) {
1916                }
1917            } break;
1918            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1919                synchronized (ActivityManagerService.this) {
1920                    checkExcessivePowerUsageLocked(true);
1921                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1922                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1923                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1924                }
1925            } break;
1926            case REPORT_MEM_USAGE_MSG: {
1927                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1928                Thread thread = new Thread() {
1929                    @Override public void run() {
1930                        reportMemUsage(memInfos);
1931                    }
1932                };
1933                thread.start();
1934                break;
1935            }
1936            case REPORT_USER_SWITCH_MSG: {
1937                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1938                break;
1939            }
1940            case CONTINUE_USER_SWITCH_MSG: {
1941                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1942                break;
1943            }
1944            case USER_SWITCH_TIMEOUT_MSG: {
1945                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1946                break;
1947            }
1948            case IMMERSIVE_MODE_LOCK_MSG: {
1949                final boolean nextState = (msg.arg1 != 0);
1950                if (mUpdateLock.isHeld() != nextState) {
1951                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1952                            "Applying new update lock state '" + nextState
1953                            + "' for " + (ActivityRecord)msg.obj);
1954                    if (nextState) {
1955                        mUpdateLock.acquire();
1956                    } else {
1957                        mUpdateLock.release();
1958                    }
1959                }
1960                break;
1961            }
1962            case PERSIST_URI_GRANTS_MSG: {
1963                writeGrantedUriPermissions();
1964                break;
1965            }
1966            case REQUEST_ALL_PSS_MSG: {
1967                synchronized (ActivityManagerService.this) {
1968                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1969                }
1970                break;
1971            }
1972            case START_PROFILES_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    mUserController.startProfilesLocked();
1975                }
1976                break;
1977            }
1978            case UPDATE_TIME: {
1979                synchronized (ActivityManagerService.this) {
1980                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1981                        ProcessRecord r = mLruProcesses.get(i);
1982                        if (r.thread != null) {
1983                            try {
1984                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1985                            } catch (RemoteException ex) {
1986                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1987                            }
1988                        }
1989                    }
1990                }
1991                break;
1992            }
1993            case SYSTEM_USER_START_MSG: {
1994                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1995                        Integer.toString(msg.arg1), msg.arg1);
1996                mSystemServiceManager.startUser(msg.arg1);
1997                break;
1998            }
1999            case SYSTEM_USER_UNLOCK_MSG: {
2000                final int userId = msg.arg1;
2001                mSystemServiceManager.unlockUser(userId);
2002                synchronized (ActivityManagerService.this) {
2003                    mRecentTasks.loadUserRecentsLocked(userId);
2004                }
2005                if (userId == UserHandle.USER_SYSTEM) {
2006                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2007                }
2008                installEncryptionUnawareProviders(userId);
2009                mUserController.finishUserUnlocked((UserState) msg.obj);
2010                break;
2011            }
2012            case SYSTEM_USER_CURRENT_MSG: {
2013                mBatteryStatsService.noteEvent(
2014                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2015                        Integer.toString(msg.arg2), msg.arg2);
2016                mBatteryStatsService.noteEvent(
2017                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2018                        Integer.toString(msg.arg1), msg.arg1);
2019                mSystemServiceManager.switchUser(msg.arg1);
2020                break;
2021            }
2022            case ENTER_ANIMATION_COMPLETE_MSG: {
2023                synchronized (ActivityManagerService.this) {
2024                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2025                    if (r != null && r.app != null && r.app.thread != null) {
2026                        try {
2027                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2028                        } catch (RemoteException e) {
2029                        }
2030                    }
2031                }
2032                break;
2033            }
2034            case FINISH_BOOTING_MSG: {
2035                if (msg.arg1 != 0) {
2036                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2037                    finishBooting();
2038                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2039                }
2040                if (msg.arg2 != 0) {
2041                    enableScreenAfterBoot();
2042                }
2043                break;
2044            }
2045            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2046                try {
2047                    Locale l = (Locale) msg.obj;
2048                    IBinder service = ServiceManager.getService("mount");
2049                    IMountService mountService = IMountService.Stub.asInterface(service);
2050                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2051                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2052                } catch (RemoteException e) {
2053                    Log.e(TAG, "Error storing locale for decryption UI", e);
2054                }
2055                break;
2056            }
2057            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2058                synchronized (ActivityManagerService.this) {
2059                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2060                        try {
2061                            // Make a one-way callback to the listener
2062                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2063                        } catch (RemoteException e){
2064                            // Handled by the RemoteCallbackList
2065                        }
2066                    }
2067                    mTaskStackListeners.finishBroadcast();
2068                }
2069                break;
2070            }
2071            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2072                synchronized (ActivityManagerService.this) {
2073                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2074                        try {
2075                            // Make a one-way callback to the listener
2076                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2077                        } catch (RemoteException e){
2078                            // Handled by the RemoteCallbackList
2079                        }
2080                    }
2081                    mTaskStackListeners.finishBroadcast();
2082                }
2083                break;
2084            }
2085            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2086                synchronized (ActivityManagerService.this) {
2087                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2088                        try {
2089                            // Make a one-way callback to the listener
2090                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2091                        } catch (RemoteException e){
2092                            // Handled by the RemoteCallbackList
2093                        }
2094                    }
2095                    mTaskStackListeners.finishBroadcast();
2096                }
2097                break;
2098            }
2099            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2100                synchronized (ActivityManagerService.this) {
2101                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2102                        try {
2103                            // Make a one-way callback to the listener
2104                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2105                        } catch (RemoteException e){
2106                            // Handled by the RemoteCallbackList
2107                        }
2108                    }
2109                    mTaskStackListeners.finishBroadcast();
2110                }
2111                break;
2112            }
2113            case NOTIFY_FORCED_RESIZABLE_MSG: {
2114                synchronized (ActivityManagerService.this) {
2115                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2116                        try {
2117                            // Make a one-way callback to the listener
2118                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2119                                    (String) msg.obj, msg.arg1);
2120                        } catch (RemoteException e){
2121                            // Handled by the RemoteCallbackList
2122                        }
2123                    }
2124                    mTaskStackListeners.finishBroadcast();
2125                }
2126                break;
2127            }
2128                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2129                    synchronized (ActivityManagerService.this) {
2130                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2131                            try {
2132                                // Make a one-way callback to the listener
2133                                mTaskStackListeners.getBroadcastItem(i)
2134                                        .onActivityDismissingDockedStack();
2135                            } catch (RemoteException e){
2136                                // Handled by the RemoteCallbackList
2137                            }
2138                        }
2139                        mTaskStackListeners.finishBroadcast();
2140                    }
2141                    break;
2142                }
2143            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2144                final int uid = msg.arg1;
2145                final byte[] firstPacket = (byte[]) msg.obj;
2146
2147                synchronized (mPidsSelfLocked) {
2148                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2149                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2150                        if (p.uid == uid) {
2151                            try {
2152                                p.thread.notifyCleartextNetwork(firstPacket);
2153                            } catch (RemoteException ignored) {
2154                            }
2155                        }
2156                    }
2157                }
2158                break;
2159            }
2160            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2161                final String procName;
2162                final int uid;
2163                final long memLimit;
2164                final String reportPackage;
2165                synchronized (ActivityManagerService.this) {
2166                    procName = mMemWatchDumpProcName;
2167                    uid = mMemWatchDumpUid;
2168                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2169                    if (val == null) {
2170                        val = mMemWatchProcesses.get(procName, 0);
2171                    }
2172                    if (val != null) {
2173                        memLimit = val.first;
2174                        reportPackage = val.second;
2175                    } else {
2176                        memLimit = 0;
2177                        reportPackage = null;
2178                    }
2179                }
2180                if (procName == null) {
2181                    return;
2182                }
2183
2184                if (DEBUG_PSS) Slog.d(TAG_PSS,
2185                        "Showing dump heap notification from " + procName + "/" + uid);
2186
2187                INotificationManager inm = NotificationManager.getService();
2188                if (inm == null) {
2189                    return;
2190                }
2191
2192                String text = mContext.getString(R.string.dump_heap_notification, procName);
2193
2194
2195                Intent deleteIntent = new Intent();
2196                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2197                Intent intent = new Intent();
2198                intent.setClassName("android", DumpHeapActivity.class.getName());
2199                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2200                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2201                if (reportPackage != null) {
2202                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2203                }
2204                int userId = UserHandle.getUserId(uid);
2205                Notification notification = new Notification.Builder(mContext)
2206                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2207                        .setWhen(0)
2208                        .setOngoing(true)
2209                        .setAutoCancel(true)
2210                        .setTicker(text)
2211                        .setColor(mContext.getColor(
2212                                com.android.internal.R.color.system_notification_accent_color))
2213                        .setContentTitle(text)
2214                        .setContentText(
2215                                mContext.getText(R.string.dump_heap_notification_detail))
2216                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2217                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2218                                new UserHandle(userId)))
2219                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2220                                deleteIntent, 0, UserHandle.SYSTEM))
2221                        .build();
2222
2223                try {
2224                    int[] outId = new int[1];
2225                    inm.enqueueNotificationWithTag("android", "android", null,
2226                            R.string.dump_heap_notification,
2227                            notification, outId, userId);
2228                } catch (RuntimeException e) {
2229                    Slog.w(ActivityManagerService.TAG,
2230                            "Error showing notification for dump heap", e);
2231                } catch (RemoteException e) {
2232                }
2233            } break;
2234            case DELETE_DUMPHEAP_MSG: {
2235                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2236                        DumpHeapActivity.JAVA_URI,
2237                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2238                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2239                        UserHandle.myUserId());
2240                synchronized (ActivityManagerService.this) {
2241                    mMemWatchDumpFile = null;
2242                    mMemWatchDumpProcName = null;
2243                    mMemWatchDumpPid = -1;
2244                    mMemWatchDumpUid = -1;
2245                }
2246            } break;
2247            case FOREGROUND_PROFILE_CHANGED_MSG: {
2248                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2249            } break;
2250            case REPORT_TIME_TRACKER_MSG: {
2251                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2252                tracker.deliverResult(mContext);
2253            } break;
2254            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2255                mUserController.dispatchUserSwitchComplete(msg.arg1);
2256            } break;
2257            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2258                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2259                try {
2260                    connection.shutdown();
2261                } catch (RemoteException e) {
2262                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2263                }
2264                // Only a UiAutomation can set this flag and now that
2265                // it is finished we make sure it is reset to its default.
2266                mUserIsMonkey = false;
2267            } break;
2268            case APP_BOOST_DEACTIVATE_MSG: {
2269                synchronized(ActivityManagerService.this) {
2270                    if (mIsBoosted) {
2271                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2272                            nativeMigrateFromBoost();
2273                            mIsBoosted = false;
2274                            mBoostStartTime = 0;
2275                        } else {
2276                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2277                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2278                        }
2279                    }
2280                }
2281            } break;
2282            case IDLE_UIDS_MSG: {
2283                idleUids();
2284            } break;
2285            case LOG_STACK_STATE: {
2286                synchronized (ActivityManagerService.this) {
2287                    mStackSupervisor.logStackState();
2288                }
2289            } break;
2290            case VR_MODE_CHANGE_MSG: {
2291                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                boolean vrMode;
2294                ComponentName requestedPackage;
2295                ComponentName callingPackage;
2296                int userId;
2297                synchronized (ActivityManagerService.this) {
2298                    vrMode = r.requestedVrComponent != null;
2299                    requestedPackage = r.requestedVrComponent;
2300                    userId = r.userId;
2301                    callingPackage = r.info.getComponentName();
2302                    if (mInVrMode != vrMode) {
2303                        mInVrMode = vrMode;
2304                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2305                    }
2306                }
2307                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2308            } break;
2309            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2310                final ActivityRecord r = (ActivityRecord) msg.obj;
2311                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2312                if (needsVrMode) {
2313                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2314                            r.info.getComponentName(), false);
2315                }
2316            } break;
2317            }
2318        }
2319    };
2320
2321    static final int COLLECT_PSS_BG_MSG = 1;
2322
2323    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2324        @Override
2325        public void handleMessage(Message msg) {
2326            switch (msg.what) {
2327            case COLLECT_PSS_BG_MSG: {
2328                long start = SystemClock.uptimeMillis();
2329                MemInfoReader memInfo = null;
2330                synchronized (ActivityManagerService.this) {
2331                    if (mFullPssPending) {
2332                        mFullPssPending = false;
2333                        memInfo = new MemInfoReader();
2334                    }
2335                }
2336                if (memInfo != null) {
2337                    updateCpuStatsNow();
2338                    long nativeTotalPss = 0;
2339                    synchronized (mProcessCpuTracker) {
2340                        final int N = mProcessCpuTracker.countStats();
2341                        for (int j=0; j<N; j++) {
2342                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2343                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2344                                // This is definitely an application process; skip it.
2345                                continue;
2346                            }
2347                            synchronized (mPidsSelfLocked) {
2348                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2349                                    // This is one of our own processes; skip it.
2350                                    continue;
2351                                }
2352                            }
2353                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2354                        }
2355                    }
2356                    memInfo.readMemInfo();
2357                    synchronized (ActivityManagerService.this) {
2358                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2359                                + (SystemClock.uptimeMillis()-start) + "ms");
2360                        final long cachedKb = memInfo.getCachedSizeKb();
2361                        final long freeKb = memInfo.getFreeSizeKb();
2362                        final long zramKb = memInfo.getZramTotalSizeKb();
2363                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2364                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2365                                kernelKb*1024, nativeTotalPss*1024);
2366                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2367                                nativeTotalPss);
2368                    }
2369                }
2370
2371                int num = 0;
2372                long[] tmp = new long[2];
2373                do {
2374                    ProcessRecord proc;
2375                    int procState;
2376                    int pid;
2377                    long lastPssTime;
2378                    synchronized (ActivityManagerService.this) {
2379                        if (mPendingPssProcesses.size() <= 0) {
2380                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2381                                    "Collected PSS of " + num + " processes in "
2382                                    + (SystemClock.uptimeMillis() - start) + "ms");
2383                            mPendingPssProcesses.clear();
2384                            return;
2385                        }
2386                        proc = mPendingPssProcesses.remove(0);
2387                        procState = proc.pssProcState;
2388                        lastPssTime = proc.lastPssTime;
2389                        if (proc.thread != null && procState == proc.setProcState
2390                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2391                                        < SystemClock.uptimeMillis()) {
2392                            pid = proc.pid;
2393                        } else {
2394                            proc = null;
2395                            pid = 0;
2396                        }
2397                    }
2398                    if (proc != null) {
2399                        long pss = Debug.getPss(pid, tmp, null);
2400                        synchronized (ActivityManagerService.this) {
2401                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2402                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2403                                num++;
2404                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2405                                        SystemClock.uptimeMillis());
2406                            }
2407                        }
2408                    }
2409                } while (true);
2410            }
2411            }
2412        }
2413    };
2414
2415    public void setSystemProcess() {
2416        try {
2417            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2418            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2419            ServiceManager.addService("meminfo", new MemBinder(this));
2420            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2421            ServiceManager.addService("dbinfo", new DbBinder(this));
2422            if (MONITOR_CPU_USAGE) {
2423                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2424            }
2425            ServiceManager.addService("permission", new PermissionController(this));
2426            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2427
2428            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2429                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2430            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2431
2432            synchronized (this) {
2433                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2434                app.persistent = true;
2435                app.pid = MY_PID;
2436                app.maxAdj = ProcessList.SYSTEM_ADJ;
2437                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2438                synchronized (mPidsSelfLocked) {
2439                    mPidsSelfLocked.put(app.pid, app);
2440                }
2441                updateLruProcessLocked(app, false, null);
2442                updateOomAdjLocked();
2443            }
2444        } catch (PackageManager.NameNotFoundException e) {
2445            throw new RuntimeException(
2446                    "Unable to find android system package", e);
2447        }
2448    }
2449
2450    public void setWindowManager(WindowManagerService wm) {
2451        mWindowManager = wm;
2452        mStackSupervisor.setWindowManager(wm);
2453        mActivityStarter.setWindowManager(wm);
2454    }
2455
2456    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2457        mUsageStatsService = usageStatsManager;
2458    }
2459
2460    public void startObservingNativeCrashes() {
2461        final NativeCrashListener ncl = new NativeCrashListener(this);
2462        ncl.start();
2463    }
2464
2465    public IAppOpsService getAppOpsService() {
2466        return mAppOpsService;
2467    }
2468
2469    static class MemBinder extends Binder {
2470        ActivityManagerService mActivityManagerService;
2471        MemBinder(ActivityManagerService activityManagerService) {
2472            mActivityManagerService = activityManagerService;
2473        }
2474
2475        @Override
2476        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2477            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2478                    != PackageManager.PERMISSION_GRANTED) {
2479                pw.println("Permission Denial: can't dump meminfo from from pid="
2480                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2481                        + " without permission " + android.Manifest.permission.DUMP);
2482                return;
2483            }
2484
2485            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2486        }
2487    }
2488
2489    static class GraphicsBinder extends Binder {
2490        ActivityManagerService mActivityManagerService;
2491        GraphicsBinder(ActivityManagerService activityManagerService) {
2492            mActivityManagerService = activityManagerService;
2493        }
2494
2495        @Override
2496        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2497            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2498                    != PackageManager.PERMISSION_GRANTED) {
2499                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2500                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2501                        + " without permission " + android.Manifest.permission.DUMP);
2502                return;
2503            }
2504
2505            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2506        }
2507    }
2508
2509    static class DbBinder extends Binder {
2510        ActivityManagerService mActivityManagerService;
2511        DbBinder(ActivityManagerService activityManagerService) {
2512            mActivityManagerService = activityManagerService;
2513        }
2514
2515        @Override
2516        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2517            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2518                    != PackageManager.PERMISSION_GRANTED) {
2519                pw.println("Permission Denial: can't dump dbinfo from from pid="
2520                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2521                        + " without permission " + android.Manifest.permission.DUMP);
2522                return;
2523            }
2524
2525            mActivityManagerService.dumpDbInfo(fd, pw, args);
2526        }
2527    }
2528
2529    static class CpuBinder extends Binder {
2530        ActivityManagerService mActivityManagerService;
2531        CpuBinder(ActivityManagerService activityManagerService) {
2532            mActivityManagerService = activityManagerService;
2533        }
2534
2535        @Override
2536        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2537            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2538                    != PackageManager.PERMISSION_GRANTED) {
2539                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2540                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2541                        + " without permission " + android.Manifest.permission.DUMP);
2542                return;
2543            }
2544
2545            synchronized (mActivityManagerService.mProcessCpuTracker) {
2546                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2547                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2548                        SystemClock.uptimeMillis()));
2549            }
2550        }
2551    }
2552
2553    public static final class Lifecycle extends SystemService {
2554        private final ActivityManagerService mService;
2555
2556        public Lifecycle(Context context) {
2557            super(context);
2558            mService = new ActivityManagerService(context);
2559        }
2560
2561        @Override
2562        public void onStart() {
2563            mService.start();
2564        }
2565
2566        public ActivityManagerService getService() {
2567            return mService;
2568        }
2569    }
2570
2571    // Note: This method is invoked on the main thread but may need to attach various
2572    // handlers to other threads.  So take care to be explicit about the looper.
2573    public ActivityManagerService(Context systemContext) {
2574        mContext = systemContext;
2575        mFactoryTest = FactoryTest.getMode();
2576        mSystemThread = ActivityThread.currentActivityThread();
2577
2578        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2579
2580        mHandlerThread = new ServiceThread(TAG,
2581                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2582        mHandlerThread.start();
2583        mHandler = new MainHandler(mHandlerThread.getLooper());
2584        mUiHandler = new UiHandler();
2585
2586        /* static; one-time init here */
2587        if (sKillHandler == null) {
2588            sKillThread = new ServiceThread(TAG + ":kill",
2589                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2590            sKillThread.start();
2591            sKillHandler = new KillHandler(sKillThread.getLooper());
2592        }
2593
2594        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2595                "foreground", BROADCAST_FG_TIMEOUT, false);
2596        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2597                "background", BROADCAST_BG_TIMEOUT, true);
2598        mBroadcastQueues[0] = mFgBroadcastQueue;
2599        mBroadcastQueues[1] = mBgBroadcastQueue;
2600
2601        mServices = new ActiveServices(this);
2602        mProviderMap = new ProviderMap(this);
2603        mAppErrors = new AppErrors(mContext, this);
2604
2605        // TODO: Move creation of battery stats service outside of activity manager service.
2606        File dataDir = Environment.getDataDirectory();
2607        File systemDir = new File(dataDir, "system");
2608        systemDir.mkdirs();
2609        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2610        mBatteryStatsService.getActiveStatistics().readLocked();
2611        mBatteryStatsService.scheduleWriteToDisk();
2612        mOnBattery = DEBUG_POWER ? true
2613                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2614        mBatteryStatsService.getActiveStatistics().setCallback(this);
2615
2616        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2617
2618        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2619        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2620                new IAppOpsCallback.Stub() {
2621                    @Override public void opChanged(int op, int uid, String packageName) {
2622                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2623                            if (mAppOpsService.checkOperation(op, uid, packageName)
2624                                    != AppOpsManager.MODE_ALLOWED) {
2625                                runInBackgroundDisabled(uid);
2626                            }
2627                        }
2628                    }
2629                });
2630
2631        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2632
2633        mUserController = new UserController(this);
2634
2635        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2636            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2637
2638        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2639
2640        mConfiguration.setToDefaults();
2641        mConfiguration.setLocales(LocaleList.getDefault());
2642
2643        mConfigurationSeq = mConfiguration.seq = 1;
2644        mProcessCpuTracker.init();
2645
2646        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2647        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2648        mStackSupervisor = new ActivityStackSupervisor(this);
2649        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2650        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2651
2652        mProcessCpuThread = new Thread("CpuTracker") {
2653            @Override
2654            public void run() {
2655                while (true) {
2656                    try {
2657                        try {
2658                            synchronized(this) {
2659                                final long now = SystemClock.uptimeMillis();
2660                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2661                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2662                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2663                                //        + ", write delay=" + nextWriteDelay);
2664                                if (nextWriteDelay < nextCpuDelay) {
2665                                    nextCpuDelay = nextWriteDelay;
2666                                }
2667                                if (nextCpuDelay > 0) {
2668                                    mProcessCpuMutexFree.set(true);
2669                                    this.wait(nextCpuDelay);
2670                                }
2671                            }
2672                        } catch (InterruptedException e) {
2673                        }
2674                        updateCpuStatsNow();
2675                    } catch (Exception e) {
2676                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2677                    }
2678                }
2679            }
2680        };
2681
2682        Watchdog.getInstance().addMonitor(this);
2683        Watchdog.getInstance().addThread(mHandler);
2684    }
2685
2686    public void setSystemServiceManager(SystemServiceManager mgr) {
2687        mSystemServiceManager = mgr;
2688    }
2689
2690    public void setInstaller(Installer installer) {
2691        mInstaller = installer;
2692    }
2693
2694    private void start() {
2695        Process.removeAllProcessGroups();
2696        mProcessCpuThread.start();
2697
2698        mBatteryStatsService.publish(mContext);
2699        mAppOpsService.publish(mContext);
2700        Slog.d("AppOps", "AppOpsService published");
2701        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2702    }
2703
2704    void onUserStoppedLocked(int userId) {
2705        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2706    }
2707
2708    public void initPowerManagement() {
2709        mStackSupervisor.initPowerManagement();
2710        mBatteryStatsService.initPowerManagement();
2711        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2712        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2713        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2714        mVoiceWakeLock.setReferenceCounted(false);
2715    }
2716
2717    @Override
2718    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2719            throws RemoteException {
2720        if (code == SYSPROPS_TRANSACTION) {
2721            // We need to tell all apps about the system property change.
2722            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2723            synchronized(this) {
2724                final int NP = mProcessNames.getMap().size();
2725                for (int ip=0; ip<NP; ip++) {
2726                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2727                    final int NA = apps.size();
2728                    for (int ia=0; ia<NA; ia++) {
2729                        ProcessRecord app = apps.valueAt(ia);
2730                        if (app.thread != null) {
2731                            procs.add(app.thread.asBinder());
2732                        }
2733                    }
2734                }
2735            }
2736
2737            int N = procs.size();
2738            for (int i=0; i<N; i++) {
2739                Parcel data2 = Parcel.obtain();
2740                try {
2741                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2742                } catch (RemoteException e) {
2743                }
2744                data2.recycle();
2745            }
2746        }
2747        try {
2748            return super.onTransact(code, data, reply, flags);
2749        } catch (RuntimeException e) {
2750            // The activity manager only throws security exceptions, so let's
2751            // log all others.
2752            if (!(e instanceof SecurityException)) {
2753                Slog.wtf(TAG, "Activity Manager Crash", e);
2754            }
2755            throw e;
2756        }
2757    }
2758
2759    void updateCpuStats() {
2760        final long now = SystemClock.uptimeMillis();
2761        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2762            return;
2763        }
2764        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2765            synchronized (mProcessCpuThread) {
2766                mProcessCpuThread.notify();
2767            }
2768        }
2769    }
2770
2771    void updateCpuStatsNow() {
2772        synchronized (mProcessCpuTracker) {
2773            mProcessCpuMutexFree.set(false);
2774            final long now = SystemClock.uptimeMillis();
2775            boolean haveNewCpuStats = false;
2776
2777            if (MONITOR_CPU_USAGE &&
2778                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2779                mLastCpuTime.set(now);
2780                mProcessCpuTracker.update();
2781                if (mProcessCpuTracker.hasGoodLastStats()) {
2782                    haveNewCpuStats = true;
2783                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2784                    //Slog.i(TAG, "Total CPU usage: "
2785                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2786
2787                    // Slog the cpu usage if the property is set.
2788                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2789                        int user = mProcessCpuTracker.getLastUserTime();
2790                        int system = mProcessCpuTracker.getLastSystemTime();
2791                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2792                        int irq = mProcessCpuTracker.getLastIrqTime();
2793                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2794                        int idle = mProcessCpuTracker.getLastIdleTime();
2795
2796                        int total = user + system + iowait + irq + softIrq + idle;
2797                        if (total == 0) total = 1;
2798
2799                        EventLog.writeEvent(EventLogTags.CPU,
2800                                ((user+system+iowait+irq+softIrq) * 100) / total,
2801                                (user * 100) / total,
2802                                (system * 100) / total,
2803                                (iowait * 100) / total,
2804                                (irq * 100) / total,
2805                                (softIrq * 100) / total);
2806                    }
2807                }
2808            }
2809
2810            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2811            synchronized(bstats) {
2812                synchronized(mPidsSelfLocked) {
2813                    if (haveNewCpuStats) {
2814                        if (bstats.startAddingCpuLocked()) {
2815                            int totalUTime = 0;
2816                            int totalSTime = 0;
2817                            final int N = mProcessCpuTracker.countStats();
2818                            for (int i=0; i<N; i++) {
2819                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2820                                if (!st.working) {
2821                                    continue;
2822                                }
2823                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2824                                totalUTime += st.rel_utime;
2825                                totalSTime += st.rel_stime;
2826                                if (pr != null) {
2827                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2828                                    if (ps == null || !ps.isActive()) {
2829                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2830                                                pr.info.uid, pr.processName);
2831                                    }
2832                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2833                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2834                                } else {
2835                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2836                                    if (ps == null || !ps.isActive()) {
2837                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2838                                                bstats.mapUid(st.uid), st.name);
2839                                    }
2840                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2841                                }
2842                            }
2843                            final int userTime = mProcessCpuTracker.getLastUserTime();
2844                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2845                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2846                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2847                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2848                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2849                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2850                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2851                        }
2852                    }
2853                }
2854
2855                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2856                    mLastWriteTime = now;
2857                    mBatteryStatsService.scheduleWriteToDisk();
2858                }
2859            }
2860        }
2861    }
2862
2863    @Override
2864    public void batteryNeedsCpuUpdate() {
2865        updateCpuStatsNow();
2866    }
2867
2868    @Override
2869    public void batteryPowerChanged(boolean onBattery) {
2870        // When plugging in, update the CPU stats first before changing
2871        // the plug state.
2872        updateCpuStatsNow();
2873        synchronized (this) {
2874            synchronized(mPidsSelfLocked) {
2875                mOnBattery = DEBUG_POWER ? true : onBattery;
2876            }
2877        }
2878    }
2879
2880    @Override
2881    public void batterySendBroadcast(Intent intent) {
2882        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2883                AppOpsManager.OP_NONE, null, false, false,
2884                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2885    }
2886
2887    /**
2888     * Initialize the application bind args. These are passed to each
2889     * process when the bindApplication() IPC is sent to the process. They're
2890     * lazily setup to make sure the services are running when they're asked for.
2891     */
2892    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2893        if (mAppBindArgs == null) {
2894            mAppBindArgs = new HashMap<>();
2895
2896            // Isolated processes won't get this optimization, so that we don't
2897            // violate the rules about which services they have access to.
2898            if (!isolated) {
2899                // Setup the application init args
2900                mAppBindArgs.put("package", ServiceManager.getService("package"));
2901                mAppBindArgs.put("window", ServiceManager.getService("window"));
2902                mAppBindArgs.put(Context.ALARM_SERVICE,
2903                        ServiceManager.getService(Context.ALARM_SERVICE));
2904            }
2905        }
2906        return mAppBindArgs;
2907    }
2908
2909    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2910        if (r == null || mFocusedActivity == r) {
2911            return false;
2912        }
2913
2914        if (!r.isFocusable()) {
2915            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2916            return false;
2917        }
2918
2919        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2920
2921        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2922        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2923                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2924        mDoingSetFocusedActivity = true;
2925
2926        final ActivityRecord last = mFocusedActivity;
2927        mFocusedActivity = r;
2928        if (r.task.isApplicationTask()) {
2929            if (mCurAppTimeTracker != r.appTimeTracker) {
2930                // We are switching app tracking.  Complete the current one.
2931                if (mCurAppTimeTracker != null) {
2932                    mCurAppTimeTracker.stop();
2933                    mHandler.obtainMessage(
2934                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2935                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2936                    mCurAppTimeTracker = null;
2937                }
2938                if (r.appTimeTracker != null) {
2939                    mCurAppTimeTracker = r.appTimeTracker;
2940                    startTimeTrackingFocusedActivityLocked();
2941                }
2942            } else {
2943                startTimeTrackingFocusedActivityLocked();
2944            }
2945        } else {
2946            r.appTimeTracker = null;
2947        }
2948        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2949        // TODO: Probably not, because we don't want to resume voice on switching
2950        // back to this activity
2951        if (r.task.voiceInteractor != null) {
2952            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2953        } else {
2954            finishRunningVoiceLocked();
2955            IVoiceInteractionSession session;
2956            if (last != null && ((session = last.task.voiceSession) != null
2957                    || (session = last.voiceSession) != null)) {
2958                // We had been in a voice interaction session, but now focused has
2959                // move to something different.  Just finish the session, we can't
2960                // return to it and retain the proper state and synchronization with
2961                // the voice interaction service.
2962                finishVoiceTask(session);
2963            }
2964        }
2965        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2966            mWindowManager.setFocusedApp(r.appToken, true);
2967        }
2968        applyUpdateLockStateLocked(r);
2969        applyUpdateVrModeLocked(r);
2970        if (mFocusedActivity.userId != mLastFocusedUserId) {
2971            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2972            mHandler.obtainMessage(
2973                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2974            mLastFocusedUserId = mFocusedActivity.userId;
2975        }
2976
2977        // Log a warning if the focused app is changed during the process. This could
2978        // indicate a problem of the focus setting logic!
2979        if (mFocusedActivity != r) Slog.w(TAG,
2980                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2981        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2982
2983        EventLogTags.writeAmFocusedActivity(
2984                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2985                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2986                reason);
2987        return true;
2988    }
2989
2990    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2991        if (mFocusedActivity != goingAway) {
2992            return;
2993        }
2994
2995        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2996        if (focusedStack != null) {
2997            final ActivityRecord top = focusedStack.topActivity();
2998            if (top != null && top.userId != mLastFocusedUserId) {
2999                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3000                mHandler.sendMessage(
3001                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3002                mLastFocusedUserId = top.userId;
3003            }
3004        }
3005
3006        // Try to move focus to another activity if possible.
3007        if (setFocusedActivityLocked(
3008                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3009            return;
3010        }
3011
3012        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3013                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3014        mFocusedActivity = null;
3015        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3016    }
3017
3018    @Override
3019    public void setFocusedStack(int stackId) {
3020        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3021        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3022        final long callingId = Binder.clearCallingIdentity();
3023        try {
3024            synchronized (this) {
3025                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3026                if (stack == null) {
3027                    return;
3028                }
3029                final ActivityRecord r = stack.topRunningActivityLocked();
3030                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3031                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3032                }
3033            }
3034        } finally {
3035            Binder.restoreCallingIdentity(callingId);
3036        }
3037    }
3038
3039    @Override
3040    public void setFocusedTask(int taskId) {
3041        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3042        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3043        final long callingId = Binder.clearCallingIdentity();
3044        try {
3045            synchronized (this) {
3046                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3047                if (task == null) {
3048                    return;
3049                }
3050                final ActivityRecord r = task.topRunningActivityLocked();
3051                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3052                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3053                }
3054            }
3055        } finally {
3056            Binder.restoreCallingIdentity(callingId);
3057        }
3058    }
3059
3060    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3061    @Override
3062    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3064        synchronized (this) {
3065            if (listener != null) {
3066                mTaskStackListeners.register(listener);
3067            }
3068        }
3069    }
3070
3071    @Override
3072    public void notifyActivityDrawn(IBinder token) {
3073        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3074        synchronized (this) {
3075            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3076            if (r != null) {
3077                r.task.stack.notifyActivityDrawnLocked(r);
3078            }
3079        }
3080    }
3081
3082    final void applyUpdateLockStateLocked(ActivityRecord r) {
3083        // Modifications to the UpdateLock state are done on our handler, outside
3084        // the activity manager's locks.  The new state is determined based on the
3085        // state *now* of the relevant activity record.  The object is passed to
3086        // the handler solely for logging detail, not to be consulted/modified.
3087        final boolean nextState = r != null && r.immersive;
3088        mHandler.sendMessage(
3089                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3090    }
3091
3092    final void applyUpdateVrModeLocked(ActivityRecord r) {
3093        mHandler.sendMessage(
3094                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3095    }
3096
3097    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3098        mHandler.sendMessage(
3099                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3100    }
3101
3102    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3103            ComponentName callingPackage, boolean immediate) {
3104        VrManagerInternal vrService =
3105                LocalServices.getService(VrManagerInternal.class);
3106        if (immediate) {
3107            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3108        } else {
3109            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3110        }
3111    }
3112
3113    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3114        Message msg = Message.obtain();
3115        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3116        msg.obj = r.task.askedCompatMode ? null : r;
3117        mUiHandler.sendMessage(msg);
3118    }
3119
3120    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3121        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3122                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3123            final Message msg = Message.obtain();
3124            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3125            msg.obj = r;
3126            mUiHandler.sendMessage(msg);
3127        }
3128    }
3129
3130    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3131            String what, Object obj, ProcessRecord srcApp) {
3132        app.lastActivityTime = now;
3133
3134        if (app.activities.size() > 0) {
3135            // Don't want to touch dependent processes that are hosting activities.
3136            return index;
3137        }
3138
3139        int lrui = mLruProcesses.lastIndexOf(app);
3140        if (lrui < 0) {
3141            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3142                    + what + " " + obj + " from " + srcApp);
3143            return index;
3144        }
3145
3146        if (lrui >= index) {
3147            // Don't want to cause this to move dependent processes *back* in the
3148            // list as if they were less frequently used.
3149            return index;
3150        }
3151
3152        if (lrui >= mLruProcessActivityStart) {
3153            // Don't want to touch dependent processes that are hosting activities.
3154            return index;
3155        }
3156
3157        mLruProcesses.remove(lrui);
3158        if (index > 0) {
3159            index--;
3160        }
3161        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3162                + " in LRU list: " + app);
3163        mLruProcesses.add(index, app);
3164        return index;
3165    }
3166
3167    static void killProcessGroup(int uid, int pid) {
3168        if (sKillHandler != null) {
3169            sKillHandler.sendMessage(
3170                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3171        } else {
3172            Slog.w(TAG, "Asked to kill process group before system bringup!");
3173            Process.killProcessGroup(uid, pid);
3174        }
3175    }
3176
3177    final void removeLruProcessLocked(ProcessRecord app) {
3178        int lrui = mLruProcesses.lastIndexOf(app);
3179        if (lrui >= 0) {
3180            if (!app.killed) {
3181                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3182                Process.killProcessQuiet(app.pid);
3183                killProcessGroup(app.uid, app.pid);
3184            }
3185            if (lrui <= mLruProcessActivityStart) {
3186                mLruProcessActivityStart--;
3187            }
3188            if (lrui <= mLruProcessServiceStart) {
3189                mLruProcessServiceStart--;
3190            }
3191            mLruProcesses.remove(lrui);
3192        }
3193    }
3194
3195    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3196            ProcessRecord client) {
3197        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3198                || app.treatLikeActivity;
3199        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3200        if (!activityChange && hasActivity) {
3201            // The process has activities, so we are only allowing activity-based adjustments
3202            // to move it.  It should be kept in the front of the list with other
3203            // processes that have activities, and we don't want those to change their
3204            // order except due to activity operations.
3205            return;
3206        }
3207
3208        mLruSeq++;
3209        final long now = SystemClock.uptimeMillis();
3210        app.lastActivityTime = now;
3211
3212        // First a quick reject: if the app is already at the position we will
3213        // put it, then there is nothing to do.
3214        if (hasActivity) {
3215            final int N = mLruProcesses.size();
3216            if (N > 0 && mLruProcesses.get(N-1) == app) {
3217                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3218                return;
3219            }
3220        } else {
3221            if (mLruProcessServiceStart > 0
3222                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3223                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3224                return;
3225            }
3226        }
3227
3228        int lrui = mLruProcesses.lastIndexOf(app);
3229
3230        if (app.persistent && lrui >= 0) {
3231            // We don't care about the position of persistent processes, as long as
3232            // they are in the list.
3233            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3234            return;
3235        }
3236
3237        /* In progress: compute new position first, so we can avoid doing work
3238           if the process is not actually going to move.  Not yet working.
3239        int addIndex;
3240        int nextIndex;
3241        boolean inActivity = false, inService = false;
3242        if (hasActivity) {
3243            // Process has activities, put it at the very tipsy-top.
3244            addIndex = mLruProcesses.size();
3245            nextIndex = mLruProcessServiceStart;
3246            inActivity = true;
3247        } else if (hasService) {
3248            // Process has services, put it at the top of the service list.
3249            addIndex = mLruProcessActivityStart;
3250            nextIndex = mLruProcessServiceStart;
3251            inActivity = true;
3252            inService = true;
3253        } else  {
3254            // Process not otherwise of interest, it goes to the top of the non-service area.
3255            addIndex = mLruProcessServiceStart;
3256            if (client != null) {
3257                int clientIndex = mLruProcesses.lastIndexOf(client);
3258                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3259                        + app);
3260                if (clientIndex >= 0 && addIndex > clientIndex) {
3261                    addIndex = clientIndex;
3262                }
3263            }
3264            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3265        }
3266
3267        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3268                + mLruProcessActivityStart + "): " + app);
3269        */
3270
3271        if (lrui >= 0) {
3272            if (lrui < mLruProcessActivityStart) {
3273                mLruProcessActivityStart--;
3274            }
3275            if (lrui < mLruProcessServiceStart) {
3276                mLruProcessServiceStart--;
3277            }
3278            /*
3279            if (addIndex > lrui) {
3280                addIndex--;
3281            }
3282            if (nextIndex > lrui) {
3283                nextIndex--;
3284            }
3285            */
3286            mLruProcesses.remove(lrui);
3287        }
3288
3289        /*
3290        mLruProcesses.add(addIndex, app);
3291        if (inActivity) {
3292            mLruProcessActivityStart++;
3293        }
3294        if (inService) {
3295            mLruProcessActivityStart++;
3296        }
3297        */
3298
3299        int nextIndex;
3300        if (hasActivity) {
3301            final int N = mLruProcesses.size();
3302            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3303                // Process doesn't have activities, but has clients with
3304                // activities...  move it up, but one below the top (the top
3305                // should always have a real activity).
3306                if (DEBUG_LRU) Slog.d(TAG_LRU,
3307                        "Adding to second-top of LRU activity list: " + app);
3308                mLruProcesses.add(N - 1, app);
3309                // To keep it from spamming the LRU list (by making a bunch of clients),
3310                // we will push down any other entries owned by the app.
3311                final int uid = app.info.uid;
3312                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3313                    ProcessRecord subProc = mLruProcesses.get(i);
3314                    if (subProc.info.uid == uid) {
3315                        // We want to push this one down the list.  If the process after
3316                        // it is for the same uid, however, don't do so, because we don't
3317                        // want them internally to be re-ordered.
3318                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3319                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3320                                    "Pushing uid " + uid + " swapping at " + i + ": "
3321                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3322                            ProcessRecord tmp = mLruProcesses.get(i);
3323                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3324                            mLruProcesses.set(i - 1, tmp);
3325                            i--;
3326                        }
3327                    } else {
3328                        // A gap, we can stop here.
3329                        break;
3330                    }
3331                }
3332            } else {
3333                // Process has activities, put it at the very tipsy-top.
3334                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3335                mLruProcesses.add(app);
3336            }
3337            nextIndex = mLruProcessServiceStart;
3338        } else if (hasService) {
3339            // Process has services, put it at the top of the service list.
3340            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3341            mLruProcesses.add(mLruProcessActivityStart, app);
3342            nextIndex = mLruProcessServiceStart;
3343            mLruProcessActivityStart++;
3344        } else  {
3345            // Process not otherwise of interest, it goes to the top of the non-service area.
3346            int index = mLruProcessServiceStart;
3347            if (client != null) {
3348                // If there is a client, don't allow the process to be moved up higher
3349                // in the list than that client.
3350                int clientIndex = mLruProcesses.lastIndexOf(client);
3351                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3352                        + " when updating " + app);
3353                if (clientIndex <= lrui) {
3354                    // Don't allow the client index restriction to push it down farther in the
3355                    // list than it already is.
3356                    clientIndex = lrui;
3357                }
3358                if (clientIndex >= 0 && index > clientIndex) {
3359                    index = clientIndex;
3360                }
3361            }
3362            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3363            mLruProcesses.add(index, app);
3364            nextIndex = index-1;
3365            mLruProcessActivityStart++;
3366            mLruProcessServiceStart++;
3367        }
3368
3369        // If the app is currently using a content provider or service,
3370        // bump those processes as well.
3371        for (int j=app.connections.size()-1; j>=0; j--) {
3372            ConnectionRecord cr = app.connections.valueAt(j);
3373            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3374                    && cr.binding.service.app != null
3375                    && cr.binding.service.app.lruSeq != mLruSeq
3376                    && !cr.binding.service.app.persistent) {
3377                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3378                        "service connection", cr, app);
3379            }
3380        }
3381        for (int j=app.conProviders.size()-1; j>=0; j--) {
3382            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3383            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3384                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3385                        "provider reference", cpr, app);
3386            }
3387        }
3388    }
3389
3390    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3391        if (uid == Process.SYSTEM_UID) {
3392            // The system gets to run in any process.  If there are multiple
3393            // processes with the same uid, just pick the first (this
3394            // should never happen).
3395            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3396            if (procs == null) return null;
3397            final int procCount = procs.size();
3398            for (int i = 0; i < procCount; i++) {
3399                final int procUid = procs.keyAt(i);
3400                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3401                    // Don't use an app process or different user process for system component.
3402                    continue;
3403                }
3404                return procs.valueAt(i);
3405            }
3406        }
3407        ProcessRecord proc = mProcessNames.get(processName, uid);
3408        if (false && proc != null && !keepIfLarge
3409                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3410                && proc.lastCachedPss >= 4000) {
3411            // Turn this condition on to cause killing to happen regularly, for testing.
3412            if (proc.baseProcessTracker != null) {
3413                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3414            }
3415            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3416        } else if (proc != null && !keepIfLarge
3417                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3418                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3419            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3420            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3421                if (proc.baseProcessTracker != null) {
3422                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3423                }
3424                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3425            }
3426        }
3427        return proc;
3428    }
3429
3430    void notifyPackageUse(String packageName, int reason) {
3431        IPackageManager pm = AppGlobals.getPackageManager();
3432        try {
3433            pm.notifyPackageUse(packageName, reason);
3434        } catch (RemoteException e) {
3435        }
3436    }
3437
3438    boolean isNextTransitionForward() {
3439        int transit = mWindowManager.getPendingAppTransition();
3440        return transit == TRANSIT_ACTIVITY_OPEN
3441                || transit == TRANSIT_TASK_OPEN
3442                || transit == TRANSIT_TASK_TO_FRONT;
3443    }
3444
3445    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3446            String processName, String abiOverride, int uid, Runnable crashHandler) {
3447        synchronized(this) {
3448            ApplicationInfo info = new ApplicationInfo();
3449            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3450            // For isolated processes, the former contains the parent's uid and the latter the
3451            // actual uid of the isolated process.
3452            // In the special case introduced by this method (which is, starting an isolated
3453            // process directly from the SystemServer without an actual parent app process) the
3454            // closest thing to a parent's uid is SYSTEM_UID.
3455            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3456            // the |isolated| logic in the ProcessRecord constructor.
3457            info.uid = Process.SYSTEM_UID;
3458            info.processName = processName;
3459            info.className = entryPoint;
3460            info.packageName = "android";
3461            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3462                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3463                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3464                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3465                    crashHandler);
3466            return proc != null ? proc.pid : 0;
3467        }
3468    }
3469
3470    final ProcessRecord startProcessLocked(String processName,
3471            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3472            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3473            boolean isolated, boolean keepIfLarge) {
3474        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3475                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3476                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3477                null /* crashHandler */);
3478    }
3479
3480    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3481            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3482            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3483            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3484        long startTime = SystemClock.elapsedRealtime();
3485        ProcessRecord app;
3486        if (!isolated) {
3487            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3488            checkTime(startTime, "startProcess: after getProcessRecord");
3489
3490            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3491                // If we are in the background, then check to see if this process
3492                // is bad.  If so, we will just silently fail.
3493                if (mAppErrors.isBadProcessLocked(info)) {
3494                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3495                            + "/" + info.processName);
3496                    return null;
3497                }
3498            } else {
3499                // When the user is explicitly starting a process, then clear its
3500                // crash count so that we won't make it bad until they see at
3501                // least one crash dialog again, and make the process good again
3502                // if it had been bad.
3503                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3504                        + "/" + info.processName);
3505                mAppErrors.resetProcessCrashTimeLocked(info);
3506                if (mAppErrors.isBadProcessLocked(info)) {
3507                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3508                            UserHandle.getUserId(info.uid), info.uid,
3509                            info.processName);
3510                    mAppErrors.clearBadProcessLocked(info);
3511                    if (app != null) {
3512                        app.bad = false;
3513                    }
3514                }
3515            }
3516        } else {
3517            // If this is an isolated process, it can't re-use an existing process.
3518            app = null;
3519        }
3520
3521        // app launch boost for big.little configurations
3522        // use cpusets to migrate freshly launched tasks to big cores
3523        nativeMigrateToBoost();
3524        mIsBoosted = true;
3525        mBoostStartTime = SystemClock.uptimeMillis();
3526        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3527        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3528
3529        // We don't have to do anything more if:
3530        // (1) There is an existing application record; and
3531        // (2) The caller doesn't think it is dead, OR there is no thread
3532        //     object attached to it so we know it couldn't have crashed; and
3533        // (3) There is a pid assigned to it, so it is either starting or
3534        //     already running.
3535        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3536                + " app=" + app + " knownToBeDead=" + knownToBeDead
3537                + " thread=" + (app != null ? app.thread : null)
3538                + " pid=" + (app != null ? app.pid : -1));
3539        if (app != null && app.pid > 0) {
3540            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3541                // We already have the app running, or are waiting for it to
3542                // come up (we have a pid but not yet its thread), so keep it.
3543                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3544                // If this is a new package in the process, add the package to the list
3545                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3546                checkTime(startTime, "startProcess: done, added package to proc");
3547                return app;
3548            }
3549
3550            // An application record is attached to a previous process,
3551            // clean it up now.
3552            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3553            checkTime(startTime, "startProcess: bad proc running, killing");
3554            killProcessGroup(app.uid, app.pid);
3555            handleAppDiedLocked(app, true, true);
3556            checkTime(startTime, "startProcess: done killing old proc");
3557        }
3558
3559        String hostingNameStr = hostingName != null
3560                ? hostingName.flattenToShortString() : null;
3561
3562        if (app == null) {
3563            checkTime(startTime, "startProcess: creating new process record");
3564            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3565            if (app == null) {
3566                Slog.w(TAG, "Failed making new process record for "
3567                        + processName + "/" + info.uid + " isolated=" + isolated);
3568                return null;
3569            }
3570            app.crashHandler = crashHandler;
3571            checkTime(startTime, "startProcess: done creating new process record");
3572        } else {
3573            // If this is a new package in the process, add the package to the list
3574            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3575            checkTime(startTime, "startProcess: added package to existing proc");
3576        }
3577
3578        // If the system is not ready yet, then hold off on starting this
3579        // process until it is.
3580        if (!mProcessesReady
3581                && !isAllowedWhileBooting(info)
3582                && !allowWhileBooting) {
3583            if (!mProcessesOnHold.contains(app)) {
3584                mProcessesOnHold.add(app);
3585            }
3586            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3587                    "System not ready, putting on hold: " + app);
3588            checkTime(startTime, "startProcess: returning with proc on hold");
3589            return app;
3590        }
3591
3592        checkTime(startTime, "startProcess: stepping in to startProcess");
3593        startProcessLocked(
3594                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3595        checkTime(startTime, "startProcess: done starting proc!");
3596        return (app.pid != 0) ? app : null;
3597    }
3598
3599    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3600        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3601    }
3602
3603    private final void startProcessLocked(ProcessRecord app,
3604            String hostingType, String hostingNameStr) {
3605        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3606                null /* entryPoint */, null /* entryPointArgs */);
3607    }
3608
3609    private final void startProcessLocked(ProcessRecord app, String hostingType,
3610            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3611        long startTime = SystemClock.elapsedRealtime();
3612        if (app.pid > 0 && app.pid != MY_PID) {
3613            checkTime(startTime, "startProcess: removing from pids map");
3614            synchronized (mPidsSelfLocked) {
3615                mPidsSelfLocked.remove(app.pid);
3616                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3617            }
3618            checkTime(startTime, "startProcess: done removing from pids map");
3619            app.setPid(0);
3620        }
3621
3622        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3623                "startProcessLocked removing on hold: " + app);
3624        mProcessesOnHold.remove(app);
3625
3626        checkTime(startTime, "startProcess: starting to update cpu stats");
3627        updateCpuStats();
3628        checkTime(startTime, "startProcess: done updating cpu stats");
3629
3630        try {
3631            try {
3632                final int userId = UserHandle.getUserId(app.uid);
3633                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3634            } catch (RemoteException e) {
3635                throw e.rethrowAsRuntimeException();
3636            }
3637
3638            int uid = app.uid;
3639            int[] gids = null;
3640            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3641            if (!app.isolated) {
3642                int[] permGids = null;
3643                try {
3644                    checkTime(startTime, "startProcess: getting gids from package manager");
3645                    final IPackageManager pm = AppGlobals.getPackageManager();
3646                    permGids = pm.getPackageGids(app.info.packageName,
3647                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3648                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3649                            MountServiceInternal.class);
3650                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3651                            app.info.packageName);
3652                } catch (RemoteException e) {
3653                    throw e.rethrowAsRuntimeException();
3654                }
3655
3656                /*
3657                 * Add shared application and profile GIDs so applications can share some
3658                 * resources like shared libraries and access user-wide resources
3659                 */
3660                if (ArrayUtils.isEmpty(permGids)) {
3661                    gids = new int[2];
3662                } else {
3663                    gids = new int[permGids.length + 2];
3664                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3665                }
3666                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3667                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3668            }
3669            checkTime(startTime, "startProcess: building args");
3670            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3671                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3672                        && mTopComponent != null
3673                        && app.processName.equals(mTopComponent.getPackageName())) {
3674                    uid = 0;
3675                }
3676                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3677                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3678                    uid = 0;
3679                }
3680            }
3681            int debugFlags = 0;
3682            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3683                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3684                // Also turn on CheckJNI for debuggable apps. It's quite
3685                // awkward to turn on otherwise.
3686                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3687            }
3688            // Run the app in safe mode if its manifest requests so or the
3689            // system is booted in safe mode.
3690            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3691                mSafeMode == true) {
3692                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3693            }
3694            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3695                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3696            }
3697            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3698            if ("true".equals(genDebugInfoProperty)) {
3699                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3700            }
3701            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3702                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3703            }
3704            if ("1".equals(SystemProperties.get("debug.assert"))) {
3705                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3706            }
3707            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3708                // Enable all debug flags required by the native debugger.
3709                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3710                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3711                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3712                mNativeDebuggingApp = null;
3713            }
3714
3715            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3716            if (requiredAbi == null) {
3717                requiredAbi = Build.SUPPORTED_ABIS[0];
3718            }
3719
3720            String instructionSet = null;
3721            if (app.info.primaryCpuAbi != null) {
3722                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3723            }
3724
3725            app.gids = gids;
3726            app.requiredAbi = requiredAbi;
3727            app.instructionSet = instructionSet;
3728
3729            // Start the process.  It will either succeed and return a result containing
3730            // the PID of the new process, or else throw a RuntimeException.
3731            boolean isActivityProcess = (entryPoint == null);
3732            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3733            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3734                    app.processName);
3735            checkTime(startTime, "startProcess: asking zygote to start proc");
3736            Process.ProcessStartResult startResult = Process.start(entryPoint,
3737                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3738                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3739                    app.info.dataDir, entryPointArgs);
3740            checkTime(startTime, "startProcess: returned from zygote!");
3741            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3742
3743            if (app.isolated) {
3744                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3745            }
3746            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3747            checkTime(startTime, "startProcess: done updating battery stats");
3748
3749            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3750                    UserHandle.getUserId(uid), startResult.pid, uid,
3751                    app.processName, hostingType,
3752                    hostingNameStr != null ? hostingNameStr : "");
3753
3754            try {
3755                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3756                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3757            } catch (RemoteException ex) {
3758                // Ignore
3759            }
3760
3761            if (app.persistent) {
3762                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3763            }
3764
3765            checkTime(startTime, "startProcess: building log message");
3766            StringBuilder buf = mStringBuilder;
3767            buf.setLength(0);
3768            buf.append("Start proc ");
3769            buf.append(startResult.pid);
3770            buf.append(':');
3771            buf.append(app.processName);
3772            buf.append('/');
3773            UserHandle.formatUid(buf, uid);
3774            if (!isActivityProcess) {
3775                buf.append(" [");
3776                buf.append(entryPoint);
3777                buf.append("]");
3778            }
3779            buf.append(" for ");
3780            buf.append(hostingType);
3781            if (hostingNameStr != null) {
3782                buf.append(" ");
3783                buf.append(hostingNameStr);
3784            }
3785            Slog.i(TAG, buf.toString());
3786            app.setPid(startResult.pid);
3787            app.usingWrapper = startResult.usingWrapper;
3788            app.removed = false;
3789            app.killed = false;
3790            app.killedByAm = false;
3791            checkTime(startTime, "startProcess: starting to update pids map");
3792            synchronized (mPidsSelfLocked) {
3793                this.mPidsSelfLocked.put(startResult.pid, app);
3794                if (isActivityProcess) {
3795                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3796                    msg.obj = app;
3797                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3798                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3799                }
3800            }
3801            checkTime(startTime, "startProcess: done updating pids map");
3802        } catch (RuntimeException e) {
3803            Slog.e(TAG, "Failure starting process " + app.processName, e);
3804
3805            // Something went very wrong while trying to start this process; one
3806            // common case is when the package is frozen due to an active
3807            // upgrade. To recover, clean up any active bookkeeping related to
3808            // starting this process. (We already invoked this method once when
3809            // the package was initially frozen through KILL_APPLICATION_MSG, so
3810            // it doesn't hurt to use it again.)
3811            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3812                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3813        }
3814    }
3815
3816    void updateUsageStats(ActivityRecord component, boolean resumed) {
3817        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3818                "updateUsageStats: comp=" + component + "res=" + resumed);
3819        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3820        if (resumed) {
3821            if (mUsageStatsService != null) {
3822                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3823                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3824            }
3825            synchronized (stats) {
3826                stats.noteActivityResumedLocked(component.app.uid);
3827            }
3828        } else {
3829            if (mUsageStatsService != null) {
3830                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3831                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3832            }
3833            synchronized (stats) {
3834                stats.noteActivityPausedLocked(component.app.uid);
3835            }
3836        }
3837    }
3838
3839    Intent getHomeIntent() {
3840        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3841        intent.setComponent(mTopComponent);
3842        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3843        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3844            intent.addCategory(Intent.CATEGORY_HOME);
3845        }
3846        return intent;
3847    }
3848
3849    boolean startHomeActivityLocked(int userId, String reason) {
3850        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3851                && mTopAction == null) {
3852            // We are running in factory test mode, but unable to find
3853            // the factory test app, so just sit around displaying the
3854            // error message and don't try to start anything.
3855            return false;
3856        }
3857        Intent intent = getHomeIntent();
3858        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3859        if (aInfo != null) {
3860            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3861            // Don't do this if the home app is currently being
3862            // instrumented.
3863            aInfo = new ActivityInfo(aInfo);
3864            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3865            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3866                    aInfo.applicationInfo.uid, true);
3867            if (app == null || app.instrumentationClass == null) {
3868                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3869                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3870            }
3871        } else {
3872            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3873        }
3874
3875        return true;
3876    }
3877
3878    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3879        ActivityInfo ai = null;
3880        ComponentName comp = intent.getComponent();
3881        try {
3882            if (comp != null) {
3883                // Factory test.
3884                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3885            } else {
3886                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3887                        intent,
3888                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3889                        flags, userId);
3890
3891                if (info != null) {
3892                    ai = info.activityInfo;
3893                }
3894            }
3895        } catch (RemoteException e) {
3896            // ignore
3897        }
3898
3899        return ai;
3900    }
3901
3902    /**
3903     * Starts the "new version setup screen" if appropriate.
3904     */
3905    void startSetupActivityLocked() {
3906        // Only do this once per boot.
3907        if (mCheckedForSetup) {
3908            return;
3909        }
3910
3911        // We will show this screen if the current one is a different
3912        // version than the last one shown, and we are not running in
3913        // low-level factory test mode.
3914        final ContentResolver resolver = mContext.getContentResolver();
3915        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3916                Settings.Global.getInt(resolver,
3917                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3918            mCheckedForSetup = true;
3919
3920            // See if we should be showing the platform update setup UI.
3921            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3922            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3923                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3924            if (!ris.isEmpty()) {
3925                final ResolveInfo ri = ris.get(0);
3926                String vers = ri.activityInfo.metaData != null
3927                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3928                        : null;
3929                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3930                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3931                            Intent.METADATA_SETUP_VERSION);
3932                }
3933                String lastVers = Settings.Secure.getString(
3934                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3935                if (vers != null && !vers.equals(lastVers)) {
3936                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3937                    intent.setComponent(new ComponentName(
3938                            ri.activityInfo.packageName, ri.activityInfo.name));
3939                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3940                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3941                            null, 0, 0, 0, null, false, false, null, null, null);
3942                }
3943            }
3944        }
3945    }
3946
3947    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3948        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3949    }
3950
3951    void enforceNotIsolatedCaller(String caller) {
3952        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3953            throw new SecurityException("Isolated process not allowed to call " + caller);
3954        }
3955    }
3956
3957    void enforceShellRestriction(String restriction, int userHandle) {
3958        if (Binder.getCallingUid() == Process.SHELL_UID) {
3959            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3960                throw new SecurityException("Shell does not have permission to access user "
3961                        + userHandle);
3962            }
3963        }
3964    }
3965
3966    @Override
3967    public int getFrontActivityScreenCompatMode() {
3968        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3969        synchronized (this) {
3970            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3971        }
3972    }
3973
3974    @Override
3975    public void setFrontActivityScreenCompatMode(int mode) {
3976        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977                "setFrontActivityScreenCompatMode");
3978        synchronized (this) {
3979            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3980        }
3981    }
3982
3983    @Override
3984    public int getPackageScreenCompatMode(String packageName) {
3985        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3986        synchronized (this) {
3987            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3988        }
3989    }
3990
3991    @Override
3992    public void setPackageScreenCompatMode(String packageName, int mode) {
3993        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3994                "setPackageScreenCompatMode");
3995        synchronized (this) {
3996            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3997        }
3998    }
3999
4000    @Override
4001    public boolean getPackageAskScreenCompat(String packageName) {
4002        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4003        synchronized (this) {
4004            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4005        }
4006    }
4007
4008    @Override
4009    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4010        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4011                "setPackageAskScreenCompat");
4012        synchronized (this) {
4013            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4014        }
4015    }
4016
4017    private boolean hasUsageStatsPermission(String callingPackage) {
4018        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4019                Binder.getCallingUid(), callingPackage);
4020        if (mode == AppOpsManager.MODE_DEFAULT) {
4021            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4022                    == PackageManager.PERMISSION_GRANTED;
4023        }
4024        return mode == AppOpsManager.MODE_ALLOWED;
4025    }
4026
4027    @Override
4028    public int getPackageProcessState(String packageName, String callingPackage) {
4029        if (!hasUsageStatsPermission(callingPackage)) {
4030            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4031                    "getPackageProcessState");
4032        }
4033
4034        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4035        synchronized (this) {
4036            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4037                final ProcessRecord proc = mLruProcesses.get(i);
4038                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4039                        || procState > proc.setProcState) {
4040                    boolean found = false;
4041                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4042                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4043                            procState = proc.setProcState;
4044                            found = true;
4045                        }
4046                    }
4047                    if (proc.pkgDeps != null && !found) {
4048                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4049                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4050                                procState = proc.setProcState;
4051                                break;
4052                            }
4053                        }
4054                    }
4055                }
4056            }
4057        }
4058        return procState;
4059    }
4060
4061    @Override
4062    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4063        synchronized (this) {
4064            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4065            if (app == null) {
4066                return false;
4067            }
4068            if (app.trimMemoryLevel < level && app.thread != null &&
4069                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4070                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4071                try {
4072                    app.thread.scheduleTrimMemory(level);
4073                    app.trimMemoryLevel = level;
4074                    return true;
4075                } catch (RemoteException e) {
4076                    // Fallthrough to failure case.
4077                }
4078            }
4079        }
4080        return false;
4081    }
4082
4083    private void dispatchProcessesChanged() {
4084        int N;
4085        synchronized (this) {
4086            N = mPendingProcessChanges.size();
4087            if (mActiveProcessChanges.length < N) {
4088                mActiveProcessChanges = new ProcessChangeItem[N];
4089            }
4090            mPendingProcessChanges.toArray(mActiveProcessChanges);
4091            mPendingProcessChanges.clear();
4092            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4093                    "*** Delivering " + N + " process changes");
4094        }
4095
4096        int i = mProcessObservers.beginBroadcast();
4097        while (i > 0) {
4098            i--;
4099            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4100            if (observer != null) {
4101                try {
4102                    for (int j=0; j<N; j++) {
4103                        ProcessChangeItem item = mActiveProcessChanges[j];
4104                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4105                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4106                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4107                                    + item.uid + ": " + item.foregroundActivities);
4108                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4109                                    item.foregroundActivities);
4110                        }
4111                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4112                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4114                                    + ": " + item.processState);
4115                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4116                        }
4117                    }
4118                } catch (RemoteException e) {
4119                }
4120            }
4121        }
4122        mProcessObservers.finishBroadcast();
4123
4124        synchronized (this) {
4125            for (int j=0; j<N; j++) {
4126                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4127            }
4128        }
4129    }
4130
4131    private void dispatchProcessDied(int pid, int uid) {
4132        int i = mProcessObservers.beginBroadcast();
4133        while (i > 0) {
4134            i--;
4135            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4136            if (observer != null) {
4137                try {
4138                    observer.onProcessDied(pid, uid);
4139                } catch (RemoteException e) {
4140                }
4141            }
4142        }
4143        mProcessObservers.finishBroadcast();
4144    }
4145
4146    private void dispatchUidsChanged() {
4147        int N;
4148        synchronized (this) {
4149            N = mPendingUidChanges.size();
4150            if (mActiveUidChanges.length < N) {
4151                mActiveUidChanges = new UidRecord.ChangeItem[N];
4152            }
4153            for (int i=0; i<N; i++) {
4154                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4155                mActiveUidChanges[i] = change;
4156                if (change.uidRecord != null) {
4157                    change.uidRecord.pendingChange = null;
4158                    change.uidRecord = null;
4159                }
4160            }
4161            mPendingUidChanges.clear();
4162            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4163                    "*** Delivering " + N + " uid changes");
4164        }
4165
4166        if (mLocalPowerManager != null) {
4167            for (int j=0; j<N; j++) {
4168                UidRecord.ChangeItem item = mActiveUidChanges[j];
4169                if (item.change == UidRecord.CHANGE_GONE
4170                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4171                    mLocalPowerManager.uidGone(item.uid);
4172                } else {
4173                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4174                }
4175            }
4176        }
4177
4178        int i = mUidObservers.beginBroadcast();
4179        while (i > 0) {
4180            i--;
4181            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4182            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4183            if (observer != null) {
4184                try {
4185                    for (int j=0; j<N; j++) {
4186                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4187                        final int change = item.change;
4188                        UidRecord validateUid = null;
4189                        if (VALIDATE_UID_STATES && i == 0) {
4190                            validateUid = mValidateUids.get(item.uid);
4191                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4192                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4193                                validateUid = new UidRecord(item.uid);
4194                                mValidateUids.put(item.uid, validateUid);
4195                            }
4196                        }
4197                        if (change == UidRecord.CHANGE_IDLE
4198                                || change == UidRecord.CHANGE_GONE_IDLE) {
4199                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4200                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4201                                        "UID idle uid=" + item.uid);
4202                                observer.onUidIdle(item.uid);
4203                            }
4204                            if (VALIDATE_UID_STATES && i == 0) {
4205                                if (validateUid != null) {
4206                                    validateUid.idle = true;
4207                                }
4208                            }
4209                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4210                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4211                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4212                                        "UID active uid=" + item.uid);
4213                                observer.onUidActive(item.uid);
4214                            }
4215                            if (VALIDATE_UID_STATES && i == 0) {
4216                                validateUid.idle = false;
4217                            }
4218                        }
4219                        if (change == UidRecord.CHANGE_GONE
4220                                || change == UidRecord.CHANGE_GONE_IDLE) {
4221                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4222                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4223                                        "UID gone uid=" + item.uid);
4224                                observer.onUidGone(item.uid);
4225                            }
4226                            if (VALIDATE_UID_STATES && i == 0) {
4227                                if (validateUid != null) {
4228                                    mValidateUids.remove(item.uid);
4229                                }
4230                            }
4231                        } else {
4232                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4233                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4234                                        "UID CHANGED uid=" + item.uid
4235                                                + ": " + item.processState);
4236                                observer.onUidStateChanged(item.uid, item.processState);
4237                            }
4238                            if (VALIDATE_UID_STATES && i == 0) {
4239                                validateUid.curProcState = validateUid.setProcState
4240                                        = item.processState;
4241                            }
4242                        }
4243                    }
4244                } catch (RemoteException e) {
4245                }
4246            }
4247        }
4248        mUidObservers.finishBroadcast();
4249
4250        synchronized (this) {
4251            for (int j=0; j<N; j++) {
4252                mAvailUidChanges.add(mActiveUidChanges[j]);
4253            }
4254        }
4255    }
4256
4257    @Override
4258    public final int startActivity(IApplicationThread caller, String callingPackage,
4259            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4260            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4261        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4262                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4263                UserHandle.getCallingUserId());
4264    }
4265
4266    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4267        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4268        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4269                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4270                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4271
4272        // TODO: Switch to user app stacks here.
4273        String mimeType = intent.getType();
4274        final Uri data = intent.getData();
4275        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4276            mimeType = getProviderMimeType(data, userId);
4277        }
4278        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4279
4280        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4281        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4282                null, 0, 0, null, null, null, null, false, userId, container, null);
4283    }
4284
4285    @Override
4286    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4287            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4288            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4289        enforceNotIsolatedCaller("startActivity");
4290        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4291                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4292        // TODO: Switch to user app stacks here.
4293        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4294                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4295                profilerInfo, null, null, bOptions, false, userId, null, null);
4296    }
4297
4298    @Override
4299    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4300            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4301            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4302            int userId) {
4303
4304        // This is very dangerous -- it allows you to perform a start activity (including
4305        // permission grants) as any app that may launch one of your own activities.  So
4306        // we will only allow this to be done from activities that are part of the core framework,
4307        // and then only when they are running as the system.
4308        final ActivityRecord sourceRecord;
4309        final int targetUid;
4310        final String targetPackage;
4311        synchronized (this) {
4312            if (resultTo == null) {
4313                throw new SecurityException("Must be called from an activity");
4314            }
4315            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4316            if (sourceRecord == null) {
4317                throw new SecurityException("Called with bad activity token: " + resultTo);
4318            }
4319            if (!sourceRecord.info.packageName.equals("android")) {
4320                throw new SecurityException(
4321                        "Must be called from an activity that is declared in the android package");
4322            }
4323            if (sourceRecord.app == null) {
4324                throw new SecurityException("Called without a process attached to activity");
4325            }
4326            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4327                // This is still okay, as long as this activity is running under the
4328                // uid of the original calling activity.
4329                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4330                    throw new SecurityException(
4331                            "Calling activity in uid " + sourceRecord.app.uid
4332                                    + " must be system uid or original calling uid "
4333                                    + sourceRecord.launchedFromUid);
4334                }
4335            }
4336            if (ignoreTargetSecurity) {
4337                if (intent.getComponent() == null) {
4338                    throw new SecurityException(
4339                            "Component must be specified with ignoreTargetSecurity");
4340                }
4341                if (intent.getSelector() != null) {
4342                    throw new SecurityException(
4343                            "Selector not allowed with ignoreTargetSecurity");
4344                }
4345            }
4346            targetUid = sourceRecord.launchedFromUid;
4347            targetPackage = sourceRecord.launchedFromPackage;
4348        }
4349
4350        if (userId == UserHandle.USER_NULL) {
4351            userId = UserHandle.getUserId(sourceRecord.app.uid);
4352        }
4353
4354        // TODO: Switch to user app stacks here.
4355        try {
4356            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4357                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4358                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4359            return ret;
4360        } catch (SecurityException e) {
4361            // XXX need to figure out how to propagate to original app.
4362            // A SecurityException here is generally actually a fault of the original
4363            // calling activity (such as a fairly granting permissions), so propagate it
4364            // back to them.
4365            /*
4366            StringBuilder msg = new StringBuilder();
4367            msg.append("While launching");
4368            msg.append(intent.toString());
4369            msg.append(": ");
4370            msg.append(e.getMessage());
4371            */
4372            throw e;
4373        }
4374    }
4375
4376    @Override
4377    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4378            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4379            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4380        enforceNotIsolatedCaller("startActivityAndWait");
4381        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4382                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4383        WaitResult res = new WaitResult();
4384        // TODO: Switch to user app stacks here.
4385        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4386                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4387                bOptions, false, userId, null, null);
4388        return res;
4389    }
4390
4391    @Override
4392    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4393            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4394            int startFlags, Configuration config, Bundle bOptions, int userId) {
4395        enforceNotIsolatedCaller("startActivityWithConfig");
4396        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4397                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4398        // TODO: Switch to user app stacks here.
4399        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4400                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4401                null, null, config, bOptions, false, userId, null, null);
4402        return ret;
4403    }
4404
4405    @Override
4406    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4407            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4408            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4409            throws TransactionTooLargeException {
4410        enforceNotIsolatedCaller("startActivityIntentSender");
4411        // Refuse possible leaked file descriptors
4412        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4413            throw new IllegalArgumentException("File descriptors passed in Intent");
4414        }
4415
4416        IIntentSender sender = intent.getTarget();
4417        if (!(sender instanceof PendingIntentRecord)) {
4418            throw new IllegalArgumentException("Bad PendingIntent object");
4419        }
4420
4421        PendingIntentRecord pir = (PendingIntentRecord)sender;
4422
4423        synchronized (this) {
4424            // If this is coming from the currently resumed activity, it is
4425            // effectively saying that app switches are allowed at this point.
4426            final ActivityStack stack = getFocusedStack();
4427            if (stack.mResumedActivity != null &&
4428                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4429                mAppSwitchesAllowedTime = 0;
4430            }
4431        }
4432        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4433                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4434        return ret;
4435    }
4436
4437    @Override
4438    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4439            Intent intent, String resolvedType, IVoiceInteractionSession session,
4440            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4441            Bundle bOptions, int userId) {
4442        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4443                != PackageManager.PERMISSION_GRANTED) {
4444            String msg = "Permission Denial: startVoiceActivity() from pid="
4445                    + Binder.getCallingPid()
4446                    + ", uid=" + Binder.getCallingUid()
4447                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4448            Slog.w(TAG, msg);
4449            throw new SecurityException(msg);
4450        }
4451        if (session == null || interactor == null) {
4452            throw new NullPointerException("null session or interactor");
4453        }
4454        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4455                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4456        // TODO: Switch to user app stacks here.
4457        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4458                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4459                null, bOptions, false, userId, null, null);
4460    }
4461
4462    @Override
4463    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4464            throws RemoteException {
4465        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4466        synchronized (this) {
4467            ActivityRecord activity = getFocusedStack().topActivity();
4468            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4469                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4470            }
4471            if (mRunningVoice != null || activity.task.voiceSession != null
4472                    || activity.voiceSession != null) {
4473                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4474                return;
4475            }
4476            if (activity.pendingVoiceInteractionStart) {
4477                Slog.w(TAG, "Pending start of voice interaction already.");
4478                return;
4479            }
4480            activity.pendingVoiceInteractionStart = true;
4481        }
4482        LocalServices.getService(VoiceInteractionManagerInternal.class)
4483                .startLocalVoiceInteraction(callingActivity, options);
4484    }
4485
4486    @Override
4487    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4488        LocalServices.getService(VoiceInteractionManagerInternal.class)
4489                .stopLocalVoiceInteraction(callingActivity);
4490    }
4491
4492    @Override
4493    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4494        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4495                .supportsLocalVoiceInteraction();
4496    }
4497
4498    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4499            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4500        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4501        if (activityToCallback == null) return;
4502        activityToCallback.setVoiceSessionLocked(voiceSession);
4503
4504        // Inform the activity
4505        try {
4506            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4507                    voiceInteractor);
4508            long token = Binder.clearCallingIdentity();
4509            try {
4510                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4511            } finally {
4512                Binder.restoreCallingIdentity(token);
4513            }
4514            // TODO: VI Should we cache the activity so that it's easier to find later
4515            // rather than scan through all the stacks and activities?
4516        } catch (RemoteException re) {
4517            activityToCallback.clearVoiceSessionLocked();
4518            // TODO: VI Should this terminate the voice session?
4519        }
4520    }
4521
4522    @Override
4523    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4524        synchronized (this) {
4525            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4526                if (keepAwake) {
4527                    mVoiceWakeLock.acquire();
4528                } else {
4529                    mVoiceWakeLock.release();
4530                }
4531            }
4532        }
4533    }
4534
4535    @Override
4536    public boolean startNextMatchingActivity(IBinder callingActivity,
4537            Intent intent, Bundle bOptions) {
4538        // Refuse possible leaked file descriptors
4539        if (intent != null && intent.hasFileDescriptors() == true) {
4540            throw new IllegalArgumentException("File descriptors passed in Intent");
4541        }
4542        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4543
4544        synchronized (this) {
4545            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4546            if (r == null) {
4547                ActivityOptions.abort(options);
4548                return false;
4549            }
4550            if (r.app == null || r.app.thread == null) {
4551                // The caller is not running...  d'oh!
4552                ActivityOptions.abort(options);
4553                return false;
4554            }
4555            intent = new Intent(intent);
4556            // The caller is not allowed to change the data.
4557            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4558            // And we are resetting to find the next component...
4559            intent.setComponent(null);
4560
4561            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4562
4563            ActivityInfo aInfo = null;
4564            try {
4565                List<ResolveInfo> resolves =
4566                    AppGlobals.getPackageManager().queryIntentActivities(
4567                            intent, r.resolvedType,
4568                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4569                            UserHandle.getCallingUserId()).getList();
4570
4571                // Look for the original activity in the list...
4572                final int N = resolves != null ? resolves.size() : 0;
4573                for (int i=0; i<N; i++) {
4574                    ResolveInfo rInfo = resolves.get(i);
4575                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4576                            && rInfo.activityInfo.name.equals(r.info.name)) {
4577                        // We found the current one...  the next matching is
4578                        // after it.
4579                        i++;
4580                        if (i<N) {
4581                            aInfo = resolves.get(i).activityInfo;
4582                        }
4583                        if (debug) {
4584                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4585                                    + "/" + r.info.name);
4586                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4587                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4588                        }
4589                        break;
4590                    }
4591                }
4592            } catch (RemoteException e) {
4593            }
4594
4595            if (aInfo == null) {
4596                // Nobody who is next!
4597                ActivityOptions.abort(options);
4598                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4599                return false;
4600            }
4601
4602            intent.setComponent(new ComponentName(
4603                    aInfo.applicationInfo.packageName, aInfo.name));
4604            intent.setFlags(intent.getFlags()&~(
4605                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4606                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4607                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4608                    Intent.FLAG_ACTIVITY_NEW_TASK));
4609
4610            // Okay now we need to start the new activity, replacing the
4611            // currently running activity.  This is a little tricky because
4612            // we want to start the new one as if the current one is finished,
4613            // but not finish the current one first so that there is no flicker.
4614            // And thus...
4615            final boolean wasFinishing = r.finishing;
4616            r.finishing = true;
4617
4618            // Propagate reply information over to the new activity.
4619            final ActivityRecord resultTo = r.resultTo;
4620            final String resultWho = r.resultWho;
4621            final int requestCode = r.requestCode;
4622            r.resultTo = null;
4623            if (resultTo != null) {
4624                resultTo.removeResultsLocked(r, resultWho, requestCode);
4625            }
4626
4627            final long origId = Binder.clearCallingIdentity();
4628            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4629                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4630                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4631                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4632                    false, false, null, null, null);
4633            Binder.restoreCallingIdentity(origId);
4634
4635            r.finishing = wasFinishing;
4636            if (res != ActivityManager.START_SUCCESS) {
4637                return false;
4638            }
4639            return true;
4640        }
4641    }
4642
4643    @Override
4644    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4645        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4646            String msg = "Permission Denial: startActivityFromRecents called without " +
4647                    START_TASKS_FROM_RECENTS;
4648            Slog.w(TAG, msg);
4649            throw new SecurityException(msg);
4650        }
4651        final long origId = Binder.clearCallingIdentity();
4652        try {
4653            synchronized (this) {
4654                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4655            }
4656        } finally {
4657            Binder.restoreCallingIdentity(origId);
4658        }
4659    }
4660
4661    final int startActivityInPackage(int uid, String callingPackage,
4662            Intent intent, String resolvedType, IBinder resultTo,
4663            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4664            IActivityContainer container, TaskRecord inTask) {
4665
4666        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4667                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4668
4669        // TODO: Switch to user app stacks here.
4670        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4671                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4672                null, null, null, bOptions, false, userId, container, inTask);
4673        return ret;
4674    }
4675
4676    @Override
4677    public final int startActivities(IApplicationThread caller, String callingPackage,
4678            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4679            int userId) {
4680        enforceNotIsolatedCaller("startActivities");
4681        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4682                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4683        // TODO: Switch to user app stacks here.
4684        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4685                resolvedTypes, resultTo, bOptions, userId);
4686        return ret;
4687    }
4688
4689    final int startActivitiesInPackage(int uid, String callingPackage,
4690            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4691            Bundle bOptions, int userId) {
4692
4693        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4694                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4695        // TODO: Switch to user app stacks here.
4696        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4697                resultTo, bOptions, userId);
4698        return ret;
4699    }
4700
4701    @Override
4702    public void reportActivityFullyDrawn(IBinder token) {
4703        synchronized (this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return;
4707            }
4708            r.reportFullyDrawnLocked();
4709        }
4710    }
4711
4712    @Override
4713    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4714        synchronized (this) {
4715            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4716            if (r == null) {
4717                return;
4718            }
4719            TaskRecord task = r.task;
4720            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4721                // Fixed screen orientation isn't supported when activities aren't in full screen
4722                // mode.
4723                return;
4724            }
4725            final long origId = Binder.clearCallingIdentity();
4726            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4727            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4728                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4729            if (config != null) {
4730                r.frozenBeforeDestroy = true;
4731                if (!updateConfigurationLocked(config, r, false)) {
4732                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4733                }
4734            }
4735            Binder.restoreCallingIdentity(origId);
4736        }
4737    }
4738
4739    @Override
4740    public int getRequestedOrientation(IBinder token) {
4741        synchronized (this) {
4742            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4743            if (r == null) {
4744                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4745            }
4746            return mWindowManager.getAppOrientation(r.appToken);
4747        }
4748    }
4749
4750    /**
4751     * This is the internal entry point for handling Activity.finish().
4752     *
4753     * @param token The Binder token referencing the Activity we want to finish.
4754     * @param resultCode Result code, if any, from this Activity.
4755     * @param resultData Result data (Intent), if any, from this Activity.
4756     * @param finishTask Whether to finish the task associated with this Activity.
4757     *
4758     * @return Returns true if the activity successfully finished, or false if it is still running.
4759     */
4760    @Override
4761    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4762            int finishTask) {
4763        // Refuse possible leaked file descriptors
4764        if (resultData != null && resultData.hasFileDescriptors() == true) {
4765            throw new IllegalArgumentException("File descriptors passed in Intent");
4766        }
4767
4768        synchronized(this) {
4769            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4770            if (r == null) {
4771                return true;
4772            }
4773            // Keep track of the root activity of the task before we finish it
4774            TaskRecord tr = r.task;
4775            ActivityRecord rootR = tr.getRootActivity();
4776            if (rootR == null) {
4777                Slog.w(TAG, "Finishing task with all activities already finished");
4778            }
4779            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4780            // finish.
4781            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4782                    mStackSupervisor.isLastLockedTask(tr)) {
4783                Slog.i(TAG, "Not finishing task in lock task mode");
4784                mStackSupervisor.showLockTaskToast();
4785                return false;
4786            }
4787            if (mController != null) {
4788                // Find the first activity that is not finishing.
4789                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4790                if (next != null) {
4791                    // ask watcher if this is allowed
4792                    boolean resumeOK = true;
4793                    try {
4794                        resumeOK = mController.activityResuming(next.packageName);
4795                    } catch (RemoteException e) {
4796                        mController = null;
4797                        Watchdog.getInstance().setActivityController(null);
4798                    }
4799
4800                    if (!resumeOK) {
4801                        Slog.i(TAG, "Not finishing activity because controller resumed");
4802                        return false;
4803                    }
4804                }
4805            }
4806            final long origId = Binder.clearCallingIdentity();
4807            try {
4808                boolean res;
4809                final boolean finishWithRootActivity =
4810                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4811                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4812                        || (finishWithRootActivity && r == rootR)) {
4813                    // If requested, remove the task that is associated to this activity only if it
4814                    // was the root activity in the task. The result code and data is ignored
4815                    // because we don't support returning them across task boundaries. Also, to
4816                    // keep backwards compatibility we remove the task from recents when finishing
4817                    // task with root activity.
4818                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4819                    if (!res) {
4820                        Slog.i(TAG, "Removing task failed to finish activity");
4821                    }
4822                } else {
4823                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4824                            resultData, "app-request", true);
4825                    if (!res) {
4826                        Slog.i(TAG, "Failed to finish by app-request");
4827                    }
4828                }
4829                return res;
4830            } finally {
4831                Binder.restoreCallingIdentity(origId);
4832            }
4833        }
4834    }
4835
4836    @Override
4837    public final void finishHeavyWeightApp() {
4838        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4839                != PackageManager.PERMISSION_GRANTED) {
4840            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4841                    + Binder.getCallingPid()
4842                    + ", uid=" + Binder.getCallingUid()
4843                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4844            Slog.w(TAG, msg);
4845            throw new SecurityException(msg);
4846        }
4847
4848        synchronized(this) {
4849            if (mHeavyWeightProcess == null) {
4850                return;
4851            }
4852
4853            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4854            for (int i = 0; i < activities.size(); i++) {
4855                ActivityRecord r = activities.get(i);
4856                if (!r.finishing && r.isInStackLocked()) {
4857                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4858                            null, "finish-heavy", true);
4859                }
4860            }
4861
4862            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4863                    mHeavyWeightProcess.userId, 0));
4864            mHeavyWeightProcess = null;
4865        }
4866    }
4867
4868    @Override
4869    public void crashApplication(int uid, int initialPid, String packageName,
4870            String message) {
4871        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4872                != PackageManager.PERMISSION_GRANTED) {
4873            String msg = "Permission Denial: crashApplication() from pid="
4874                    + Binder.getCallingPid()
4875                    + ", uid=" + Binder.getCallingUid()
4876                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4877            Slog.w(TAG, msg);
4878            throw new SecurityException(msg);
4879        }
4880
4881        synchronized(this) {
4882            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4883        }
4884    }
4885
4886    @Override
4887    public final void finishSubActivity(IBinder token, String resultWho,
4888            int requestCode) {
4889        synchronized(this) {
4890            final long origId = Binder.clearCallingIdentity();
4891            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4892            if (r != null) {
4893                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4894            }
4895            Binder.restoreCallingIdentity(origId);
4896        }
4897    }
4898
4899    @Override
4900    public boolean finishActivityAffinity(IBinder token) {
4901        synchronized(this) {
4902            final long origId = Binder.clearCallingIdentity();
4903            try {
4904                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4905                if (r == null) {
4906                    return false;
4907                }
4908
4909                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4910                // can finish.
4911                final TaskRecord task = r.task;
4912                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4913                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4914                    mStackSupervisor.showLockTaskToast();
4915                    return false;
4916                }
4917                return task.stack.finishActivityAffinityLocked(r);
4918            } finally {
4919                Binder.restoreCallingIdentity(origId);
4920            }
4921        }
4922    }
4923
4924    @Override
4925    public void finishVoiceTask(IVoiceInteractionSession session) {
4926        synchronized (this) {
4927            final long origId = Binder.clearCallingIdentity();
4928            try {
4929                // TODO: VI Consider treating local voice interactions and voice tasks
4930                // differently here
4931                mStackSupervisor.finishVoiceTask(session);
4932            } finally {
4933                Binder.restoreCallingIdentity(origId);
4934            }
4935        }
4936
4937    }
4938
4939    @Override
4940    public boolean releaseActivityInstance(IBinder token) {
4941        synchronized(this) {
4942            final long origId = Binder.clearCallingIdentity();
4943            try {
4944                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945                if (r == null) {
4946                    return false;
4947                }
4948                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4949            } finally {
4950                Binder.restoreCallingIdentity(origId);
4951            }
4952        }
4953    }
4954
4955    @Override
4956    public void releaseSomeActivities(IApplicationThread appInt) {
4957        synchronized(this) {
4958            final long origId = Binder.clearCallingIdentity();
4959            try {
4960                ProcessRecord app = getRecordForAppLocked(appInt);
4961                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4962            } finally {
4963                Binder.restoreCallingIdentity(origId);
4964            }
4965        }
4966    }
4967
4968    @Override
4969    public boolean willActivityBeVisible(IBinder token) {
4970        synchronized(this) {
4971            ActivityStack stack = ActivityRecord.getStackLocked(token);
4972            if (stack != null) {
4973                return stack.willActivityBeVisibleLocked(token);
4974            }
4975            return false;
4976        }
4977    }
4978
4979    @Override
4980    public void overridePendingTransition(IBinder token, String packageName,
4981            int enterAnim, int exitAnim) {
4982        synchronized(this) {
4983            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4984            if (self == null) {
4985                return;
4986            }
4987
4988            final long origId = Binder.clearCallingIdentity();
4989
4990            if (self.state == ActivityState.RESUMED
4991                    || self.state == ActivityState.PAUSING) {
4992                mWindowManager.overridePendingAppTransition(packageName,
4993                        enterAnim, exitAnim, null);
4994            }
4995
4996            Binder.restoreCallingIdentity(origId);
4997        }
4998    }
4999
5000    /**
5001     * Main function for removing an existing process from the activity manager
5002     * as a result of that process going away.  Clears out all connections
5003     * to the process.
5004     */
5005    private final void handleAppDiedLocked(ProcessRecord app,
5006            boolean restarting, boolean allowRestart) {
5007        int pid = app.pid;
5008        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5009        if (!kept && !restarting) {
5010            removeLruProcessLocked(app);
5011            if (pid > 0) {
5012                ProcessList.remove(pid);
5013            }
5014        }
5015
5016        if (mProfileProc == app) {
5017            clearProfilerLocked();
5018        }
5019
5020        // Remove this application's activities from active lists.
5021        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5022
5023        app.activities.clear();
5024
5025        if (app.instrumentationClass != null) {
5026            Slog.w(TAG, "Crash of app " + app.processName
5027                  + " running instrumentation " + app.instrumentationClass);
5028            Bundle info = new Bundle();
5029            info.putString("shortMsg", "Process crashed.");
5030            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5031        }
5032
5033        if (!restarting && hasVisibleActivities
5034                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5035            // If there was nothing to resume, and we are not already restarting this process, but
5036            // there is a visible activity that is hosted by the process...  then make sure all
5037            // visible activities are running, taking care of restarting this process.
5038            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5039        }
5040    }
5041
5042    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5043        IBinder threadBinder = thread.asBinder();
5044        // Find the application record.
5045        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5046            ProcessRecord rec = mLruProcesses.get(i);
5047            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5048                return i;
5049            }
5050        }
5051        return -1;
5052    }
5053
5054    final ProcessRecord getRecordForAppLocked(
5055            IApplicationThread thread) {
5056        if (thread == null) {
5057            return null;
5058        }
5059
5060        int appIndex = getLRURecordIndexForAppLocked(thread);
5061        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5062    }
5063
5064    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5065        // If there are no longer any background processes running,
5066        // and the app that died was not running instrumentation,
5067        // then tell everyone we are now low on memory.
5068        boolean haveBg = false;
5069        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5070            ProcessRecord rec = mLruProcesses.get(i);
5071            if (rec.thread != null
5072                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5073                haveBg = true;
5074                break;
5075            }
5076        }
5077
5078        if (!haveBg) {
5079            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5080            if (doReport) {
5081                long now = SystemClock.uptimeMillis();
5082                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5083                    doReport = false;
5084                } else {
5085                    mLastMemUsageReportTime = now;
5086                }
5087            }
5088            final ArrayList<ProcessMemInfo> memInfos
5089                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5090            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5091            long now = SystemClock.uptimeMillis();
5092            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5093                ProcessRecord rec = mLruProcesses.get(i);
5094                if (rec == dyingProc || rec.thread == null) {
5095                    continue;
5096                }
5097                if (doReport) {
5098                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5099                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5100                }
5101                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5102                    // The low memory report is overriding any current
5103                    // state for a GC request.  Make sure to do
5104                    // heavy/important/visible/foreground processes first.
5105                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5106                        rec.lastRequestedGc = 0;
5107                    } else {
5108                        rec.lastRequestedGc = rec.lastLowMemory;
5109                    }
5110                    rec.reportLowMemory = true;
5111                    rec.lastLowMemory = now;
5112                    mProcessesToGc.remove(rec);
5113                    addProcessToGcListLocked(rec);
5114                }
5115            }
5116            if (doReport) {
5117                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5118                mHandler.sendMessage(msg);
5119            }
5120            scheduleAppGcsLocked();
5121        }
5122    }
5123
5124    final void appDiedLocked(ProcessRecord app) {
5125       appDiedLocked(app, app.pid, app.thread, false);
5126    }
5127
5128    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5129            boolean fromBinderDied) {
5130        // First check if this ProcessRecord is actually active for the pid.
5131        synchronized (mPidsSelfLocked) {
5132            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5133            if (curProc != app) {
5134                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5135                return;
5136            }
5137        }
5138
5139        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5140        synchronized (stats) {
5141            stats.noteProcessDiedLocked(app.info.uid, pid);
5142        }
5143
5144        if (!app.killed) {
5145            if (!fromBinderDied) {
5146                Process.killProcessQuiet(pid);
5147            }
5148            killProcessGroup(app.uid, pid);
5149            app.killed = true;
5150        }
5151
5152        // Clean up already done if the process has been re-started.
5153        if (app.pid == pid && app.thread != null &&
5154                app.thread.asBinder() == thread.asBinder()) {
5155            boolean doLowMem = app.instrumentationClass == null;
5156            boolean doOomAdj = doLowMem;
5157            if (!app.killedByAm) {
5158                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5159                        + ") has died");
5160                mAllowLowerMemLevel = true;
5161            } else {
5162                // Note that we always want to do oom adj to update our state with the
5163                // new number of procs.
5164                mAllowLowerMemLevel = false;
5165                doLowMem = false;
5166            }
5167            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5168            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5169                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5170            handleAppDiedLocked(app, false, true);
5171
5172            if (doOomAdj) {
5173                updateOomAdjLocked();
5174            }
5175            if (doLowMem) {
5176                doLowMemReportIfNeededLocked(app);
5177            }
5178        } else if (app.pid != pid) {
5179            // A new process has already been started.
5180            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5181                    + ") has died and restarted (pid " + app.pid + ").");
5182            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5183        } else if (DEBUG_PROCESSES) {
5184            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5185                    + thread.asBinder());
5186        }
5187    }
5188
5189    /**
5190     * If a stack trace dump file is configured, dump process stack traces.
5191     * @param clearTraces causes the dump file to be erased prior to the new
5192     *    traces being written, if true; when false, the new traces will be
5193     *    appended to any existing file content.
5194     * @param firstPids of dalvik VM processes to dump stack traces for first
5195     * @param lastPids of dalvik VM processes to dump stack traces for last
5196     * @param nativeProcs optional list of native process names to dump stack crawls
5197     * @return file containing stack traces, or null if no dump file is configured
5198     */
5199    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5200            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5201        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5202        if (tracesPath == null || tracesPath.length() == 0) {
5203            return null;
5204        }
5205
5206        File tracesFile = new File(tracesPath);
5207        try {
5208            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5209            tracesFile.createNewFile();
5210            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5211        } catch (IOException e) {
5212            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5213            return null;
5214        }
5215
5216        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5217        return tracesFile;
5218    }
5219
5220    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5221            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5222        // Use a FileObserver to detect when traces finish writing.
5223        // The order of traces is considered important to maintain for legibility.
5224        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5225            @Override
5226            public synchronized void onEvent(int event, String path) { notify(); }
5227        };
5228
5229        try {
5230            observer.startWatching();
5231
5232            // First collect all of the stacks of the most important pids.
5233            if (firstPids != null) {
5234                try {
5235                    int num = firstPids.size();
5236                    for (int i = 0; i < num; i++) {
5237                        synchronized (observer) {
5238                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5239                                    + firstPids.get(i));
5240                            final long sime = SystemClock.elapsedRealtime();
5241                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5242                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5243                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5244                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5245                        }
5246                    }
5247                } catch (InterruptedException e) {
5248                    Slog.wtf(TAG, e);
5249                }
5250            }
5251
5252            // Next collect the stacks of the native pids
5253            if (nativeProcs != null) {
5254                int[] pids = Process.getPidsForCommands(nativeProcs);
5255                if (pids != null) {
5256                    for (int pid : pids) {
5257                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5258                        final long sime = SystemClock.elapsedRealtime();
5259                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5260                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5261                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5262                    }
5263                }
5264            }
5265
5266            // Lastly, measure CPU usage.
5267            if (processCpuTracker != null) {
5268                processCpuTracker.init();
5269                System.gc();
5270                processCpuTracker.update();
5271                try {
5272                    synchronized (processCpuTracker) {
5273                        processCpuTracker.wait(500); // measure over 1/2 second.
5274                    }
5275                } catch (InterruptedException e) {
5276                }
5277                processCpuTracker.update();
5278
5279                // We'll take the stack crawls of just the top apps using CPU.
5280                final int N = processCpuTracker.countWorkingStats();
5281                int numProcs = 0;
5282                for (int i=0; i<N && numProcs<5; i++) {
5283                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5284                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5285                        numProcs++;
5286                        try {
5287                            synchronized (observer) {
5288                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5289                                        + stats.pid);
5290                                final long stime = SystemClock.elapsedRealtime();
5291                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5292                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5293                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5294                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5295                            }
5296                        } catch (InterruptedException e) {
5297                            Slog.wtf(TAG, e);
5298                        }
5299                    } else if (DEBUG_ANR) {
5300                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5301                                + stats.pid);
5302                    }
5303                }
5304            }
5305        } finally {
5306            observer.stopWatching();
5307        }
5308    }
5309
5310    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5311        if (true || IS_USER_BUILD) {
5312            return;
5313        }
5314        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5315        if (tracesPath == null || tracesPath.length() == 0) {
5316            return;
5317        }
5318
5319        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5320        StrictMode.allowThreadDiskWrites();
5321        try {
5322            final File tracesFile = new File(tracesPath);
5323            final File tracesDir = tracesFile.getParentFile();
5324            final File tracesTmp = new File(tracesDir, "__tmp__");
5325            try {
5326                if (tracesFile.exists()) {
5327                    tracesTmp.delete();
5328                    tracesFile.renameTo(tracesTmp);
5329                }
5330                StringBuilder sb = new StringBuilder();
5331                Time tobj = new Time();
5332                tobj.set(System.currentTimeMillis());
5333                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5334                sb.append(": ");
5335                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5336                sb.append(" since ");
5337                sb.append(msg);
5338                FileOutputStream fos = new FileOutputStream(tracesFile);
5339                fos.write(sb.toString().getBytes());
5340                if (app == null) {
5341                    fos.write("\n*** No application process!".getBytes());
5342                }
5343                fos.close();
5344                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5345            } catch (IOException e) {
5346                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5347                return;
5348            }
5349
5350            if (app != null) {
5351                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5352                firstPids.add(app.pid);
5353                dumpStackTraces(tracesPath, firstPids, null, null, null);
5354            }
5355
5356            File lastTracesFile = null;
5357            File curTracesFile = null;
5358            for (int i=9; i>=0; i--) {
5359                String name = String.format(Locale.US, "slow%02d.txt", i);
5360                curTracesFile = new File(tracesDir, name);
5361                if (curTracesFile.exists()) {
5362                    if (lastTracesFile != null) {
5363                        curTracesFile.renameTo(lastTracesFile);
5364                    } else {
5365                        curTracesFile.delete();
5366                    }
5367                }
5368                lastTracesFile = curTracesFile;
5369            }
5370            tracesFile.renameTo(curTracesFile);
5371            if (tracesTmp.exists()) {
5372                tracesTmp.renameTo(tracesFile);
5373            }
5374        } finally {
5375            StrictMode.setThreadPolicy(oldPolicy);
5376        }
5377    }
5378
5379    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5380        if (!mLaunchWarningShown) {
5381            mLaunchWarningShown = true;
5382            mUiHandler.post(new Runnable() {
5383                @Override
5384                public void run() {
5385                    synchronized (ActivityManagerService.this) {
5386                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5387                        d.show();
5388                        mUiHandler.postDelayed(new Runnable() {
5389                            @Override
5390                            public void run() {
5391                                synchronized (ActivityManagerService.this) {
5392                                    d.dismiss();
5393                                    mLaunchWarningShown = false;
5394                                }
5395                            }
5396                        }, 4000);
5397                    }
5398                }
5399            });
5400        }
5401    }
5402
5403    @Override
5404    public boolean clearApplicationUserData(final String packageName,
5405            final IPackageDataObserver observer, int userId) {
5406        enforceNotIsolatedCaller("clearApplicationUserData");
5407        int uid = Binder.getCallingUid();
5408        int pid = Binder.getCallingPid();
5409        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5410                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5411
5412
5413        long callingId = Binder.clearCallingIdentity();
5414        try {
5415            IPackageManager pm = AppGlobals.getPackageManager();
5416            int pkgUid = -1;
5417            synchronized(this) {
5418                if (getPackageManagerInternalLocked().canPackageBeWiped(
5419                        userId, packageName)) {
5420                    throw new SecurityException(
5421                            "Cannot clear data for a device owner or a profile owner");
5422                }
5423
5424                try {
5425                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5426                } catch (RemoteException e) {
5427                }
5428                if (pkgUid == -1) {
5429                    Slog.w(TAG, "Invalid packageName: " + packageName);
5430                    if (observer != null) {
5431                        try {
5432                            observer.onRemoveCompleted(packageName, false);
5433                        } catch (RemoteException e) {
5434                            Slog.i(TAG, "Observer no longer exists.");
5435                        }
5436                    }
5437                    return false;
5438                }
5439                if (uid == pkgUid || checkComponentPermission(
5440                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5441                        pid, uid, -1, true)
5442                        == PackageManager.PERMISSION_GRANTED) {
5443                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5444                } else {
5445                    throw new SecurityException("PID " + pid + " does not have permission "
5446                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5447                                    + " of package " + packageName);
5448                }
5449
5450                // Remove all tasks match the cleared application package and user
5451                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5452                    final TaskRecord tr = mRecentTasks.get(i);
5453                    final String taskPackageName =
5454                            tr.getBaseIntent().getComponent().getPackageName();
5455                    if (tr.userId != userId) continue;
5456                    if (!taskPackageName.equals(packageName)) continue;
5457                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5458                }
5459            }
5460
5461            final int pkgUidF = pkgUid;
5462            final int userIdF = userId;
5463            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5464                @Override
5465                public void onRemoveCompleted(String packageName, boolean succeeded)
5466                        throws RemoteException {
5467                    synchronized (ActivityManagerService.this) {
5468                        finishForceStopPackageLocked(packageName, pkgUidF);
5469                    }
5470
5471                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5472                            Uri.fromParts("package", packageName, null));
5473                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5474                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5475                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5476                            null, null, 0, null, null, null, null, false, false, userIdF);
5477
5478                    if (observer != null) {
5479                        observer.onRemoveCompleted(packageName, succeeded);
5480                    }
5481                }
5482            };
5483
5484            try {
5485                // Clear application user data
5486                pm.clearApplicationUserData(packageName, localObserver, userId);
5487
5488                synchronized(this) {
5489                    // Remove all permissions granted from/to this package
5490                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5491                }
5492
5493                // Remove all zen rules created by this package; revoke it's zen access.
5494                INotificationManager inm = NotificationManager.getService();
5495                inm.removeAutomaticZenRules(packageName);
5496                inm.setNotificationPolicyAccessGranted(packageName, false);
5497
5498            } catch (RemoteException e) {
5499            }
5500        } finally {
5501            Binder.restoreCallingIdentity(callingId);
5502        }
5503        return true;
5504    }
5505
5506    @Override
5507    public void killBackgroundProcesses(final String packageName, int userId) {
5508        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5509                != PackageManager.PERMISSION_GRANTED &&
5510                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5511                        != PackageManager.PERMISSION_GRANTED) {
5512            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5513                    + Binder.getCallingPid()
5514                    + ", uid=" + Binder.getCallingUid()
5515                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5516            Slog.w(TAG, msg);
5517            throw new SecurityException(msg);
5518        }
5519
5520        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5521                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5522        long callingId = Binder.clearCallingIdentity();
5523        try {
5524            IPackageManager pm = AppGlobals.getPackageManager();
5525            synchronized(this) {
5526                int appId = -1;
5527                try {
5528                    appId = UserHandle.getAppId(
5529                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5530                } catch (RemoteException e) {
5531                }
5532                if (appId == -1) {
5533                    Slog.w(TAG, "Invalid packageName: " + packageName);
5534                    return;
5535                }
5536                killPackageProcessesLocked(packageName, appId, userId,
5537                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5538            }
5539        } finally {
5540            Binder.restoreCallingIdentity(callingId);
5541        }
5542    }
5543
5544    @Override
5545    public void killAllBackgroundProcesses() {
5546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5547                != PackageManager.PERMISSION_GRANTED) {
5548            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5549                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5550                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5551            Slog.w(TAG, msg);
5552            throw new SecurityException(msg);
5553        }
5554
5555        final long callingId = Binder.clearCallingIdentity();
5556        try {
5557            synchronized (this) {
5558                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5559                final int NP = mProcessNames.getMap().size();
5560                for (int ip = 0; ip < NP; ip++) {
5561                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5562                    final int NA = apps.size();
5563                    for (int ia = 0; ia < NA; ia++) {
5564                        final ProcessRecord app = apps.valueAt(ia);
5565                        if (app.persistent) {
5566                            // We don't kill persistent processes.
5567                            continue;
5568                        }
5569                        if (app.removed) {
5570                            procs.add(app);
5571                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5572                            app.removed = true;
5573                            procs.add(app);
5574                        }
5575                    }
5576                }
5577
5578                final int N = procs.size();
5579                for (int i = 0; i < N; i++) {
5580                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5581                }
5582
5583                mAllowLowerMemLevel = true;
5584
5585                updateOomAdjLocked();
5586                doLowMemReportIfNeededLocked(null);
5587            }
5588        } finally {
5589            Binder.restoreCallingIdentity(callingId);
5590        }
5591    }
5592
5593    /**
5594     * Kills all background processes, except those matching any of the
5595     * specified properties.
5596     *
5597     * @param minTargetSdk the target SDK version at or above which to preserve
5598     *                     processes, or {@code -1} to ignore the target SDK
5599     * @param maxProcState the process state at or below which to preserve
5600     *                     processes, or {@code -1} to ignore the process state
5601     */
5602    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5603        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5604                != PackageManager.PERMISSION_GRANTED) {
5605            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5606                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5607                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5608            Slog.w(TAG, msg);
5609            throw new SecurityException(msg);
5610        }
5611
5612        final long callingId = Binder.clearCallingIdentity();
5613        try {
5614            synchronized (this) {
5615                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5616                final int NP = mProcessNames.getMap().size();
5617                for (int ip = 0; ip < NP; ip++) {
5618                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5619                    final int NA = apps.size();
5620                    for (int ia = 0; ia < NA; ia++) {
5621                        final ProcessRecord app = apps.valueAt(ia);
5622                        if (app.removed) {
5623                            procs.add(app);
5624                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5625                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5626                            app.removed = true;
5627                            procs.add(app);
5628                        }
5629                    }
5630                }
5631
5632                final int N = procs.size();
5633                for (int i = 0; i < N; i++) {
5634                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5635                }
5636            }
5637        } finally {
5638            Binder.restoreCallingIdentity(callingId);
5639        }
5640    }
5641
5642    @Override
5643    public void forceStopPackage(final String packageName, int userId) {
5644        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5645                != PackageManager.PERMISSION_GRANTED) {
5646            String msg = "Permission Denial: forceStopPackage() from pid="
5647                    + Binder.getCallingPid()
5648                    + ", uid=" + Binder.getCallingUid()
5649                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5650            Slog.w(TAG, msg);
5651            throw new SecurityException(msg);
5652        }
5653        final int callingPid = Binder.getCallingPid();
5654        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5655                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5656        long callingId = Binder.clearCallingIdentity();
5657        try {
5658            IPackageManager pm = AppGlobals.getPackageManager();
5659            synchronized(this) {
5660                int[] users = userId == UserHandle.USER_ALL
5661                        ? mUserController.getUsers() : new int[] { userId };
5662                for (int user : users) {
5663                    int pkgUid = -1;
5664                    try {
5665                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5666                                user);
5667                    } catch (RemoteException e) {
5668                    }
5669                    if (pkgUid == -1) {
5670                        Slog.w(TAG, "Invalid packageName: " + packageName);
5671                        continue;
5672                    }
5673                    try {
5674                        pm.setPackageStoppedState(packageName, true, user);
5675                    } catch (RemoteException e) {
5676                    } catch (IllegalArgumentException e) {
5677                        Slog.w(TAG, "Failed trying to unstop package "
5678                                + packageName + ": " + e);
5679                    }
5680                    if (mUserController.isUserRunningLocked(user, 0)) {
5681                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5682                        finishForceStopPackageLocked(packageName, pkgUid);
5683                    }
5684                }
5685            }
5686        } finally {
5687            Binder.restoreCallingIdentity(callingId);
5688        }
5689    }
5690
5691    @Override
5692    public void addPackageDependency(String packageName) {
5693        synchronized (this) {
5694            int callingPid = Binder.getCallingPid();
5695            if (callingPid == Process.myPid()) {
5696                //  Yeah, um, no.
5697                return;
5698            }
5699            ProcessRecord proc;
5700            synchronized (mPidsSelfLocked) {
5701                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5702            }
5703            if (proc != null) {
5704                if (proc.pkgDeps == null) {
5705                    proc.pkgDeps = new ArraySet<String>(1);
5706                }
5707                proc.pkgDeps.add(packageName);
5708            }
5709        }
5710    }
5711
5712    /*
5713     * The pkg name and app id have to be specified.
5714     */
5715    @Override
5716    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5717        if (pkg == null) {
5718            return;
5719        }
5720        // Make sure the uid is valid.
5721        if (appid < 0) {
5722            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5723            return;
5724        }
5725        int callerUid = Binder.getCallingUid();
5726        // Only the system server can kill an application
5727        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5728            // Post an aysnc message to kill the application
5729            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5730            msg.arg1 = appid;
5731            msg.arg2 = 0;
5732            Bundle bundle = new Bundle();
5733            bundle.putString("pkg", pkg);
5734            bundle.putString("reason", reason);
5735            msg.obj = bundle;
5736            mHandler.sendMessage(msg);
5737        } else {
5738            throw new SecurityException(callerUid + " cannot kill pkg: " +
5739                    pkg);
5740        }
5741    }
5742
5743    @Override
5744    public void closeSystemDialogs(String reason) {
5745        enforceNotIsolatedCaller("closeSystemDialogs");
5746
5747        final int pid = Binder.getCallingPid();
5748        final int uid = Binder.getCallingUid();
5749        final long origId = Binder.clearCallingIdentity();
5750        try {
5751            synchronized (this) {
5752                // Only allow this from foreground processes, so that background
5753                // applications can't abuse it to prevent system UI from being shown.
5754                if (uid >= Process.FIRST_APPLICATION_UID) {
5755                    ProcessRecord proc;
5756                    synchronized (mPidsSelfLocked) {
5757                        proc = mPidsSelfLocked.get(pid);
5758                    }
5759                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5760                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5761                                + " from background process " + proc);
5762                        return;
5763                    }
5764                }
5765                closeSystemDialogsLocked(reason);
5766            }
5767        } finally {
5768            Binder.restoreCallingIdentity(origId);
5769        }
5770    }
5771
5772    void closeSystemDialogsLocked(String reason) {
5773        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5774        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5775                | Intent.FLAG_RECEIVER_FOREGROUND);
5776        if (reason != null) {
5777            intent.putExtra("reason", reason);
5778        }
5779        mWindowManager.closeSystemDialogs(reason);
5780
5781        mStackSupervisor.closeSystemDialogsLocked();
5782
5783        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5784                AppOpsManager.OP_NONE, null, false, false,
5785                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5786    }
5787
5788    @Override
5789    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5790        enforceNotIsolatedCaller("getProcessMemoryInfo");
5791        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5792        for (int i=pids.length-1; i>=0; i--) {
5793            ProcessRecord proc;
5794            int oomAdj;
5795            synchronized (this) {
5796                synchronized (mPidsSelfLocked) {
5797                    proc = mPidsSelfLocked.get(pids[i]);
5798                    oomAdj = proc != null ? proc.setAdj : 0;
5799                }
5800            }
5801            infos[i] = new Debug.MemoryInfo();
5802            Debug.getMemoryInfo(pids[i], infos[i]);
5803            if (proc != null) {
5804                synchronized (this) {
5805                    if (proc.thread != null && proc.setAdj == oomAdj) {
5806                        // Record this for posterity if the process has been stable.
5807                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5808                                infos[i].getTotalUss(), false, proc.pkgList);
5809                    }
5810                }
5811            }
5812        }
5813        return infos;
5814    }
5815
5816    @Override
5817    public long[] getProcessPss(int[] pids) {
5818        enforceNotIsolatedCaller("getProcessPss");
5819        long[] pss = new long[pids.length];
5820        for (int i=pids.length-1; i>=0; i--) {
5821            ProcessRecord proc;
5822            int oomAdj;
5823            synchronized (this) {
5824                synchronized (mPidsSelfLocked) {
5825                    proc = mPidsSelfLocked.get(pids[i]);
5826                    oomAdj = proc != null ? proc.setAdj : 0;
5827                }
5828            }
5829            long[] tmpUss = new long[1];
5830            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5831            if (proc != null) {
5832                synchronized (this) {
5833                    if (proc.thread != null && proc.setAdj == oomAdj) {
5834                        // Record this for posterity if the process has been stable.
5835                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5836                    }
5837                }
5838            }
5839        }
5840        return pss;
5841    }
5842
5843    @Override
5844    public void killApplicationProcess(String processName, int uid) {
5845        if (processName == null) {
5846            return;
5847        }
5848
5849        int callerUid = Binder.getCallingUid();
5850        // Only the system server can kill an application
5851        if (callerUid == Process.SYSTEM_UID) {
5852            synchronized (this) {
5853                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5854                if (app != null && app.thread != null) {
5855                    try {
5856                        app.thread.scheduleSuicide();
5857                    } catch (RemoteException e) {
5858                        // If the other end already died, then our work here is done.
5859                    }
5860                } else {
5861                    Slog.w(TAG, "Process/uid not found attempting kill of "
5862                            + processName + " / " + uid);
5863                }
5864            }
5865        } else {
5866            throw new SecurityException(callerUid + " cannot kill app process: " +
5867                    processName);
5868        }
5869    }
5870
5871    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5872        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5873                false, true, false, false, UserHandle.getUserId(uid), reason);
5874    }
5875
5876    private void finishForceStopPackageLocked(final String packageName, int uid) {
5877        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5878                Uri.fromParts("package", packageName, null));
5879        if (!mProcessesReady) {
5880            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5881                    | Intent.FLAG_RECEIVER_FOREGROUND);
5882        }
5883        intent.putExtra(Intent.EXTRA_UID, uid);
5884        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5885        broadcastIntentLocked(null, null, intent,
5886                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5887                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5888    }
5889
5890
5891    private final boolean killPackageProcessesLocked(String packageName, int appId,
5892            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5893            boolean doit, boolean evenPersistent, String reason) {
5894        ArrayList<ProcessRecord> procs = new ArrayList<>();
5895
5896        // Remove all processes this package may have touched: all with the
5897        // same UID (except for the system or root user), and all whose name
5898        // matches the package name.
5899        final int NP = mProcessNames.getMap().size();
5900        for (int ip=0; ip<NP; ip++) {
5901            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5902            final int NA = apps.size();
5903            for (int ia=0; ia<NA; ia++) {
5904                ProcessRecord app = apps.valueAt(ia);
5905                if (app.persistent && !evenPersistent) {
5906                    // we don't kill persistent processes
5907                    continue;
5908                }
5909                if (app.removed) {
5910                    if (doit) {
5911                        procs.add(app);
5912                    }
5913                    continue;
5914                }
5915
5916                // Skip process if it doesn't meet our oom adj requirement.
5917                if (app.setAdj < minOomAdj) {
5918                    continue;
5919                }
5920
5921                // If no package is specified, we call all processes under the
5922                // give user id.
5923                if (packageName == null) {
5924                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5925                        continue;
5926                    }
5927                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5928                        continue;
5929                    }
5930                // Package has been specified, we want to hit all processes
5931                // that match it.  We need to qualify this by the processes
5932                // that are running under the specified app and user ID.
5933                } else {
5934                    final boolean isDep = app.pkgDeps != null
5935                            && app.pkgDeps.contains(packageName);
5936                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5937                        continue;
5938                    }
5939                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5940                        continue;
5941                    }
5942                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5943                        continue;
5944                    }
5945                }
5946
5947                // Process has passed all conditions, kill it!
5948                if (!doit) {
5949                    return true;
5950                }
5951                app.removed = true;
5952                procs.add(app);
5953            }
5954        }
5955
5956        int N = procs.size();
5957        for (int i=0; i<N; i++) {
5958            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5959        }
5960        updateOomAdjLocked();
5961        return N > 0;
5962    }
5963
5964    private void cleanupDisabledPackageComponentsLocked(
5965            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5966
5967        Set<String> disabledClasses = null;
5968        boolean packageDisabled = false;
5969        IPackageManager pm = AppGlobals.getPackageManager();
5970
5971        if (changedClasses == null) {
5972            // Nothing changed...
5973            return;
5974        }
5975
5976        // Determine enable/disable state of the package and its components.
5977        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5978        for (int i = changedClasses.length - 1; i >= 0; i--) {
5979            final String changedClass = changedClasses[i];
5980
5981            if (changedClass.equals(packageName)) {
5982                try {
5983                    // Entire package setting changed
5984                    enabled = pm.getApplicationEnabledSetting(packageName,
5985                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5986                } catch (Exception e) {
5987                    // No such package/component; probably racing with uninstall.  In any
5988                    // event it means we have nothing further to do here.
5989                    return;
5990                }
5991                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5992                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5993                if (packageDisabled) {
5994                    // Entire package is disabled.
5995                    // No need to continue to check component states.
5996                    disabledClasses = null;
5997                    break;
5998                }
5999            } else {
6000                try {
6001                    enabled = pm.getComponentEnabledSetting(
6002                            new ComponentName(packageName, changedClass),
6003                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6004                } catch (Exception e) {
6005                    // As above, probably racing with uninstall.
6006                    return;
6007                }
6008                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6009                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6010                    if (disabledClasses == null) {
6011                        disabledClasses = new ArraySet<>(changedClasses.length);
6012                    }
6013                    disabledClasses.add(changedClass);
6014                }
6015            }
6016        }
6017
6018        if (!packageDisabled && disabledClasses == null) {
6019            // Nothing to do here...
6020            return;
6021        }
6022
6023        // Clean-up disabled activities.
6024        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6025                packageName, disabledClasses, true, false, userId) && mBooted) {
6026            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6027            mStackSupervisor.scheduleIdleLocked();
6028        }
6029
6030        // Clean-up disabled tasks
6031        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6032
6033        // Clean-up disabled services.
6034        mServices.bringDownDisabledPackageServicesLocked(
6035                packageName, disabledClasses, userId, false, killProcess, true);
6036
6037        // Clean-up disabled providers.
6038        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6039        mProviderMap.collectPackageProvidersLocked(
6040                packageName, disabledClasses, true, false, userId, providers);
6041        for (int i = providers.size() - 1; i >= 0; i--) {
6042            removeDyingProviderLocked(null, providers.get(i), true);
6043        }
6044
6045        // Clean-up disabled broadcast receivers.
6046        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6047            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6048                    packageName, disabledClasses, userId, true);
6049        }
6050
6051    }
6052
6053    final boolean clearBroadcastQueueForUserLocked(int userId) {
6054        boolean didSomething = false;
6055        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6056            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6057                    null, null, userId, true);
6058        }
6059        return didSomething;
6060    }
6061
6062    final boolean forceStopPackageLocked(String packageName, int appId,
6063            boolean callerWillRestart, boolean purgeCache, boolean doit,
6064            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6065        int i;
6066
6067        if (userId == UserHandle.USER_ALL && packageName == null) {
6068            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6069        }
6070
6071        if (appId < 0 && packageName != null) {
6072            try {
6073                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6074                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6075            } catch (RemoteException e) {
6076            }
6077        }
6078
6079        if (doit) {
6080            if (packageName != null) {
6081                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6082                        + " user=" + userId + ": " + reason);
6083            } else {
6084                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6085            }
6086
6087            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6088        }
6089
6090        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6091                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6092                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6093
6094        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6095                packageName, null, doit, evenPersistent, userId)) {
6096            if (!doit) {
6097                return true;
6098            }
6099            didSomething = true;
6100        }
6101
6102        if (mServices.bringDownDisabledPackageServicesLocked(
6103                packageName, null, userId, evenPersistent, true, doit)) {
6104            if (!doit) {
6105                return true;
6106            }
6107            didSomething = true;
6108        }
6109
6110        if (packageName == null) {
6111            // Remove all sticky broadcasts from this user.
6112            mStickyBroadcasts.remove(userId);
6113        }
6114
6115        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6116        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6117                userId, providers)) {
6118            if (!doit) {
6119                return true;
6120            }
6121            didSomething = true;
6122        }
6123        for (i = providers.size() - 1; i >= 0; i--) {
6124            removeDyingProviderLocked(null, providers.get(i), true);
6125        }
6126
6127        // Remove transient permissions granted from/to this package/user
6128        removeUriPermissionsForPackageLocked(packageName, userId, false);
6129
6130        if (doit) {
6131            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6132                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6133                        packageName, null, userId, doit);
6134            }
6135        }
6136
6137        if (packageName == null || uninstalling) {
6138            // Remove pending intents.  For now we only do this when force
6139            // stopping users, because we have some problems when doing this
6140            // for packages -- app widgets are not currently cleaned up for
6141            // such packages, so they can be left with bad pending intents.
6142            if (mIntentSenderRecords.size() > 0) {
6143                Iterator<WeakReference<PendingIntentRecord>> it
6144                        = mIntentSenderRecords.values().iterator();
6145                while (it.hasNext()) {
6146                    WeakReference<PendingIntentRecord> wpir = it.next();
6147                    if (wpir == null) {
6148                        it.remove();
6149                        continue;
6150                    }
6151                    PendingIntentRecord pir = wpir.get();
6152                    if (pir == null) {
6153                        it.remove();
6154                        continue;
6155                    }
6156                    if (packageName == null) {
6157                        // Stopping user, remove all objects for the user.
6158                        if (pir.key.userId != userId) {
6159                            // Not the same user, skip it.
6160                            continue;
6161                        }
6162                    } else {
6163                        if (UserHandle.getAppId(pir.uid) != appId) {
6164                            // Different app id, skip it.
6165                            continue;
6166                        }
6167                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6168                            // Different user, skip it.
6169                            continue;
6170                        }
6171                        if (!pir.key.packageName.equals(packageName)) {
6172                            // Different package, skip it.
6173                            continue;
6174                        }
6175                    }
6176                    if (!doit) {
6177                        return true;
6178                    }
6179                    didSomething = true;
6180                    it.remove();
6181                    pir.canceled = true;
6182                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6183                        pir.key.activity.pendingResults.remove(pir.ref);
6184                    }
6185                }
6186            }
6187        }
6188
6189        if (doit) {
6190            if (purgeCache && packageName != null) {
6191                AttributeCache ac = AttributeCache.instance();
6192                if (ac != null) {
6193                    ac.removePackage(packageName);
6194                }
6195            }
6196            if (mBooted) {
6197                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6198                mStackSupervisor.scheduleIdleLocked();
6199            }
6200        }
6201
6202        return didSomething;
6203    }
6204
6205    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6206        ProcessRecord old = mProcessNames.remove(name, uid);
6207        if (old != null) {
6208            old.uidRecord.numProcs--;
6209            if (old.uidRecord.numProcs == 0) {
6210                // No more processes using this uid, tell clients it is gone.
6211                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6212                        "No more processes in " + old.uidRecord);
6213                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6214                mActiveUids.remove(uid);
6215                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6216            }
6217            old.uidRecord = null;
6218        }
6219        mIsolatedProcesses.remove(uid);
6220        return old;
6221    }
6222
6223    private final void addProcessNameLocked(ProcessRecord proc) {
6224        // We shouldn't already have a process under this name, but just in case we
6225        // need to clean up whatever may be there now.
6226        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6227        if (old == proc && proc.persistent) {
6228            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6229            Slog.w(TAG, "Re-adding persistent process " + proc);
6230        } else if (old != null) {
6231            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6232        }
6233        UidRecord uidRec = mActiveUids.get(proc.uid);
6234        if (uidRec == null) {
6235            uidRec = new UidRecord(proc.uid);
6236            // This is the first appearance of the uid, report it now!
6237            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6238                    "Creating new process uid: " + uidRec);
6239            mActiveUids.put(proc.uid, uidRec);
6240            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6241            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6242        }
6243        proc.uidRecord = uidRec;
6244        uidRec.numProcs++;
6245        mProcessNames.put(proc.processName, proc.uid, proc);
6246        if (proc.isolated) {
6247            mIsolatedProcesses.put(proc.uid, proc);
6248        }
6249    }
6250
6251    boolean removeProcessLocked(ProcessRecord app,
6252            boolean callerWillRestart, boolean allowRestart, String reason) {
6253        final String name = app.processName;
6254        final int uid = app.uid;
6255        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6256            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6257
6258        ProcessRecord old = mProcessNames.get(name, uid);
6259        if (old != app) {
6260            // This process is no longer active, so nothing to do.
6261            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6262            return false;
6263        }
6264        removeProcessNameLocked(name, uid);
6265        if (mHeavyWeightProcess == app) {
6266            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6267                    mHeavyWeightProcess.userId, 0));
6268            mHeavyWeightProcess = null;
6269        }
6270        boolean needRestart = false;
6271        if (app.pid > 0 && app.pid != MY_PID) {
6272            int pid = app.pid;
6273            synchronized (mPidsSelfLocked) {
6274                mPidsSelfLocked.remove(pid);
6275                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6276            }
6277            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6278            if (app.isolated) {
6279                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6280            }
6281            boolean willRestart = false;
6282            if (app.persistent && !app.isolated) {
6283                if (!callerWillRestart) {
6284                    willRestart = true;
6285                } else {
6286                    needRestart = true;
6287                }
6288            }
6289            app.kill(reason, true);
6290            handleAppDiedLocked(app, willRestart, allowRestart);
6291            if (willRestart) {
6292                removeLruProcessLocked(app);
6293                addAppLocked(app.info, false, null /* ABI override */);
6294            }
6295        } else {
6296            mRemovedProcesses.add(app);
6297        }
6298
6299        return needRestart;
6300    }
6301
6302    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6303        cleanupAppInLaunchingProvidersLocked(app, true);
6304        removeProcessLocked(app, false, true, "timeout publishing content providers");
6305    }
6306
6307    private final void processStartTimedOutLocked(ProcessRecord app) {
6308        final int pid = app.pid;
6309        boolean gone = false;
6310        synchronized (mPidsSelfLocked) {
6311            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6312            if (knownApp != null && knownApp.thread == null) {
6313                mPidsSelfLocked.remove(pid);
6314                gone = true;
6315            }
6316        }
6317
6318        if (gone) {
6319            Slog.w(TAG, "Process " + app + " failed to attach");
6320            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6321                    pid, app.uid, app.processName);
6322            removeProcessNameLocked(app.processName, app.uid);
6323            if (mHeavyWeightProcess == app) {
6324                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6325                        mHeavyWeightProcess.userId, 0));
6326                mHeavyWeightProcess = null;
6327            }
6328            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6329            if (app.isolated) {
6330                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6331            }
6332            // Take care of any launching providers waiting for this process.
6333            cleanupAppInLaunchingProvidersLocked(app, true);
6334            // Take care of any services that are waiting for the process.
6335            mServices.processStartTimedOutLocked(app);
6336            app.kill("start timeout", true);
6337            removeLruProcessLocked(app);
6338            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6339                Slog.w(TAG, "Unattached app died before backup, skipping");
6340                try {
6341                    IBackupManager bm = IBackupManager.Stub.asInterface(
6342                            ServiceManager.getService(Context.BACKUP_SERVICE));
6343                    bm.agentDisconnected(app.info.packageName);
6344                } catch (RemoteException e) {
6345                    // Can't happen; the backup manager is local
6346                }
6347            }
6348            if (isPendingBroadcastProcessLocked(pid)) {
6349                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6350                skipPendingBroadcastLocked(pid);
6351            }
6352        } else {
6353            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6354        }
6355    }
6356
6357    private final boolean attachApplicationLocked(IApplicationThread thread,
6358            int pid) {
6359
6360        // Find the application record that is being attached...  either via
6361        // the pid if we are running in multiple processes, or just pull the
6362        // next app record if we are emulating process with anonymous threads.
6363        ProcessRecord app;
6364        if (pid != MY_PID && pid >= 0) {
6365            synchronized (mPidsSelfLocked) {
6366                app = mPidsSelfLocked.get(pid);
6367            }
6368        } else {
6369            app = null;
6370        }
6371
6372        if (app == null) {
6373            Slog.w(TAG, "No pending application record for pid " + pid
6374                    + " (IApplicationThread " + thread + "); dropping process");
6375            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6376            if (pid > 0 && pid != MY_PID) {
6377                Process.killProcessQuiet(pid);
6378                //TODO: killProcessGroup(app.info.uid, pid);
6379            } else {
6380                try {
6381                    thread.scheduleExit();
6382                } catch (Exception e) {
6383                    // Ignore exceptions.
6384                }
6385            }
6386            return false;
6387        }
6388
6389        // If this application record is still attached to a previous
6390        // process, clean it up now.
6391        if (app.thread != null) {
6392            handleAppDiedLocked(app, true, true);
6393        }
6394
6395        // Tell the process all about itself.
6396
6397        if (DEBUG_ALL) Slog.v(
6398                TAG, "Binding process pid " + pid + " to record " + app);
6399
6400        final String processName = app.processName;
6401        try {
6402            AppDeathRecipient adr = new AppDeathRecipient(
6403                    app, pid, thread);
6404            thread.asBinder().linkToDeath(adr, 0);
6405            app.deathRecipient = adr;
6406        } catch (RemoteException e) {
6407            app.resetPackageList(mProcessStats);
6408            startProcessLocked(app, "link fail", processName);
6409            return false;
6410        }
6411
6412        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6413
6414        app.makeActive(thread, mProcessStats);
6415        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6416        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6417        app.forcingToForeground = null;
6418        updateProcessForegroundLocked(app, false, false);
6419        app.hasShownUi = false;
6420        app.debugging = false;
6421        app.cached = false;
6422        app.killedByAm = false;
6423
6424        // We carefully use the same state that PackageManager uses for
6425        // filtering, since we use this flag to decide if we need to install
6426        // providers when user is unlocked later
6427        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6428
6429        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6430
6431        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6432        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6433
6434        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6435            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6436            msg.obj = app;
6437            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6438        }
6439
6440        if (!normalMode) {
6441            Slog.i(TAG, "Launching preboot mode app: " + app);
6442        }
6443
6444        if (DEBUG_ALL) Slog.v(
6445            TAG, "New app record " + app
6446            + " thread=" + thread.asBinder() + " pid=" + pid);
6447        try {
6448            int testMode = IApplicationThread.DEBUG_OFF;
6449            if (mDebugApp != null && mDebugApp.equals(processName)) {
6450                testMode = mWaitForDebugger
6451                    ? IApplicationThread.DEBUG_WAIT
6452                    : IApplicationThread.DEBUG_ON;
6453                app.debugging = true;
6454                if (mDebugTransient) {
6455                    mDebugApp = mOrigDebugApp;
6456                    mWaitForDebugger = mOrigWaitForDebugger;
6457                }
6458            }
6459            String profileFile = app.instrumentationProfileFile;
6460            ParcelFileDescriptor profileFd = null;
6461            int samplingInterval = 0;
6462            boolean profileAutoStop = false;
6463            if (mProfileApp != null && mProfileApp.equals(processName)) {
6464                mProfileProc = app;
6465                profileFile = mProfileFile;
6466                profileFd = mProfileFd;
6467                samplingInterval = mSamplingInterval;
6468                profileAutoStop = mAutoStopProfiler;
6469            }
6470            boolean enableTrackAllocation = false;
6471            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6472                enableTrackAllocation = true;
6473                mTrackAllocationApp = null;
6474            }
6475
6476            // If the app is being launched for restore or full backup, set it up specially
6477            boolean isRestrictedBackupMode = false;
6478            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6479                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6480                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6481                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6482                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6483            }
6484
6485            if (app.instrumentationClass != null) {
6486                notifyPackageUse(app.instrumentationClass.getPackageName(),
6487                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6488            }
6489            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6490                    + processName + " with config " + mConfiguration);
6491            ApplicationInfo appInfo = app.instrumentationInfo != null
6492                    ? app.instrumentationInfo : app.info;
6493            app.compat = compatibilityInfoForPackageLocked(appInfo);
6494            if (profileFd != null) {
6495                profileFd = profileFd.dup();
6496            }
6497            ProfilerInfo profilerInfo = profileFile == null ? null
6498                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6499            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6500                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6501                    app.instrumentationUiAutomationConnection, testMode,
6502                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6503                    isRestrictedBackupMode || !normalMode, app.persistent,
6504                    new Configuration(mConfiguration), app.compat,
6505                    getCommonServicesLocked(app.isolated),
6506                    mCoreSettingsObserver.getCoreSettingsLocked());
6507            updateLruProcessLocked(app, false, null);
6508            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6509        } catch (Exception e) {
6510            // todo: Yikes!  What should we do?  For now we will try to
6511            // start another process, but that could easily get us in
6512            // an infinite loop of restarting processes...
6513            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6514
6515            app.resetPackageList(mProcessStats);
6516            app.unlinkDeathRecipient();
6517            startProcessLocked(app, "bind fail", processName);
6518            return false;
6519        }
6520
6521        // Remove this record from the list of starting applications.
6522        mPersistentStartingProcesses.remove(app);
6523        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6524                "Attach application locked removing on hold: " + app);
6525        mProcessesOnHold.remove(app);
6526
6527        boolean badApp = false;
6528        boolean didSomething = false;
6529
6530        // See if the top visible activity is waiting to run in this process...
6531        if (normalMode) {
6532            try {
6533                if (mStackSupervisor.attachApplicationLocked(app)) {
6534                    didSomething = true;
6535                }
6536            } catch (Exception e) {
6537                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6538                badApp = true;
6539            }
6540        }
6541
6542        // Find any services that should be running in this process...
6543        if (!badApp) {
6544            try {
6545                didSomething |= mServices.attachApplicationLocked(app, processName);
6546            } catch (Exception e) {
6547                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6548                badApp = true;
6549            }
6550        }
6551
6552        // Check if a next-broadcast receiver is in this process...
6553        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6554            try {
6555                didSomething |= sendPendingBroadcastsLocked(app);
6556            } catch (Exception e) {
6557                // If the app died trying to launch the receiver we declare it 'bad'
6558                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6559                badApp = true;
6560            }
6561        }
6562
6563        // Check whether the next backup agent is in this process...
6564        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6565            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6566                    "New app is backup target, launching agent for " + app);
6567            notifyPackageUse(mBackupTarget.appInfo.packageName,
6568                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6569            try {
6570                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6571                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6572                        mBackupTarget.backupMode);
6573            } catch (Exception e) {
6574                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6575                badApp = true;
6576            }
6577        }
6578
6579        if (badApp) {
6580            app.kill("error during init", true);
6581            handleAppDiedLocked(app, false, true);
6582            return false;
6583        }
6584
6585        if (!didSomething) {
6586            updateOomAdjLocked();
6587        }
6588
6589        return true;
6590    }
6591
6592    @Override
6593    public final void attachApplication(IApplicationThread thread) {
6594        synchronized (this) {
6595            int callingPid = Binder.getCallingPid();
6596            final long origId = Binder.clearCallingIdentity();
6597            attachApplicationLocked(thread, callingPid);
6598            Binder.restoreCallingIdentity(origId);
6599        }
6600    }
6601
6602    @Override
6603    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6604        final long origId = Binder.clearCallingIdentity();
6605        synchronized (this) {
6606            ActivityStack stack = ActivityRecord.getStackLocked(token);
6607            if (stack != null) {
6608                ActivityRecord r =
6609                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6610                if (stopProfiling) {
6611                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6612                        try {
6613                            mProfileFd.close();
6614                        } catch (IOException e) {
6615                        }
6616                        clearProfilerLocked();
6617                    }
6618                }
6619            }
6620        }
6621        Binder.restoreCallingIdentity(origId);
6622    }
6623
6624    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6625        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6626                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6627    }
6628
6629    void enableScreenAfterBoot() {
6630        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6631                SystemClock.uptimeMillis());
6632        mWindowManager.enableScreenAfterBoot();
6633
6634        synchronized (this) {
6635            updateEventDispatchingLocked();
6636        }
6637    }
6638
6639    @Override
6640    public void showBootMessage(final CharSequence msg, final boolean always) {
6641        if (Binder.getCallingUid() != Process.myUid()) {
6642            // These days only the core system can call this, so apps can't get in
6643            // the way of what we show about running them.
6644        }
6645        mWindowManager.showBootMessage(msg, always);
6646    }
6647
6648    @Override
6649    public void keyguardWaitingForActivityDrawn() {
6650        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6651        final long token = Binder.clearCallingIdentity();
6652        try {
6653            synchronized (this) {
6654                if (DEBUG_LOCKSCREEN) logLockScreen("");
6655                mWindowManager.keyguardWaitingForActivityDrawn();
6656                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6657                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6658                    updateSleepIfNeededLocked();
6659                }
6660            }
6661        } finally {
6662            Binder.restoreCallingIdentity(token);
6663        }
6664    }
6665
6666    @Override
6667    public void keyguardGoingAway(int flags) {
6668        enforceNotIsolatedCaller("keyguardGoingAway");
6669        final long token = Binder.clearCallingIdentity();
6670        try {
6671            synchronized (this) {
6672                if (DEBUG_LOCKSCREEN) logLockScreen("");
6673                mWindowManager.keyguardGoingAway(flags);
6674                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6675                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6676                    updateSleepIfNeededLocked();
6677
6678                    // Some stack visibility might change (e.g. docked stack)
6679                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6680                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6681                }
6682            }
6683        } finally {
6684            Binder.restoreCallingIdentity(token);
6685        }
6686    }
6687
6688    final void finishBooting() {
6689        synchronized (this) {
6690            if (!mBootAnimationComplete) {
6691                mCallFinishBooting = true;
6692                return;
6693            }
6694            mCallFinishBooting = false;
6695        }
6696
6697        ArraySet<String> completedIsas = new ArraySet<String>();
6698        for (String abi : Build.SUPPORTED_ABIS) {
6699            Process.establishZygoteConnectionForAbi(abi);
6700            final String instructionSet = VMRuntime.getInstructionSet(abi);
6701            if (!completedIsas.contains(instructionSet)) {
6702                try {
6703                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6704                } catch (InstallerException e) {
6705                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6706                            e.getMessage() +")");
6707                }
6708                completedIsas.add(instructionSet);
6709            }
6710        }
6711
6712        IntentFilter pkgFilter = new IntentFilter();
6713        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6714        pkgFilter.addDataScheme("package");
6715        mContext.registerReceiver(new BroadcastReceiver() {
6716            @Override
6717            public void onReceive(Context context, Intent intent) {
6718                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6719                if (pkgs != null) {
6720                    for (String pkg : pkgs) {
6721                        synchronized (ActivityManagerService.this) {
6722                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6723                                    0, "query restart")) {
6724                                setResultCode(Activity.RESULT_OK);
6725                                return;
6726                            }
6727                        }
6728                    }
6729                }
6730            }
6731        }, pkgFilter);
6732
6733        IntentFilter dumpheapFilter = new IntentFilter();
6734        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6735        mContext.registerReceiver(new BroadcastReceiver() {
6736            @Override
6737            public void onReceive(Context context, Intent intent) {
6738                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6739                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6740                } else {
6741                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6742                }
6743            }
6744        }, dumpheapFilter);
6745
6746        // Let system services know.
6747        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6748
6749        synchronized (this) {
6750            // Ensure that any processes we had put on hold are now started
6751            // up.
6752            final int NP = mProcessesOnHold.size();
6753            if (NP > 0) {
6754                ArrayList<ProcessRecord> procs =
6755                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6756                for (int ip=0; ip<NP; ip++) {
6757                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6758                            + procs.get(ip));
6759                    startProcessLocked(procs.get(ip), "on-hold", null);
6760                }
6761            }
6762
6763            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6764                // Start looking for apps that are abusing wake locks.
6765                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6766                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6767                // Tell anyone interested that we are done booting!
6768                SystemProperties.set("sys.boot_completed", "1");
6769
6770                // And trigger dev.bootcomplete if we are not showing encryption progress
6771                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6772                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6773                    SystemProperties.set("dev.bootcomplete", "1");
6774                }
6775                mUserController.sendBootCompletedLocked(
6776                        new IIntentReceiver.Stub() {
6777                            @Override
6778                            public void performReceive(Intent intent, int resultCode,
6779                                    String data, Bundle extras, boolean ordered,
6780                                    boolean sticky, int sendingUser) {
6781                                synchronized (ActivityManagerService.this) {
6782                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6783                                            true, false);
6784                                }
6785                            }
6786                        });
6787                scheduleStartProfilesLocked();
6788            }
6789        }
6790    }
6791
6792    @Override
6793    public void bootAnimationComplete() {
6794        final boolean callFinishBooting;
6795        synchronized (this) {
6796            callFinishBooting = mCallFinishBooting;
6797            mBootAnimationComplete = true;
6798        }
6799        if (callFinishBooting) {
6800            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6801            finishBooting();
6802            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6803        }
6804    }
6805
6806    final void ensureBootCompleted() {
6807        boolean booting;
6808        boolean enableScreen;
6809        synchronized (this) {
6810            booting = mBooting;
6811            mBooting = false;
6812            enableScreen = !mBooted;
6813            mBooted = true;
6814        }
6815
6816        if (booting) {
6817            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6818            finishBooting();
6819            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6820        }
6821
6822        if (enableScreen) {
6823            enableScreenAfterBoot();
6824        }
6825    }
6826
6827    @Override
6828    public final void activityResumed(IBinder token) {
6829        final long origId = Binder.clearCallingIdentity();
6830        synchronized(this) {
6831            ActivityStack stack = ActivityRecord.getStackLocked(token);
6832            if (stack != null) {
6833                stack.activityResumedLocked(token);
6834            }
6835        }
6836        Binder.restoreCallingIdentity(origId);
6837    }
6838
6839    @Override
6840    public final void activityPaused(IBinder token) {
6841        final long origId = Binder.clearCallingIdentity();
6842        synchronized(this) {
6843            ActivityStack stack = ActivityRecord.getStackLocked(token);
6844            if (stack != null) {
6845                stack.activityPausedLocked(token, false);
6846            }
6847        }
6848        Binder.restoreCallingIdentity(origId);
6849    }
6850
6851    @Override
6852    public final void activityStopped(IBinder token, Bundle icicle,
6853            PersistableBundle persistentState, CharSequence description) {
6854        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6855
6856        // Refuse possible leaked file descriptors
6857        if (icicle != null && icicle.hasFileDescriptors()) {
6858            throw new IllegalArgumentException("File descriptors passed in Bundle");
6859        }
6860
6861        final long origId = Binder.clearCallingIdentity();
6862
6863        synchronized (this) {
6864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6865            if (r != null) {
6866                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6867            }
6868        }
6869
6870        trimApplications();
6871
6872        Binder.restoreCallingIdentity(origId);
6873    }
6874
6875    @Override
6876    public final void activityDestroyed(IBinder token) {
6877        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6878        synchronized (this) {
6879            ActivityStack stack = ActivityRecord.getStackLocked(token);
6880            if (stack != null) {
6881                stack.activityDestroyedLocked(token, "activityDestroyed");
6882            }
6883        }
6884    }
6885
6886    @Override
6887    public final void activityRelaunched(IBinder token) {
6888        final long origId = Binder.clearCallingIdentity();
6889        synchronized (this) {
6890            mStackSupervisor.activityRelaunchedLocked(token);
6891        }
6892        Binder.restoreCallingIdentity(origId);
6893    }
6894
6895    @Override
6896    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6897            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6898        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6899                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6900        synchronized (this) {
6901            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6902            if (record == null) {
6903                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6904                        + "found for: " + token);
6905            }
6906            record.setSizeConfigurations(horizontalSizeConfiguration,
6907                    verticalSizeConfigurations, smallestSizeConfigurations);
6908        }
6909    }
6910
6911    @Override
6912    public final void backgroundResourcesReleased(IBinder token) {
6913        final long origId = Binder.clearCallingIdentity();
6914        try {
6915            synchronized (this) {
6916                ActivityStack stack = ActivityRecord.getStackLocked(token);
6917                if (stack != null) {
6918                    stack.backgroundResourcesReleased();
6919                }
6920            }
6921        } finally {
6922            Binder.restoreCallingIdentity(origId);
6923        }
6924    }
6925
6926    @Override
6927    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6928        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6929    }
6930
6931    @Override
6932    public final void notifyEnterAnimationComplete(IBinder token) {
6933        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6934    }
6935
6936    @Override
6937    public String getCallingPackage(IBinder token) {
6938        synchronized (this) {
6939            ActivityRecord r = getCallingRecordLocked(token);
6940            return r != null ? r.info.packageName : null;
6941        }
6942    }
6943
6944    @Override
6945    public ComponentName getCallingActivity(IBinder token) {
6946        synchronized (this) {
6947            ActivityRecord r = getCallingRecordLocked(token);
6948            return r != null ? r.intent.getComponent() : null;
6949        }
6950    }
6951
6952    private ActivityRecord getCallingRecordLocked(IBinder token) {
6953        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6954        if (r == null) {
6955            return null;
6956        }
6957        return r.resultTo;
6958    }
6959
6960    @Override
6961    public ComponentName getActivityClassForToken(IBinder token) {
6962        synchronized(this) {
6963            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6964            if (r == null) {
6965                return null;
6966            }
6967            return r.intent.getComponent();
6968        }
6969    }
6970
6971    @Override
6972    public String getPackageForToken(IBinder token) {
6973        synchronized(this) {
6974            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6975            if (r == null) {
6976                return null;
6977            }
6978            return r.packageName;
6979        }
6980    }
6981
6982    @Override
6983    public boolean isRootVoiceInteraction(IBinder token) {
6984        synchronized(this) {
6985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6986            if (r == null) {
6987                return false;
6988            }
6989            return r.rootVoiceInteraction;
6990        }
6991    }
6992
6993    @Override
6994    public IIntentSender getIntentSender(int type,
6995            String packageName, IBinder token, String resultWho,
6996            int requestCode, Intent[] intents, String[] resolvedTypes,
6997            int flags, Bundle bOptions, int userId) {
6998        enforceNotIsolatedCaller("getIntentSender");
6999        // Refuse possible leaked file descriptors
7000        if (intents != null) {
7001            if (intents.length < 1) {
7002                throw new IllegalArgumentException("Intents array length must be >= 1");
7003            }
7004            for (int i=0; i<intents.length; i++) {
7005                Intent intent = intents[i];
7006                if (intent != null) {
7007                    if (intent.hasFileDescriptors()) {
7008                        throw new IllegalArgumentException("File descriptors passed in Intent");
7009                    }
7010                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7011                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7012                        throw new IllegalArgumentException(
7013                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7014                    }
7015                    intents[i] = new Intent(intent);
7016                }
7017            }
7018            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7019                throw new IllegalArgumentException(
7020                        "Intent array length does not match resolvedTypes length");
7021            }
7022        }
7023        if (bOptions != null) {
7024            if (bOptions.hasFileDescriptors()) {
7025                throw new IllegalArgumentException("File descriptors passed in options");
7026            }
7027        }
7028
7029        synchronized(this) {
7030            int callingUid = Binder.getCallingUid();
7031            int origUserId = userId;
7032            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7033                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7034                    ALLOW_NON_FULL, "getIntentSender", null);
7035            if (origUserId == UserHandle.USER_CURRENT) {
7036                // We don't want to evaluate this until the pending intent is
7037                // actually executed.  However, we do want to always do the
7038                // security checking for it above.
7039                userId = UserHandle.USER_CURRENT;
7040            }
7041            try {
7042                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7043                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7044                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7045                    if (!UserHandle.isSameApp(callingUid, uid)) {
7046                        String msg = "Permission Denial: getIntentSender() from pid="
7047                            + Binder.getCallingPid()
7048                            + ", uid=" + Binder.getCallingUid()
7049                            + ", (need uid=" + uid + ")"
7050                            + " is not allowed to send as package " + packageName;
7051                        Slog.w(TAG, msg);
7052                        throw new SecurityException(msg);
7053                    }
7054                }
7055
7056                return getIntentSenderLocked(type, packageName, callingUid, userId,
7057                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7058
7059            } catch (RemoteException e) {
7060                throw new SecurityException(e);
7061            }
7062        }
7063    }
7064
7065    IIntentSender getIntentSenderLocked(int type, String packageName,
7066            int callingUid, int userId, IBinder token, String resultWho,
7067            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7068            Bundle bOptions) {
7069        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7070        ActivityRecord activity = null;
7071        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7072            activity = ActivityRecord.isInStackLocked(token);
7073            if (activity == null) {
7074                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7075                return null;
7076            }
7077            if (activity.finishing) {
7078                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7079                return null;
7080            }
7081        }
7082
7083        // We're going to be splicing together extras before sending, so we're
7084        // okay poking into any contained extras.
7085        if (intents != null) {
7086            for (int i = 0; i < intents.length; i++) {
7087                intents[i].setDefusable(true);
7088            }
7089        }
7090        Bundle.setDefusable(bOptions, true);
7091
7092        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7093        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7094        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7095        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7096                |PendingIntent.FLAG_UPDATE_CURRENT);
7097
7098        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7099                type, packageName, activity, resultWho,
7100                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7101        WeakReference<PendingIntentRecord> ref;
7102        ref = mIntentSenderRecords.get(key);
7103        PendingIntentRecord rec = ref != null ? ref.get() : null;
7104        if (rec != null) {
7105            if (!cancelCurrent) {
7106                if (updateCurrent) {
7107                    if (rec.key.requestIntent != null) {
7108                        rec.key.requestIntent.replaceExtras(intents != null ?
7109                                intents[intents.length - 1] : null);
7110                    }
7111                    if (intents != null) {
7112                        intents[intents.length-1] = rec.key.requestIntent;
7113                        rec.key.allIntents = intents;
7114                        rec.key.allResolvedTypes = resolvedTypes;
7115                    } else {
7116                        rec.key.allIntents = null;
7117                        rec.key.allResolvedTypes = null;
7118                    }
7119                }
7120                return rec;
7121            }
7122            rec.canceled = true;
7123            mIntentSenderRecords.remove(key);
7124        }
7125        if (noCreate) {
7126            return rec;
7127        }
7128        rec = new PendingIntentRecord(this, key, callingUid);
7129        mIntentSenderRecords.put(key, rec.ref);
7130        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7131            if (activity.pendingResults == null) {
7132                activity.pendingResults
7133                        = new HashSet<WeakReference<PendingIntentRecord>>();
7134            }
7135            activity.pendingResults.add(rec.ref);
7136        }
7137        return rec;
7138    }
7139
7140    @Override
7141    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7142            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7143        if (target instanceof PendingIntentRecord) {
7144            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7145                    finishedReceiver, requiredPermission, options);
7146        } else {
7147            if (intent == null) {
7148                // Weird case: someone has given us their own custom IIntentSender, and now
7149                // they have someone else trying to send to it but of course this isn't
7150                // really a PendingIntent, so there is no base Intent, and the caller isn't
7151                // supplying an Intent... but we never want to dispatch a null Intent to
7152                // a receiver, so um...  let's make something up.
7153                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7154                intent = new Intent(Intent.ACTION_MAIN);
7155            }
7156            try {
7157                target.send(code, intent, resolvedType, null, requiredPermission, options);
7158            } catch (RemoteException e) {
7159            }
7160            // Platform code can rely on getting a result back when the send is done, but if
7161            // this intent sender is from outside of the system we can't rely on it doing that.
7162            // So instead we don't give it the result receiver, and instead just directly
7163            // report the finish immediately.
7164            if (finishedReceiver != null) {
7165                try {
7166                    finishedReceiver.performReceive(intent, 0,
7167                            null, null, false, false, UserHandle.getCallingUserId());
7168                } catch (RemoteException e) {
7169                }
7170            }
7171            return 0;
7172        }
7173    }
7174
7175    /**
7176     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7177     *
7178     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7179     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7180     */
7181    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7182        if (DEBUG_WHITELISTS) {
7183            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7184                    + targetUid + ", " + duration + ")");
7185        }
7186        synchronized (mPidsSelfLocked) {
7187            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7188            if (pr == null) {
7189                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7190                return;
7191            }
7192            if (!pr.whitelistManager) {
7193                if (DEBUG_WHITELISTS) {
7194                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7195                            + callerPid + " is not allowed");
7196                }
7197                return;
7198            }
7199        }
7200
7201        final long token = Binder.clearCallingIdentity();
7202        try {
7203            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7204                    true, "pe from uid:" + callerUid);
7205        } finally {
7206            Binder.restoreCallingIdentity(token);
7207        }
7208    }
7209
7210    @Override
7211    public void cancelIntentSender(IIntentSender sender) {
7212        if (!(sender instanceof PendingIntentRecord)) {
7213            return;
7214        }
7215        synchronized(this) {
7216            PendingIntentRecord rec = (PendingIntentRecord)sender;
7217            try {
7218                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7219                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7220                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7221                    String msg = "Permission Denial: cancelIntentSender() from pid="
7222                        + Binder.getCallingPid()
7223                        + ", uid=" + Binder.getCallingUid()
7224                        + " is not allowed to cancel packges "
7225                        + rec.key.packageName;
7226                    Slog.w(TAG, msg);
7227                    throw new SecurityException(msg);
7228                }
7229            } catch (RemoteException e) {
7230                throw new SecurityException(e);
7231            }
7232            cancelIntentSenderLocked(rec, true);
7233        }
7234    }
7235
7236    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7237        rec.canceled = true;
7238        mIntentSenderRecords.remove(rec.key);
7239        if (cleanActivity && rec.key.activity != null) {
7240            rec.key.activity.pendingResults.remove(rec.ref);
7241        }
7242    }
7243
7244    @Override
7245    public String getPackageForIntentSender(IIntentSender pendingResult) {
7246        if (!(pendingResult instanceof PendingIntentRecord)) {
7247            return null;
7248        }
7249        try {
7250            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7251            return res.key.packageName;
7252        } catch (ClassCastException e) {
7253        }
7254        return null;
7255    }
7256
7257    @Override
7258    public int getUidForIntentSender(IIntentSender sender) {
7259        if (sender instanceof PendingIntentRecord) {
7260            try {
7261                PendingIntentRecord res = (PendingIntentRecord)sender;
7262                return res.uid;
7263            } catch (ClassCastException e) {
7264            }
7265        }
7266        return -1;
7267    }
7268
7269    @Override
7270    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7271        if (!(pendingResult instanceof PendingIntentRecord)) {
7272            return false;
7273        }
7274        try {
7275            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7276            if (res.key.allIntents == null) {
7277                return false;
7278            }
7279            for (int i=0; i<res.key.allIntents.length; i++) {
7280                Intent intent = res.key.allIntents[i];
7281                if (intent.getPackage() != null && intent.getComponent() != null) {
7282                    return false;
7283                }
7284            }
7285            return true;
7286        } catch (ClassCastException e) {
7287        }
7288        return false;
7289    }
7290
7291    @Override
7292    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7293        if (!(pendingResult instanceof PendingIntentRecord)) {
7294            return false;
7295        }
7296        try {
7297            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7298            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7299                return true;
7300            }
7301            return false;
7302        } catch (ClassCastException e) {
7303        }
7304        return false;
7305    }
7306
7307    @Override
7308    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7309        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7310                "getIntentForIntentSender()");
7311        if (!(pendingResult instanceof PendingIntentRecord)) {
7312            return null;
7313        }
7314        try {
7315            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7316            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7317        } catch (ClassCastException e) {
7318        }
7319        return null;
7320    }
7321
7322    @Override
7323    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7324        if (!(pendingResult instanceof PendingIntentRecord)) {
7325            return null;
7326        }
7327        try {
7328            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7329            synchronized (this) {
7330                return getTagForIntentSenderLocked(res, prefix);
7331            }
7332        } catch (ClassCastException e) {
7333        }
7334        return null;
7335    }
7336
7337    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7338        final Intent intent = res.key.requestIntent;
7339        if (intent != null) {
7340            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7341                    || res.lastTagPrefix.equals(prefix))) {
7342                return res.lastTag;
7343            }
7344            res.lastTagPrefix = prefix;
7345            final StringBuilder sb = new StringBuilder(128);
7346            if (prefix != null) {
7347                sb.append(prefix);
7348            }
7349            if (intent.getAction() != null) {
7350                sb.append(intent.getAction());
7351            } else if (intent.getComponent() != null) {
7352                intent.getComponent().appendShortString(sb);
7353            } else {
7354                sb.append("?");
7355            }
7356            return res.lastTag = sb.toString();
7357        }
7358        return null;
7359    }
7360
7361    @Override
7362    public void setProcessLimit(int max) {
7363        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7364                "setProcessLimit()");
7365        synchronized (this) {
7366            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7367            mProcessLimitOverride = max;
7368        }
7369        trimApplications();
7370    }
7371
7372    @Override
7373    public int getProcessLimit() {
7374        synchronized (this) {
7375            return mProcessLimitOverride;
7376        }
7377    }
7378
7379    void foregroundTokenDied(ForegroundToken token) {
7380        synchronized (ActivityManagerService.this) {
7381            synchronized (mPidsSelfLocked) {
7382                ForegroundToken cur
7383                    = mForegroundProcesses.get(token.pid);
7384                if (cur != token) {
7385                    return;
7386                }
7387                mForegroundProcesses.remove(token.pid);
7388                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7389                if (pr == null) {
7390                    return;
7391                }
7392                pr.forcingToForeground = null;
7393                updateProcessForegroundLocked(pr, false, false);
7394            }
7395            updateOomAdjLocked();
7396        }
7397    }
7398
7399    @Override
7400    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7401        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7402                "setProcessForeground()");
7403        synchronized(this) {
7404            boolean changed = false;
7405
7406            synchronized (mPidsSelfLocked) {
7407                ProcessRecord pr = mPidsSelfLocked.get(pid);
7408                if (pr == null && isForeground) {
7409                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7410                    return;
7411                }
7412                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7413                if (oldToken != null) {
7414                    oldToken.token.unlinkToDeath(oldToken, 0);
7415                    mForegroundProcesses.remove(pid);
7416                    if (pr != null) {
7417                        pr.forcingToForeground = null;
7418                    }
7419                    changed = true;
7420                }
7421                if (isForeground && token != null) {
7422                    ForegroundToken newToken = new ForegroundToken() {
7423                        @Override
7424                        public void binderDied() {
7425                            foregroundTokenDied(this);
7426                        }
7427                    };
7428                    newToken.pid = pid;
7429                    newToken.token = token;
7430                    try {
7431                        token.linkToDeath(newToken, 0);
7432                        mForegroundProcesses.put(pid, newToken);
7433                        pr.forcingToForeground = token;
7434                        changed = true;
7435                    } catch (RemoteException e) {
7436                        // If the process died while doing this, we will later
7437                        // do the cleanup with the process death link.
7438                    }
7439                }
7440            }
7441
7442            if (changed) {
7443                updateOomAdjLocked();
7444            }
7445        }
7446    }
7447
7448    @Override
7449    public boolean isAppForeground(int uid) throws RemoteException {
7450        synchronized (this) {
7451            UidRecord uidRec = mActiveUids.get(uid);
7452            if (uidRec == null || uidRec.idle) {
7453                return false;
7454            }
7455            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7456        }
7457    }
7458
7459    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7460    // be guarded by permission checking.
7461    int getUidState(int uid) {
7462        synchronized (this) {
7463            UidRecord uidRec = mActiveUids.get(uid);
7464            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7465        }
7466    }
7467
7468    @Override
7469    public boolean isInMultiWindowMode(IBinder token) {
7470        final long origId = Binder.clearCallingIdentity();
7471        try {
7472            synchronized(this) {
7473                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7474                if (r == null) {
7475                    return false;
7476                }
7477                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7478                return !r.task.mFullscreen;
7479            }
7480        } finally {
7481            Binder.restoreCallingIdentity(origId);
7482        }
7483    }
7484
7485    @Override
7486    public boolean isInPictureInPictureMode(IBinder token) {
7487        final long origId = Binder.clearCallingIdentity();
7488        try {
7489            synchronized(this) {
7490                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7491                if (stack == null) {
7492                    return false;
7493                }
7494                return stack.mStackId == PINNED_STACK_ID;
7495            }
7496        } finally {
7497            Binder.restoreCallingIdentity(origId);
7498        }
7499    }
7500
7501    @Override
7502    public void enterPictureInPictureMode(IBinder token) {
7503        final long origId = Binder.clearCallingIdentity();
7504        try {
7505            synchronized(this) {
7506                if (!mSupportsPictureInPicture) {
7507                    throw new IllegalStateException("enterPictureInPictureMode: "
7508                            + "Device doesn't support picture-in-picture mode.");
7509                }
7510
7511                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7512
7513                if (r == null) {
7514                    throw new IllegalStateException("enterPictureInPictureMode: "
7515                            + "Can't find activity for token=" + token);
7516                }
7517
7518                if (!r.supportsPictureInPicture()) {
7519                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7520                            + "Picture-In-Picture not supported for r=" + r);
7521                }
7522
7523                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7524                // current bounds.
7525                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7526                final Rect bounds = (pinnedStack != null)
7527                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7528
7529                mStackSupervisor.moveActivityToPinnedStackLocked(
7530                        r, "enterPictureInPictureMode", bounds);
7531            }
7532        } finally {
7533            Binder.restoreCallingIdentity(origId);
7534        }
7535    }
7536
7537    // =========================================================
7538    // PROCESS INFO
7539    // =========================================================
7540
7541    static class ProcessInfoService extends IProcessInfoService.Stub {
7542        final ActivityManagerService mActivityManagerService;
7543        ProcessInfoService(ActivityManagerService activityManagerService) {
7544            mActivityManagerService = activityManagerService;
7545        }
7546
7547        @Override
7548        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7549            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7550                    /*in*/ pids, /*out*/ states, null);
7551        }
7552
7553        @Override
7554        public void getProcessStatesAndOomScoresFromPids(
7555                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7556            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7557                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7558        }
7559    }
7560
7561    /**
7562     * For each PID in the given input array, write the current process state
7563     * for that process into the states array, or -1 to indicate that no
7564     * process with the given PID exists. If scores array is provided, write
7565     * the oom score for the process into the scores array, with INVALID_ADJ
7566     * indicating the PID doesn't exist.
7567     */
7568    public void getProcessStatesAndOomScoresForPIDs(
7569            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7570        if (scores != null) {
7571            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7572                    "getProcessStatesAndOomScoresForPIDs()");
7573        }
7574
7575        if (pids == null) {
7576            throw new NullPointerException("pids");
7577        } else if (states == null) {
7578            throw new NullPointerException("states");
7579        } else if (pids.length != states.length) {
7580            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7581        } else if (scores != null && pids.length != scores.length) {
7582            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7583        }
7584
7585        synchronized (mPidsSelfLocked) {
7586            for (int i = 0; i < pids.length; i++) {
7587                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7588                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7589                        pr.curProcState;
7590                if (scores != null) {
7591                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7592                }
7593            }
7594        }
7595    }
7596
7597    // =========================================================
7598    // PERMISSIONS
7599    // =========================================================
7600
7601    static class PermissionController extends IPermissionController.Stub {
7602        ActivityManagerService mActivityManagerService;
7603        PermissionController(ActivityManagerService activityManagerService) {
7604            mActivityManagerService = activityManagerService;
7605        }
7606
7607        @Override
7608        public boolean checkPermission(String permission, int pid, int uid) {
7609            return mActivityManagerService.checkPermission(permission, pid,
7610                    uid) == PackageManager.PERMISSION_GRANTED;
7611        }
7612
7613        @Override
7614        public String[] getPackagesForUid(int uid) {
7615            return mActivityManagerService.mContext.getPackageManager()
7616                    .getPackagesForUid(uid);
7617        }
7618
7619        @Override
7620        public boolean isRuntimePermission(String permission) {
7621            try {
7622                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7623                        .getPermissionInfo(permission, 0);
7624                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7625            } catch (NameNotFoundException nnfe) {
7626                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7627            }
7628            return false;
7629        }
7630    }
7631
7632    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7633        @Override
7634        public int checkComponentPermission(String permission, int pid, int uid,
7635                int owningUid, boolean exported) {
7636            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7637                    owningUid, exported);
7638        }
7639
7640        @Override
7641        public Object getAMSLock() {
7642            return ActivityManagerService.this;
7643        }
7644    }
7645
7646    /**
7647     * This can be called with or without the global lock held.
7648     */
7649    int checkComponentPermission(String permission, int pid, int uid,
7650            int owningUid, boolean exported) {
7651        if (pid == MY_PID) {
7652            return PackageManager.PERMISSION_GRANTED;
7653        }
7654        return ActivityManager.checkComponentPermission(permission, uid,
7655                owningUid, exported);
7656    }
7657
7658    /**
7659     * As the only public entry point for permissions checking, this method
7660     * can enforce the semantic that requesting a check on a null global
7661     * permission is automatically denied.  (Internally a null permission
7662     * string is used when calling {@link #checkComponentPermission} in cases
7663     * when only uid-based security is needed.)
7664     *
7665     * This can be called with or without the global lock held.
7666     */
7667    @Override
7668    public int checkPermission(String permission, int pid, int uid) {
7669        if (permission == null) {
7670            return PackageManager.PERMISSION_DENIED;
7671        }
7672        return checkComponentPermission(permission, pid, uid, -1, true);
7673    }
7674
7675    @Override
7676    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7677        if (permission == null) {
7678            return PackageManager.PERMISSION_DENIED;
7679        }
7680
7681        // We might be performing an operation on behalf of an indirect binder
7682        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7683        // client identity accordingly before proceeding.
7684        Identity tlsIdentity = sCallerIdentity.get();
7685        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7686            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7687                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7688            uid = tlsIdentity.uid;
7689            pid = tlsIdentity.pid;
7690        }
7691
7692        return checkComponentPermission(permission, pid, uid, -1, true);
7693    }
7694
7695    /**
7696     * Binder IPC calls go through the public entry point.
7697     * This can be called with or without the global lock held.
7698     */
7699    int checkCallingPermission(String permission) {
7700        return checkPermission(permission,
7701                Binder.getCallingPid(),
7702                UserHandle.getAppId(Binder.getCallingUid()));
7703    }
7704
7705    /**
7706     * This can be called with or without the global lock held.
7707     */
7708    void enforceCallingPermission(String permission, String func) {
7709        if (checkCallingPermission(permission)
7710                == PackageManager.PERMISSION_GRANTED) {
7711            return;
7712        }
7713
7714        String msg = "Permission Denial: " + func + " from pid="
7715                + Binder.getCallingPid()
7716                + ", uid=" + Binder.getCallingUid()
7717                + " requires " + permission;
7718        Slog.w(TAG, msg);
7719        throw new SecurityException(msg);
7720    }
7721
7722    /**
7723     * Determine if UID is holding permissions required to access {@link Uri} in
7724     * the given {@link ProviderInfo}. Final permission checking is always done
7725     * in {@link ContentProvider}.
7726     */
7727    private final boolean checkHoldingPermissionsLocked(
7728            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7729        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7730                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7731        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7732            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7733                    != PERMISSION_GRANTED) {
7734                return false;
7735            }
7736        }
7737        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7738    }
7739
7740    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7741            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7742        if (pi.applicationInfo.uid == uid) {
7743            return true;
7744        } else if (!pi.exported) {
7745            return false;
7746        }
7747
7748        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7749        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7750        try {
7751            // check if target holds top-level <provider> permissions
7752            if (!readMet && pi.readPermission != null && considerUidPermissions
7753                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7754                readMet = true;
7755            }
7756            if (!writeMet && pi.writePermission != null && considerUidPermissions
7757                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7758                writeMet = true;
7759            }
7760
7761            // track if unprotected read/write is allowed; any denied
7762            // <path-permission> below removes this ability
7763            boolean allowDefaultRead = pi.readPermission == null;
7764            boolean allowDefaultWrite = pi.writePermission == null;
7765
7766            // check if target holds any <path-permission> that match uri
7767            final PathPermission[] pps = pi.pathPermissions;
7768            if (pps != null) {
7769                final String path = grantUri.uri.getPath();
7770                int i = pps.length;
7771                while (i > 0 && (!readMet || !writeMet)) {
7772                    i--;
7773                    PathPermission pp = pps[i];
7774                    if (pp.match(path)) {
7775                        if (!readMet) {
7776                            final String pprperm = pp.getReadPermission();
7777                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7778                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7779                                    + ": match=" + pp.match(path)
7780                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7781                            if (pprperm != null) {
7782                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7783                                        == PERMISSION_GRANTED) {
7784                                    readMet = true;
7785                                } else {
7786                                    allowDefaultRead = false;
7787                                }
7788                            }
7789                        }
7790                        if (!writeMet) {
7791                            final String ppwperm = pp.getWritePermission();
7792                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7793                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7794                                    + ": match=" + pp.match(path)
7795                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7796                            if (ppwperm != null) {
7797                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7798                                        == PERMISSION_GRANTED) {
7799                                    writeMet = true;
7800                                } else {
7801                                    allowDefaultWrite = false;
7802                                }
7803                            }
7804                        }
7805                    }
7806                }
7807            }
7808
7809            // grant unprotected <provider> read/write, if not blocked by
7810            // <path-permission> above
7811            if (allowDefaultRead) readMet = true;
7812            if (allowDefaultWrite) writeMet = true;
7813
7814        } catch (RemoteException e) {
7815            return false;
7816        }
7817
7818        return readMet && writeMet;
7819    }
7820
7821    public int getAppStartMode(int uid, String packageName) {
7822        synchronized (this) {
7823            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7824        }
7825    }
7826
7827    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7828            boolean allowWhenForeground) {
7829        UidRecord uidRec = mActiveUids.get(uid);
7830        if (!mLenientBackgroundCheck) {
7831            if (!allowWhenForeground || uidRec == null
7832                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7833                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7834                        packageName) != AppOpsManager.MODE_ALLOWED) {
7835                    return ActivityManager.APP_START_MODE_DELAYED;
7836                }
7837            }
7838
7839        } else if (uidRec == null || uidRec.idle) {
7840            if (callingPid >= 0) {
7841                ProcessRecord proc;
7842                synchronized (mPidsSelfLocked) {
7843                    proc = mPidsSelfLocked.get(callingPid);
7844                }
7845                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7846                    // Whoever is instigating this is in the foreground, so we will allow it
7847                    // to go through.
7848                    return ActivityManager.APP_START_MODE_NORMAL;
7849                }
7850            }
7851            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7852                    != AppOpsManager.MODE_ALLOWED) {
7853                return ActivityManager.APP_START_MODE_DELAYED;
7854            }
7855        }
7856        return ActivityManager.APP_START_MODE_NORMAL;
7857    }
7858
7859    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7860        ProviderInfo pi = null;
7861        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7862        if (cpr != null) {
7863            pi = cpr.info;
7864        } else {
7865            try {
7866                pi = AppGlobals.getPackageManager().resolveContentProvider(
7867                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7868                        userHandle);
7869            } catch (RemoteException ex) {
7870            }
7871        }
7872        return pi;
7873    }
7874
7875    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7876        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7877        if (targetUris != null) {
7878            return targetUris.get(grantUri);
7879        }
7880        return null;
7881    }
7882
7883    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7884            String targetPkg, int targetUid, GrantUri grantUri) {
7885        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7886        if (targetUris == null) {
7887            targetUris = Maps.newArrayMap();
7888            mGrantedUriPermissions.put(targetUid, targetUris);
7889        }
7890
7891        UriPermission perm = targetUris.get(grantUri);
7892        if (perm == null) {
7893            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7894            targetUris.put(grantUri, perm);
7895        }
7896
7897        return perm;
7898    }
7899
7900    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7901            final int modeFlags) {
7902        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7903        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7904                : UriPermission.STRENGTH_OWNED;
7905
7906        // Root gets to do everything.
7907        if (uid == 0) {
7908            return true;
7909        }
7910
7911        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7912        if (perms == null) return false;
7913
7914        // First look for exact match
7915        final UriPermission exactPerm = perms.get(grantUri);
7916        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7917            return true;
7918        }
7919
7920        // No exact match, look for prefixes
7921        final int N = perms.size();
7922        for (int i = 0; i < N; i++) {
7923            final UriPermission perm = perms.valueAt(i);
7924            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7925                    && perm.getStrength(modeFlags) >= minStrength) {
7926                return true;
7927            }
7928        }
7929
7930        return false;
7931    }
7932
7933    /**
7934     * @param uri This uri must NOT contain an embedded userId.
7935     * @param userId The userId in which the uri is to be resolved.
7936     */
7937    @Override
7938    public int checkUriPermission(Uri uri, int pid, int uid,
7939            final int modeFlags, int userId, IBinder callerToken) {
7940        enforceNotIsolatedCaller("checkUriPermission");
7941
7942        // Another redirected-binder-call permissions check as in
7943        // {@link checkPermissionWithToken}.
7944        Identity tlsIdentity = sCallerIdentity.get();
7945        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7946            uid = tlsIdentity.uid;
7947            pid = tlsIdentity.pid;
7948        }
7949
7950        // Our own process gets to do everything.
7951        if (pid == MY_PID) {
7952            return PackageManager.PERMISSION_GRANTED;
7953        }
7954        synchronized (this) {
7955            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7956                    ? PackageManager.PERMISSION_GRANTED
7957                    : PackageManager.PERMISSION_DENIED;
7958        }
7959    }
7960
7961    /**
7962     * Check if the targetPkg can be granted permission to access uri by
7963     * the callingUid using the given modeFlags.  Throws a security exception
7964     * if callingUid is not allowed to do this.  Returns the uid of the target
7965     * if the URI permission grant should be performed; returns -1 if it is not
7966     * needed (for example targetPkg already has permission to access the URI).
7967     * If you already know the uid of the target, you can supply it in
7968     * lastTargetUid else set that to -1.
7969     */
7970    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7971            final int modeFlags, int lastTargetUid) {
7972        if (!Intent.isAccessUriMode(modeFlags)) {
7973            return -1;
7974        }
7975
7976        if (targetPkg != null) {
7977            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7978                    "Checking grant " + targetPkg + " permission to " + grantUri);
7979        }
7980
7981        final IPackageManager pm = AppGlobals.getPackageManager();
7982
7983        // If this is not a content: uri, we can't do anything with it.
7984        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7985            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7986                    "Can't grant URI permission for non-content URI: " + grantUri);
7987            return -1;
7988        }
7989
7990        final String authority = grantUri.uri.getAuthority();
7991        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7992                MATCH_DEBUG_TRIAGED_MISSING);
7993        if (pi == null) {
7994            Slog.w(TAG, "No content provider found for permission check: " +
7995                    grantUri.uri.toSafeString());
7996            return -1;
7997        }
7998
7999        int targetUid = lastTargetUid;
8000        if (targetUid < 0 && targetPkg != null) {
8001            try {
8002                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8003                        UserHandle.getUserId(callingUid));
8004                if (targetUid < 0) {
8005                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8006                            "Can't grant URI permission no uid for: " + targetPkg);
8007                    return -1;
8008                }
8009            } catch (RemoteException ex) {
8010                return -1;
8011            }
8012        }
8013
8014        if (targetUid >= 0) {
8015            // First...  does the target actually need this permission?
8016            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8017                // No need to grant the target this permission.
8018                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8019                        "Target " + targetPkg + " already has full permission to " + grantUri);
8020                return -1;
8021            }
8022        } else {
8023            // First...  there is no target package, so can anyone access it?
8024            boolean allowed = pi.exported;
8025            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8026                if (pi.readPermission != null) {
8027                    allowed = false;
8028                }
8029            }
8030            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8031                if (pi.writePermission != null) {
8032                    allowed = false;
8033                }
8034            }
8035            if (allowed) {
8036                return -1;
8037            }
8038        }
8039
8040        /* There is a special cross user grant if:
8041         * - The target is on another user.
8042         * - Apps on the current user can access the uri without any uid permissions.
8043         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8044         * grant uri permissions.
8045         */
8046        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8047                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8048                modeFlags, false /*without considering the uid permissions*/);
8049
8050        // Second...  is the provider allowing granting of URI permissions?
8051        if (!specialCrossUserGrant) {
8052            if (!pi.grantUriPermissions) {
8053                throw new SecurityException("Provider " + pi.packageName
8054                        + "/" + pi.name
8055                        + " does not allow granting of Uri permissions (uri "
8056                        + grantUri + ")");
8057            }
8058            if (pi.uriPermissionPatterns != null) {
8059                final int N = pi.uriPermissionPatterns.length;
8060                boolean allowed = false;
8061                for (int i=0; i<N; i++) {
8062                    if (pi.uriPermissionPatterns[i] != null
8063                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8064                        allowed = true;
8065                        break;
8066                    }
8067                }
8068                if (!allowed) {
8069                    throw new SecurityException("Provider " + pi.packageName
8070                            + "/" + pi.name
8071                            + " does not allow granting of permission to path of Uri "
8072                            + grantUri);
8073                }
8074            }
8075        }
8076
8077        // Third...  does the caller itself have permission to access
8078        // this uri?
8079        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8080            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8081                // Require they hold a strong enough Uri permission
8082                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8083                    throw new SecurityException("Uid " + callingUid
8084                            + " does not have permission to uri " + grantUri);
8085                }
8086            }
8087        }
8088        return targetUid;
8089    }
8090
8091    /**
8092     * @param uri This uri must NOT contain an embedded userId.
8093     * @param userId The userId in which the uri is to be resolved.
8094     */
8095    @Override
8096    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8097            final int modeFlags, int userId) {
8098        enforceNotIsolatedCaller("checkGrantUriPermission");
8099        synchronized(this) {
8100            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8101                    new GrantUri(userId, uri, false), modeFlags, -1);
8102        }
8103    }
8104
8105    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8106            final int modeFlags, UriPermissionOwner owner) {
8107        if (!Intent.isAccessUriMode(modeFlags)) {
8108            return;
8109        }
8110
8111        // So here we are: the caller has the assumed permission
8112        // to the uri, and the target doesn't.  Let's now give this to
8113        // the target.
8114
8115        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8116                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8117
8118        final String authority = grantUri.uri.getAuthority();
8119        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8120                MATCH_DEBUG_TRIAGED_MISSING);
8121        if (pi == null) {
8122            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8123            return;
8124        }
8125
8126        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8127            grantUri.prefix = true;
8128        }
8129        final UriPermission perm = findOrCreateUriPermissionLocked(
8130                pi.packageName, targetPkg, targetUid, grantUri);
8131        perm.grantModes(modeFlags, owner);
8132    }
8133
8134    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8135            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8136        if (targetPkg == null) {
8137            throw new NullPointerException("targetPkg");
8138        }
8139        int targetUid;
8140        final IPackageManager pm = AppGlobals.getPackageManager();
8141        try {
8142            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8143        } catch (RemoteException ex) {
8144            return;
8145        }
8146
8147        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8148                targetUid);
8149        if (targetUid < 0) {
8150            return;
8151        }
8152
8153        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8154                owner);
8155    }
8156
8157    static class NeededUriGrants extends ArrayList<GrantUri> {
8158        final String targetPkg;
8159        final int targetUid;
8160        final int flags;
8161
8162        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8163            this.targetPkg = targetPkg;
8164            this.targetUid = targetUid;
8165            this.flags = flags;
8166        }
8167    }
8168
8169    /**
8170     * Like checkGrantUriPermissionLocked, but takes an Intent.
8171     */
8172    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8173            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8174        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8175                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8176                + " clip=" + (intent != null ? intent.getClipData() : null)
8177                + " from " + intent + "; flags=0x"
8178                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8179
8180        if (targetPkg == null) {
8181            throw new NullPointerException("targetPkg");
8182        }
8183
8184        if (intent == null) {
8185            return null;
8186        }
8187        Uri data = intent.getData();
8188        ClipData clip = intent.getClipData();
8189        if (data == null && clip == null) {
8190            return null;
8191        }
8192        // Default userId for uris in the intent (if they don't specify it themselves)
8193        int contentUserHint = intent.getContentUserHint();
8194        if (contentUserHint == UserHandle.USER_CURRENT) {
8195            contentUserHint = UserHandle.getUserId(callingUid);
8196        }
8197        final IPackageManager pm = AppGlobals.getPackageManager();
8198        int targetUid;
8199        if (needed != null) {
8200            targetUid = needed.targetUid;
8201        } else {
8202            try {
8203                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8204                        targetUserId);
8205            } catch (RemoteException ex) {
8206                return null;
8207            }
8208            if (targetUid < 0) {
8209                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8210                        "Can't grant URI permission no uid for: " + targetPkg
8211                        + " on user " + targetUserId);
8212                return null;
8213            }
8214        }
8215        if (data != null) {
8216            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8217            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8218                    targetUid);
8219            if (targetUid > 0) {
8220                if (needed == null) {
8221                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8222                }
8223                needed.add(grantUri);
8224            }
8225        }
8226        if (clip != null) {
8227            for (int i=0; i<clip.getItemCount(); i++) {
8228                Uri uri = clip.getItemAt(i).getUri();
8229                if (uri != null) {
8230                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8231                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8232                            targetUid);
8233                    if (targetUid > 0) {
8234                        if (needed == null) {
8235                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8236                        }
8237                        needed.add(grantUri);
8238                    }
8239                } else {
8240                    Intent clipIntent = clip.getItemAt(i).getIntent();
8241                    if (clipIntent != null) {
8242                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8243                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8244                        if (newNeeded != null) {
8245                            needed = newNeeded;
8246                        }
8247                    }
8248                }
8249            }
8250        }
8251
8252        return needed;
8253    }
8254
8255    /**
8256     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8257     */
8258    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8259            UriPermissionOwner owner) {
8260        if (needed != null) {
8261            for (int i=0; i<needed.size(); i++) {
8262                GrantUri grantUri = needed.get(i);
8263                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8264                        grantUri, needed.flags, owner);
8265            }
8266        }
8267    }
8268
8269    void grantUriPermissionFromIntentLocked(int callingUid,
8270            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8271        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8272                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8273        if (needed == null) {
8274            return;
8275        }
8276
8277        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8278    }
8279
8280    /**
8281     * @param uri This uri must NOT contain an embedded userId.
8282     * @param userId The userId in which the uri is to be resolved.
8283     */
8284    @Override
8285    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8286            final int modeFlags, int userId) {
8287        enforceNotIsolatedCaller("grantUriPermission");
8288        GrantUri grantUri = new GrantUri(userId, uri, false);
8289        synchronized(this) {
8290            final ProcessRecord r = getRecordForAppLocked(caller);
8291            if (r == null) {
8292                throw new SecurityException("Unable to find app for caller "
8293                        + caller
8294                        + " when granting permission to uri " + grantUri);
8295            }
8296            if (targetPkg == null) {
8297                throw new IllegalArgumentException("null target");
8298            }
8299            if (grantUri == null) {
8300                throw new IllegalArgumentException("null uri");
8301            }
8302
8303            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8304                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8305                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8306                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8307
8308            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8309                    UserHandle.getUserId(r.uid));
8310        }
8311    }
8312
8313    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8314        if (perm.modeFlags == 0) {
8315            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8316                    perm.targetUid);
8317            if (perms != null) {
8318                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8319                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8320
8321                perms.remove(perm.uri);
8322                if (perms.isEmpty()) {
8323                    mGrantedUriPermissions.remove(perm.targetUid);
8324                }
8325            }
8326        }
8327    }
8328
8329    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8330        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8331                "Revoking all granted permissions to " + grantUri);
8332
8333        final IPackageManager pm = AppGlobals.getPackageManager();
8334        final String authority = grantUri.uri.getAuthority();
8335        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8336                MATCH_DEBUG_TRIAGED_MISSING);
8337        if (pi == null) {
8338            Slog.w(TAG, "No content provider found for permission revoke: "
8339                    + grantUri.toSafeString());
8340            return;
8341        }
8342
8343        // Does the caller have this permission on the URI?
8344        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8345            // If they don't have direct access to the URI, then revoke any
8346            // ownerless URI permissions that have been granted to them.
8347            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8348            if (perms != null) {
8349                boolean persistChanged = false;
8350                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8351                    final UriPermission perm = it.next();
8352                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8353                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8354                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8355                                "Revoking non-owned " + perm.targetUid
8356                                + " permission to " + perm.uri);
8357                        persistChanged |= perm.revokeModes(
8358                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8359                        if (perm.modeFlags == 0) {
8360                            it.remove();
8361                        }
8362                    }
8363                }
8364                if (perms.isEmpty()) {
8365                    mGrantedUriPermissions.remove(callingUid);
8366                }
8367                if (persistChanged) {
8368                    schedulePersistUriGrants();
8369                }
8370            }
8371            return;
8372        }
8373
8374        boolean persistChanged = false;
8375
8376        // Go through all of the permissions and remove any that match.
8377        int N = mGrantedUriPermissions.size();
8378        for (int i = 0; i < N; i++) {
8379            final int targetUid = mGrantedUriPermissions.keyAt(i);
8380            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8381
8382            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8383                final UriPermission perm = it.next();
8384                if (perm.uri.sourceUserId == grantUri.sourceUserId
8385                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8386                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8387                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8388                    persistChanged |= perm.revokeModes(
8389                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8390                    if (perm.modeFlags == 0) {
8391                        it.remove();
8392                    }
8393                }
8394            }
8395
8396            if (perms.isEmpty()) {
8397                mGrantedUriPermissions.remove(targetUid);
8398                N--;
8399                i--;
8400            }
8401        }
8402
8403        if (persistChanged) {
8404            schedulePersistUriGrants();
8405        }
8406    }
8407
8408    /**
8409     * @param uri This uri must NOT contain an embedded userId.
8410     * @param userId The userId in which the uri is to be resolved.
8411     */
8412    @Override
8413    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8414            int userId) {
8415        enforceNotIsolatedCaller("revokeUriPermission");
8416        synchronized(this) {
8417            final ProcessRecord r = getRecordForAppLocked(caller);
8418            if (r == null) {
8419                throw new SecurityException("Unable to find app for caller "
8420                        + caller
8421                        + " when revoking permission to uri " + uri);
8422            }
8423            if (uri == null) {
8424                Slog.w(TAG, "revokeUriPermission: null uri");
8425                return;
8426            }
8427
8428            if (!Intent.isAccessUriMode(modeFlags)) {
8429                return;
8430            }
8431
8432            final String authority = uri.getAuthority();
8433            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8434                    MATCH_DEBUG_TRIAGED_MISSING);
8435            if (pi == null) {
8436                Slog.w(TAG, "No content provider found for permission revoke: "
8437                        + uri.toSafeString());
8438                return;
8439            }
8440
8441            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8442        }
8443    }
8444
8445    /**
8446     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8447     * given package.
8448     *
8449     * @param packageName Package name to match, or {@code null} to apply to all
8450     *            packages.
8451     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8452     *            to all users.
8453     * @param persistable If persistable grants should be removed.
8454     */
8455    private void removeUriPermissionsForPackageLocked(
8456            String packageName, int userHandle, boolean persistable) {
8457        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8458            throw new IllegalArgumentException("Must narrow by either package or user");
8459        }
8460
8461        boolean persistChanged = false;
8462
8463        int N = mGrantedUriPermissions.size();
8464        for (int i = 0; i < N; i++) {
8465            final int targetUid = mGrantedUriPermissions.keyAt(i);
8466            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8467
8468            // Only inspect grants matching user
8469            if (userHandle == UserHandle.USER_ALL
8470                    || userHandle == UserHandle.getUserId(targetUid)) {
8471                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8472                    final UriPermission perm = it.next();
8473
8474                    // Only inspect grants matching package
8475                    if (packageName == null || perm.sourcePkg.equals(packageName)
8476                            || perm.targetPkg.equals(packageName)) {
8477                        persistChanged |= perm.revokeModes(persistable
8478                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8479
8480                        // Only remove when no modes remain; any persisted grants
8481                        // will keep this alive.
8482                        if (perm.modeFlags == 0) {
8483                            it.remove();
8484                        }
8485                    }
8486                }
8487
8488                if (perms.isEmpty()) {
8489                    mGrantedUriPermissions.remove(targetUid);
8490                    N--;
8491                    i--;
8492                }
8493            }
8494        }
8495
8496        if (persistChanged) {
8497            schedulePersistUriGrants();
8498        }
8499    }
8500
8501    @Override
8502    public IBinder newUriPermissionOwner(String name) {
8503        enforceNotIsolatedCaller("newUriPermissionOwner");
8504        synchronized(this) {
8505            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8506            return owner.getExternalTokenLocked();
8507        }
8508    }
8509
8510    @Override
8511    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8512        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8513        synchronized(this) {
8514            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8515            if (r == null) {
8516                throw new IllegalArgumentException("Activity does not exist; token="
8517                        + activityToken);
8518            }
8519            return r.getUriPermissionsLocked().getExternalTokenLocked();
8520        }
8521    }
8522    /**
8523     * @param uri This uri must NOT contain an embedded userId.
8524     * @param sourceUserId The userId in which the uri is to be resolved.
8525     * @param targetUserId The userId of the app that receives the grant.
8526     */
8527    @Override
8528    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8529            final int modeFlags, int sourceUserId, int targetUserId) {
8530        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8531                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8532                "grantUriPermissionFromOwner", null);
8533        synchronized(this) {
8534            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8535            if (owner == null) {
8536                throw new IllegalArgumentException("Unknown owner: " + token);
8537            }
8538            if (fromUid != Binder.getCallingUid()) {
8539                if (Binder.getCallingUid() != Process.myUid()) {
8540                    // Only system code can grant URI permissions on behalf
8541                    // of other users.
8542                    throw new SecurityException("nice try");
8543                }
8544            }
8545            if (targetPkg == null) {
8546                throw new IllegalArgumentException("null target");
8547            }
8548            if (uri == null) {
8549                throw new IllegalArgumentException("null uri");
8550            }
8551
8552            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8553                    modeFlags, owner, targetUserId);
8554        }
8555    }
8556
8557    /**
8558     * @param uri This uri must NOT contain an embedded userId.
8559     * @param userId The userId in which the uri is to be resolved.
8560     */
8561    @Override
8562    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8563        synchronized(this) {
8564            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8565            if (owner == null) {
8566                throw new IllegalArgumentException("Unknown owner: " + token);
8567            }
8568
8569            if (uri == null) {
8570                owner.removeUriPermissionsLocked(mode);
8571            } else {
8572                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8573            }
8574        }
8575    }
8576
8577    private void schedulePersistUriGrants() {
8578        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8579            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8580                    10 * DateUtils.SECOND_IN_MILLIS);
8581        }
8582    }
8583
8584    private void writeGrantedUriPermissions() {
8585        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8586
8587        // Snapshot permissions so we can persist without lock
8588        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8589        synchronized (this) {
8590            final int size = mGrantedUriPermissions.size();
8591            for (int i = 0; i < size; i++) {
8592                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8593                for (UriPermission perm : perms.values()) {
8594                    if (perm.persistedModeFlags != 0) {
8595                        persist.add(perm.snapshot());
8596                    }
8597                }
8598            }
8599        }
8600
8601        FileOutputStream fos = null;
8602        try {
8603            fos = mGrantFile.startWrite();
8604
8605            XmlSerializer out = new FastXmlSerializer();
8606            out.setOutput(fos, StandardCharsets.UTF_8.name());
8607            out.startDocument(null, true);
8608            out.startTag(null, TAG_URI_GRANTS);
8609            for (UriPermission.Snapshot perm : persist) {
8610                out.startTag(null, TAG_URI_GRANT);
8611                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8612                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8613                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8614                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8615                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8616                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8617                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8618                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8619                out.endTag(null, TAG_URI_GRANT);
8620            }
8621            out.endTag(null, TAG_URI_GRANTS);
8622            out.endDocument();
8623
8624            mGrantFile.finishWrite(fos);
8625        } catch (IOException e) {
8626            if (fos != null) {
8627                mGrantFile.failWrite(fos);
8628            }
8629        }
8630    }
8631
8632    private void readGrantedUriPermissionsLocked() {
8633        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8634
8635        final long now = System.currentTimeMillis();
8636
8637        FileInputStream fis = null;
8638        try {
8639            fis = mGrantFile.openRead();
8640            final XmlPullParser in = Xml.newPullParser();
8641            in.setInput(fis, StandardCharsets.UTF_8.name());
8642
8643            int type;
8644            while ((type = in.next()) != END_DOCUMENT) {
8645                final String tag = in.getName();
8646                if (type == START_TAG) {
8647                    if (TAG_URI_GRANT.equals(tag)) {
8648                        final int sourceUserId;
8649                        final int targetUserId;
8650                        final int userHandle = readIntAttribute(in,
8651                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8652                        if (userHandle != UserHandle.USER_NULL) {
8653                            // For backwards compatibility.
8654                            sourceUserId = userHandle;
8655                            targetUserId = userHandle;
8656                        } else {
8657                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8658                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8659                        }
8660                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8661                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8662                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8663                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8664                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8665                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8666
8667                        // Sanity check that provider still belongs to source package
8668                        // Both direct boot aware and unaware packages are fine as we
8669                        // will do filtering at query time to avoid multiple parsing.
8670                        final ProviderInfo pi = getProviderInfoLocked(
8671                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8672                                        | MATCH_DIRECT_BOOT_UNAWARE);
8673                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8674                            int targetUid = -1;
8675                            try {
8676                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8677                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8678                            } catch (RemoteException e) {
8679                            }
8680                            if (targetUid != -1) {
8681                                final UriPermission perm = findOrCreateUriPermissionLocked(
8682                                        sourcePkg, targetPkg, targetUid,
8683                                        new GrantUri(sourceUserId, uri, prefix));
8684                                perm.initPersistedModes(modeFlags, createdTime);
8685                            }
8686                        } else {
8687                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8688                                    + " but instead found " + pi);
8689                        }
8690                    }
8691                }
8692            }
8693        } catch (FileNotFoundException e) {
8694            // Missing grants is okay
8695        } catch (IOException e) {
8696            Slog.wtf(TAG, "Failed reading Uri grants", e);
8697        } catch (XmlPullParserException e) {
8698            Slog.wtf(TAG, "Failed reading Uri grants", e);
8699        } finally {
8700            IoUtils.closeQuietly(fis);
8701        }
8702    }
8703
8704    /**
8705     * @param uri This uri must NOT contain an embedded userId.
8706     * @param userId The userId in which the uri is to be resolved.
8707     */
8708    @Override
8709    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8710        enforceNotIsolatedCaller("takePersistableUriPermission");
8711
8712        Preconditions.checkFlagsArgument(modeFlags,
8713                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8714
8715        synchronized (this) {
8716            final int callingUid = Binder.getCallingUid();
8717            boolean persistChanged = false;
8718            GrantUri grantUri = new GrantUri(userId, uri, false);
8719
8720            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8721                    new GrantUri(userId, uri, false));
8722            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8723                    new GrantUri(userId, uri, true));
8724
8725            final boolean exactValid = (exactPerm != null)
8726                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8727            final boolean prefixValid = (prefixPerm != null)
8728                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8729
8730            if (!(exactValid || prefixValid)) {
8731                throw new SecurityException("No persistable permission grants found for UID "
8732                        + callingUid + " and Uri " + grantUri.toSafeString());
8733            }
8734
8735            if (exactValid) {
8736                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8737            }
8738            if (prefixValid) {
8739                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8740            }
8741
8742            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8743
8744            if (persistChanged) {
8745                schedulePersistUriGrants();
8746            }
8747        }
8748    }
8749
8750    /**
8751     * @param uri This uri must NOT contain an embedded userId.
8752     * @param userId The userId in which the uri is to be resolved.
8753     */
8754    @Override
8755    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8756        enforceNotIsolatedCaller("releasePersistableUriPermission");
8757
8758        Preconditions.checkFlagsArgument(modeFlags,
8759                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8760
8761        synchronized (this) {
8762            final int callingUid = Binder.getCallingUid();
8763            boolean persistChanged = false;
8764
8765            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8766                    new GrantUri(userId, uri, false));
8767            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8768                    new GrantUri(userId, uri, true));
8769            if (exactPerm == null && prefixPerm == null) {
8770                throw new SecurityException("No permission grants found for UID " + callingUid
8771                        + " and Uri " + uri.toSafeString());
8772            }
8773
8774            if (exactPerm != null) {
8775                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8776                removeUriPermissionIfNeededLocked(exactPerm);
8777            }
8778            if (prefixPerm != null) {
8779                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8780                removeUriPermissionIfNeededLocked(prefixPerm);
8781            }
8782
8783            if (persistChanged) {
8784                schedulePersistUriGrants();
8785            }
8786        }
8787    }
8788
8789    /**
8790     * Prune any older {@link UriPermission} for the given UID until outstanding
8791     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8792     *
8793     * @return if any mutations occured that require persisting.
8794     */
8795    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8796        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8797        if (perms == null) return false;
8798        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8799
8800        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8801        for (UriPermission perm : perms.values()) {
8802            if (perm.persistedModeFlags != 0) {
8803                persisted.add(perm);
8804            }
8805        }
8806
8807        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8808        if (trimCount <= 0) return false;
8809
8810        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8811        for (int i = 0; i < trimCount; i++) {
8812            final UriPermission perm = persisted.get(i);
8813
8814            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8815                    "Trimming grant created at " + perm.persistedCreateTime);
8816
8817            perm.releasePersistableModes(~0);
8818            removeUriPermissionIfNeededLocked(perm);
8819        }
8820
8821        return true;
8822    }
8823
8824    @Override
8825    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8826            String packageName, boolean incoming) {
8827        enforceNotIsolatedCaller("getPersistedUriPermissions");
8828        Preconditions.checkNotNull(packageName, "packageName");
8829
8830        final int callingUid = Binder.getCallingUid();
8831        final IPackageManager pm = AppGlobals.getPackageManager();
8832        try {
8833            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8834                    UserHandle.getUserId(callingUid));
8835            if (packageUid != callingUid) {
8836                throw new SecurityException(
8837                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8838            }
8839        } catch (RemoteException e) {
8840            throw new SecurityException("Failed to verify package name ownership");
8841        }
8842
8843        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8844        synchronized (this) {
8845            if (incoming) {
8846                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8847                        callingUid);
8848                if (perms == null) {
8849                    Slog.w(TAG, "No permission grants found for " + packageName);
8850                } else {
8851                    final int userId = UserHandle.getUserId(callingUid);
8852                    Set<String> existingAuthorities = null;
8853
8854                    for (UriPermission perm : perms.values()) {
8855                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8856                            // Is this provider available in the current boot state? If the user
8857                            // is not running and unlocked we check if the provider package exists.
8858                            if (!mUserController.isUserRunningLocked(userId,
8859                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8860                                String authority = perm.uri.uri.getAuthority();
8861                                if (existingAuthorities == null
8862                                        || !existingAuthorities.contains(authority)) {
8863                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8864                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8865                                    if (providerInfo != null) {
8866                                        if (existingAuthorities == null) {
8867                                            existingAuthorities = new ArraySet<>();
8868                                        }
8869                                        existingAuthorities.add(authority);
8870                                    } else {
8871                                        continue;
8872                                    }
8873                                }
8874                            }
8875                            result.add(perm.buildPersistedPublicApiObject());
8876                        }
8877                    }
8878                }
8879            } else {
8880                final int size = mGrantedUriPermissions.size();
8881                for (int i = 0; i < size; i++) {
8882                    final ArrayMap<GrantUri, UriPermission> perms =
8883                            mGrantedUriPermissions.valueAt(i);
8884                    for (UriPermission perm : perms.values()) {
8885                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8886                            result.add(perm.buildPersistedPublicApiObject());
8887                        }
8888                    }
8889                }
8890            }
8891        }
8892        return new ParceledListSlice<android.content.UriPermission>(result);
8893    }
8894
8895    @Override
8896    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8897            String packageName, int userId) {
8898        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8899                "getGrantedUriPermissions");
8900
8901        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8902        synchronized (this) {
8903            final int size = mGrantedUriPermissions.size();
8904            for (int i = 0; i < size; i++) {
8905                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8906                for (UriPermission perm : perms.values()) {
8907                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8908                            && perm.persistedModeFlags != 0) {
8909                        result.add(perm.buildPersistedPublicApiObject());
8910                    }
8911                }
8912            }
8913        }
8914        return new ParceledListSlice<android.content.UriPermission>(result);
8915    }
8916
8917    @Override
8918    public void clearGrantedUriPermissions(String packageName, int userId) {
8919        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8920                "clearGrantedUriPermissions");
8921        removeUriPermissionsForPackageLocked(packageName, userId, true);
8922    }
8923
8924    @Override
8925    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8926        synchronized (this) {
8927            ProcessRecord app =
8928                who != null ? getRecordForAppLocked(who) : null;
8929            if (app == null) return;
8930
8931            Message msg = Message.obtain();
8932            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8933            msg.obj = app;
8934            msg.arg1 = waiting ? 1 : 0;
8935            mUiHandler.sendMessage(msg);
8936        }
8937    }
8938
8939    @Override
8940    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8941        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8942        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8943        outInfo.availMem = Process.getFreeMemory();
8944        outInfo.totalMem = Process.getTotalMemory();
8945        outInfo.threshold = homeAppMem;
8946        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8947        outInfo.hiddenAppThreshold = cachedAppMem;
8948        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8949                ProcessList.SERVICE_ADJ);
8950        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8951                ProcessList.VISIBLE_APP_ADJ);
8952        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8953                ProcessList.FOREGROUND_APP_ADJ);
8954    }
8955
8956    // =========================================================
8957    // TASK MANAGEMENT
8958    // =========================================================
8959
8960    @Override
8961    public List<IAppTask> getAppTasks(String callingPackage) {
8962        int callingUid = Binder.getCallingUid();
8963        long ident = Binder.clearCallingIdentity();
8964
8965        synchronized(this) {
8966            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8967            try {
8968                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8969
8970                final int N = mRecentTasks.size();
8971                for (int i = 0; i < N; i++) {
8972                    TaskRecord tr = mRecentTasks.get(i);
8973                    // Skip tasks that do not match the caller.  We don't need to verify
8974                    // callingPackage, because we are also limiting to callingUid and know
8975                    // that will limit to the correct security sandbox.
8976                    if (tr.effectiveUid != callingUid) {
8977                        continue;
8978                    }
8979                    Intent intent = tr.getBaseIntent();
8980                    if (intent == null ||
8981                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8982                        continue;
8983                    }
8984                    ActivityManager.RecentTaskInfo taskInfo =
8985                            createRecentTaskInfoFromTaskRecord(tr);
8986                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8987                    list.add(taskImpl);
8988                }
8989            } finally {
8990                Binder.restoreCallingIdentity(ident);
8991            }
8992            return list;
8993        }
8994    }
8995
8996    @Override
8997    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8998        final int callingUid = Binder.getCallingUid();
8999        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9000
9001        synchronized(this) {
9002            if (DEBUG_ALL) Slog.v(
9003                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9004
9005            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9006                    callingUid);
9007
9008            // TODO: Improve with MRU list from all ActivityStacks.
9009            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9010        }
9011
9012        return list;
9013    }
9014
9015    /**
9016     * Creates a new RecentTaskInfo from a TaskRecord.
9017     */
9018    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9019        // Update the task description to reflect any changes in the task stack
9020        tr.updateTaskDescription();
9021
9022        // Compose the recent task info
9023        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9024        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9025        rti.persistentId = tr.taskId;
9026        rti.baseIntent = new Intent(tr.getBaseIntent());
9027        rti.origActivity = tr.origActivity;
9028        rti.realActivity = tr.realActivity;
9029        rti.description = tr.lastDescription;
9030        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9031        rti.userId = tr.userId;
9032        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9033        rti.firstActiveTime = tr.firstActiveTime;
9034        rti.lastActiveTime = tr.lastActiveTime;
9035        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9036        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9037        rti.numActivities = 0;
9038        if (tr.mBounds != null) {
9039            rti.bounds = new Rect(tr.mBounds);
9040        }
9041        rti.isDockable = tr.canGoInDockedStack();
9042        rti.resizeMode = tr.mResizeMode;
9043
9044        ActivityRecord base = null;
9045        ActivityRecord top = null;
9046        ActivityRecord tmp;
9047
9048        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9049            tmp = tr.mActivities.get(i);
9050            if (tmp.finishing) {
9051                continue;
9052            }
9053            base = tmp;
9054            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9055                top = base;
9056            }
9057            rti.numActivities++;
9058        }
9059
9060        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9061        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9062
9063        return rti;
9064    }
9065
9066    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9067        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9068                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9069        if (!allowed) {
9070            if (checkPermission(android.Manifest.permission.GET_TASKS,
9071                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9072                // Temporary compatibility: some existing apps on the system image may
9073                // still be requesting the old permission and not switched to the new
9074                // one; if so, we'll still allow them full access.  This means we need
9075                // to see if they are holding the old permission and are a system app.
9076                try {
9077                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9078                        allowed = true;
9079                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9080                                + " is using old GET_TASKS but privileged; allowing");
9081                    }
9082                } catch (RemoteException e) {
9083                }
9084            }
9085        }
9086        if (!allowed) {
9087            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9088                    + " does not hold REAL_GET_TASKS; limiting output");
9089        }
9090        return allowed;
9091    }
9092
9093    @Override
9094    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9095        final int callingUid = Binder.getCallingUid();
9096        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9097                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9098
9099        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9100        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9101        synchronized (this) {
9102            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9103                    callingUid);
9104            final boolean detailed = checkCallingPermission(
9105                    android.Manifest.permission.GET_DETAILED_TASKS)
9106                    == PackageManager.PERMISSION_GRANTED;
9107
9108            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9109                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9110                return Collections.emptyList();
9111            }
9112            mRecentTasks.loadUserRecentsLocked(userId);
9113
9114            final int recentsCount = mRecentTasks.size();
9115            ArrayList<ActivityManager.RecentTaskInfo> res =
9116                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9117
9118            final Set<Integer> includedUsers;
9119            if (includeProfiles) {
9120                includedUsers = mUserController.getProfileIds(userId);
9121            } else {
9122                includedUsers = new HashSet<>();
9123            }
9124            includedUsers.add(Integer.valueOf(userId));
9125
9126            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9127                TaskRecord tr = mRecentTasks.get(i);
9128                // Only add calling user or related users recent tasks
9129                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9130                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9131                    continue;
9132                }
9133
9134                if (tr.realActivitySuspended) {
9135                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9136                    continue;
9137                }
9138
9139                // Return the entry if desired by the caller.  We always return
9140                // the first entry, because callers always expect this to be the
9141                // foreground app.  We may filter others if the caller has
9142                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9143                // we should exclude the entry.
9144
9145                if (i == 0
9146                        || withExcluded
9147                        || (tr.intent == null)
9148                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9149                                == 0)) {
9150                    if (!allowed) {
9151                        // If the caller doesn't have the GET_TASKS permission, then only
9152                        // allow them to see a small subset of tasks -- their own and home.
9153                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9154                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9155                            continue;
9156                        }
9157                    }
9158                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9159                        if (tr.stack != null && tr.stack.isHomeStack()) {
9160                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9161                                    "Skipping, home stack task: " + tr);
9162                            continue;
9163                        }
9164                    }
9165                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9166                        final ActivityStack stack = tr.stack;
9167                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9168                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                    "Skipping, top task in docked stack: " + tr);
9170                            continue;
9171                        }
9172                    }
9173                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9174                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9175                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9176                                    "Skipping, pinned stack task: " + tr);
9177                            continue;
9178                        }
9179                    }
9180                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9181                        // Don't include auto remove tasks that are finished or finishing.
9182                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9183                                "Skipping, auto-remove without activity: " + tr);
9184                        continue;
9185                    }
9186                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9187                            && !tr.isAvailable) {
9188                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189                                "Skipping, unavail real act: " + tr);
9190                        continue;
9191                    }
9192
9193                    if (!tr.mUserSetupComplete) {
9194                        // Don't include task launched while user is not done setting-up.
9195                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9196                                "Skipping, user setup not complete: " + tr);
9197                        continue;
9198                    }
9199
9200                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9201                    if (!detailed) {
9202                        rti.baseIntent.replaceExtras((Bundle)null);
9203                    }
9204
9205                    res.add(rti);
9206                    maxNum--;
9207                }
9208            }
9209            return res;
9210        }
9211    }
9212
9213    @Override
9214    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9215        synchronized (this) {
9216            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9217                    "getTaskThumbnail()");
9218            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9219                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9220            if (tr != null) {
9221                return tr.getTaskThumbnailLocked();
9222            }
9223        }
9224        return null;
9225    }
9226
9227    @Override
9228    public int addAppTask(IBinder activityToken, Intent intent,
9229            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9230        final int callingUid = Binder.getCallingUid();
9231        final long callingIdent = Binder.clearCallingIdentity();
9232
9233        try {
9234            synchronized (this) {
9235                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9236                if (r == null) {
9237                    throw new IllegalArgumentException("Activity does not exist; token="
9238                            + activityToken);
9239                }
9240                ComponentName comp = intent.getComponent();
9241                if (comp == null) {
9242                    throw new IllegalArgumentException("Intent " + intent
9243                            + " must specify explicit component");
9244                }
9245                if (thumbnail.getWidth() != mThumbnailWidth
9246                        || thumbnail.getHeight() != mThumbnailHeight) {
9247                    throw new IllegalArgumentException("Bad thumbnail size: got "
9248                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9249                            + mThumbnailWidth + "x" + mThumbnailHeight);
9250                }
9251                if (intent.getSelector() != null) {
9252                    intent.setSelector(null);
9253                }
9254                if (intent.getSourceBounds() != null) {
9255                    intent.setSourceBounds(null);
9256                }
9257                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9258                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9259                        // The caller has added this as an auto-remove task...  that makes no
9260                        // sense, so turn off auto-remove.
9261                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9262                    }
9263                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9264                    // Must be a new task.
9265                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9266                }
9267                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9268                    mLastAddedTaskActivity = null;
9269                }
9270                ActivityInfo ainfo = mLastAddedTaskActivity;
9271                if (ainfo == null) {
9272                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9273                            comp, 0, UserHandle.getUserId(callingUid));
9274                    if (ainfo.applicationInfo.uid != callingUid) {
9275                        throw new SecurityException(
9276                                "Can't add task for another application: target uid="
9277                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9278                    }
9279                }
9280
9281                // Use the full screen as the context for the task thumbnail
9282                final Point displaySize = new Point();
9283                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9284                r.task.stack.getDisplaySize(displaySize);
9285                thumbnailInfo.taskWidth = displaySize.x;
9286                thumbnailInfo.taskHeight = displaySize.y;
9287                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9288
9289                TaskRecord task = new TaskRecord(this,
9290                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9291                        ainfo, intent, description, thumbnailInfo);
9292
9293                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9294                if (trimIdx >= 0) {
9295                    // If this would have caused a trim, then we'll abort because that
9296                    // means it would be added at the end of the list but then just removed.
9297                    return INVALID_TASK_ID;
9298                }
9299
9300                final int N = mRecentTasks.size();
9301                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9302                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9303                    tr.removedFromRecents();
9304                }
9305
9306                task.inRecents = true;
9307                mRecentTasks.add(task);
9308                r.task.stack.addTask(task, false, "addAppTask");
9309
9310                task.setLastThumbnailLocked(thumbnail);
9311                task.freeLastThumbnail();
9312
9313                return task.taskId;
9314            }
9315        } finally {
9316            Binder.restoreCallingIdentity(callingIdent);
9317        }
9318    }
9319
9320    @Override
9321    public Point getAppTaskThumbnailSize() {
9322        synchronized (this) {
9323            return new Point(mThumbnailWidth,  mThumbnailHeight);
9324        }
9325    }
9326
9327    @Override
9328    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9329        synchronized (this) {
9330            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9331            if (r != null) {
9332                r.setTaskDescription(td);
9333                r.task.updateTaskDescription();
9334            }
9335        }
9336    }
9337
9338    @Override
9339    public void setTaskResizeable(int taskId, int resizeableMode) {
9340        synchronized (this) {
9341            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9342                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9343            if (task == null) {
9344                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9345                return;
9346            }
9347            if (task.mResizeMode != resizeableMode) {
9348                task.mResizeMode = resizeableMode;
9349                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9350                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9351                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9352            }
9353        }
9354    }
9355
9356    @Override
9357    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9358        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9359        long ident = Binder.clearCallingIdentity();
9360        try {
9361            synchronized (this) {
9362                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9363                if (task == null) {
9364                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9365                    return;
9366                }
9367                int stackId = task.stack.mStackId;
9368                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9369                // in crop windows resize mode or if the task size is affected by the docked stack
9370                // changing size. No need to update configuration.
9371                if (bounds != null && task.inCropWindowsResizeMode()
9372                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9373                    mWindowManager.scrollTask(task.taskId, bounds);
9374                    return;
9375                }
9376
9377                // Place the task in the right stack if it isn't there already based on
9378                // the requested bounds.
9379                // The stack transition logic is:
9380                // - a null bounds on a freeform task moves that task to fullscreen
9381                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9382                //   that task to freeform
9383                // - otherwise the task is not moved
9384                if (!StackId.isTaskResizeAllowed(stackId)) {
9385                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9386                }
9387                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9388                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9389                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9390                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9391                }
9392                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9393                if (stackId != task.stack.mStackId) {
9394                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9395                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9396                    preserveWindow = false;
9397                }
9398
9399                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9400                        false /* deferResume */);
9401            }
9402        } finally {
9403            Binder.restoreCallingIdentity(ident);
9404        }
9405    }
9406
9407    @Override
9408    public Rect getTaskBounds(int taskId) {
9409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9410        long ident = Binder.clearCallingIdentity();
9411        Rect rect = new Rect();
9412        try {
9413            synchronized (this) {
9414                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9415                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9416                if (task == null) {
9417                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9418                    return rect;
9419                }
9420                if (task.stack != null) {
9421                    // Return the bounds from window manager since it will be adjusted for various
9422                    // things like the presense of a docked stack for tasks that aren't resizeable.
9423                    mWindowManager.getTaskBounds(task.taskId, rect);
9424                } else {
9425                    // Task isn't in window manager yet since it isn't associated with a stack.
9426                    // Return the persist value from activity manager
9427                    if (task.mBounds != null) {
9428                        rect.set(task.mBounds);
9429                    } else if (task.mLastNonFullscreenBounds != null) {
9430                        rect.set(task.mLastNonFullscreenBounds);
9431                    }
9432                }
9433            }
9434        } finally {
9435            Binder.restoreCallingIdentity(ident);
9436        }
9437        return rect;
9438    }
9439
9440    @Override
9441    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9442        if (userId != UserHandle.getCallingUserId()) {
9443            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9444                    "getTaskDescriptionIcon");
9445        }
9446        final File passedIconFile = new File(filePath);
9447        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9448                passedIconFile.getName());
9449        if (!legitIconFile.getPath().equals(filePath)
9450                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9451            throw new IllegalArgumentException("Bad file path: " + filePath
9452                    + " passed for userId " + userId);
9453        }
9454        return mRecentTasks.getTaskDescriptionIcon(filePath);
9455    }
9456
9457    @Override
9458    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9459            throws RemoteException {
9460        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9461                opts.getCustomInPlaceResId() == 0) {
9462            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9463                    "with valid animation");
9464        }
9465        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9466        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9467                opts.getCustomInPlaceResId());
9468        mWindowManager.executeAppTransition();
9469    }
9470
9471    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9472            boolean removeFromRecents) {
9473        if (removeFromRecents) {
9474            mRecentTasks.remove(tr);
9475            tr.removedFromRecents();
9476        }
9477        ComponentName component = tr.getBaseIntent().getComponent();
9478        if (component == null) {
9479            Slog.w(TAG, "No component for base intent of task: " + tr);
9480            return;
9481        }
9482
9483        // Find any running services associated with this app and stop if needed.
9484        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9485
9486        if (!killProcess) {
9487            return;
9488        }
9489
9490        // Determine if the process(es) for this task should be killed.
9491        final String pkg = component.getPackageName();
9492        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9493        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9494        for (int i = 0; i < pmap.size(); i++) {
9495
9496            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9497            for (int j = 0; j < uids.size(); j++) {
9498                ProcessRecord proc = uids.valueAt(j);
9499                if (proc.userId != tr.userId) {
9500                    // Don't kill process for a different user.
9501                    continue;
9502                }
9503                if (proc == mHomeProcess) {
9504                    // Don't kill the home process along with tasks from the same package.
9505                    continue;
9506                }
9507                if (!proc.pkgList.containsKey(pkg)) {
9508                    // Don't kill process that is not associated with this task.
9509                    continue;
9510                }
9511
9512                for (int k = 0; k < proc.activities.size(); k++) {
9513                    TaskRecord otherTask = proc.activities.get(k).task;
9514                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9515                        // Don't kill process(es) that has an activity in a different task that is
9516                        // also in recents.
9517                        return;
9518                    }
9519                }
9520
9521                if (proc.foregroundServices) {
9522                    // Don't kill process(es) with foreground service.
9523                    return;
9524                }
9525
9526                // Add process to kill list.
9527                procsToKill.add(proc);
9528            }
9529        }
9530
9531        // Kill the running processes.
9532        for (int i = 0; i < procsToKill.size(); i++) {
9533            ProcessRecord pr = procsToKill.get(i);
9534            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9535                    && pr.curReceiver == null) {
9536                pr.kill("remove task", true);
9537            } else {
9538                // We delay killing processes that are not in the background or running a receiver.
9539                pr.waitingToKill = "remove task";
9540            }
9541        }
9542    }
9543
9544    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9545        // Remove all tasks with activities in the specified package from the list of recent tasks
9546        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9547            TaskRecord tr = mRecentTasks.get(i);
9548            if (tr.userId != userId) continue;
9549
9550            ComponentName cn = tr.intent.getComponent();
9551            if (cn != null && cn.getPackageName().equals(packageName)) {
9552                // If the package name matches, remove the task.
9553                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9554            }
9555        }
9556    }
9557
9558    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9559            int userId) {
9560
9561        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9562            TaskRecord tr = mRecentTasks.get(i);
9563            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9564                continue;
9565            }
9566
9567            ComponentName cn = tr.intent.getComponent();
9568            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9569                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9570            if (sameComponent) {
9571                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9572            }
9573        }
9574    }
9575
9576    /**
9577     * Removes the task with the specified task id.
9578     *
9579     * @param taskId Identifier of the task to be removed.
9580     * @param killProcess Kill any process associated with the task if possible.
9581     * @param removeFromRecents Whether to also remove the task from recents.
9582     * @return Returns true if the given task was found and removed.
9583     */
9584    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9585            boolean removeFromRecents) {
9586        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9587                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9588        if (tr != null) {
9589            tr.removeTaskActivitiesLocked();
9590            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9591            if (tr.isPersistable) {
9592                notifyTaskPersisterLocked(null, true);
9593            }
9594            return true;
9595        }
9596        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9597        return false;
9598    }
9599
9600    @Override
9601    public void removeStack(int stackId) {
9602        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9603        if (stackId == HOME_STACK_ID) {
9604            throw new IllegalArgumentException("Removing home stack is not allowed.");
9605        }
9606
9607        synchronized (this) {
9608            final long ident = Binder.clearCallingIdentity();
9609            try {
9610                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9611                if (stack == null) {
9612                    return;
9613                }
9614                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9615                for (int i = tasks.size() - 1; i >= 0; i--) {
9616                    removeTaskByIdLocked(
9617                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9618                }
9619            } finally {
9620                Binder.restoreCallingIdentity(ident);
9621            }
9622        }
9623    }
9624
9625    @Override
9626    public boolean removeTask(int taskId) {
9627        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9628        synchronized (this) {
9629            final long ident = Binder.clearCallingIdentity();
9630            try {
9631                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9632            } finally {
9633                Binder.restoreCallingIdentity(ident);
9634            }
9635        }
9636    }
9637
9638    /**
9639     * TODO: Add mController hook
9640     */
9641    @Override
9642    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9643        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9644
9645        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9646        synchronized(this) {
9647            moveTaskToFrontLocked(taskId, flags, bOptions);
9648        }
9649    }
9650
9651    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9652        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9653
9654        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9655                Binder.getCallingUid(), -1, -1, "Task to front")) {
9656            ActivityOptions.abort(options);
9657            return;
9658        }
9659        final long origId = Binder.clearCallingIdentity();
9660        try {
9661            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9662            if (task == null) {
9663                Slog.d(TAG, "Could not find task for id: "+ taskId);
9664                return;
9665            }
9666            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9667                mStackSupervisor.showLockTaskToast();
9668                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9669                return;
9670            }
9671            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9672            if (prev != null && prev.isRecentsActivity()) {
9673                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9674            }
9675            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9676                    false /* forceNonResizable */);
9677        } finally {
9678            Binder.restoreCallingIdentity(origId);
9679        }
9680        ActivityOptions.abort(options);
9681    }
9682
9683    /**
9684     * Moves an activity, and all of the other activities within the same task, to the bottom
9685     * of the history stack.  The activity's order within the task is unchanged.
9686     *
9687     * @param token A reference to the activity we wish to move
9688     * @param nonRoot If false then this only works if the activity is the root
9689     *                of a task; if true it will work for any activity in a task.
9690     * @return Returns true if the move completed, false if not.
9691     */
9692    @Override
9693    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9694        enforceNotIsolatedCaller("moveActivityTaskToBack");
9695        synchronized(this) {
9696            final long origId = Binder.clearCallingIdentity();
9697            try {
9698                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9699                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9700                if (task != null) {
9701                    if (mStackSupervisor.isLockedTask(task)) {
9702                        mStackSupervisor.showLockTaskToast();
9703                        return false;
9704                    }
9705                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9706                }
9707            } finally {
9708                Binder.restoreCallingIdentity(origId);
9709            }
9710        }
9711        return false;
9712    }
9713
9714    @Override
9715    public void moveTaskBackwards(int task) {
9716        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9717                "moveTaskBackwards()");
9718
9719        synchronized(this) {
9720            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9721                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9722                return;
9723            }
9724            final long origId = Binder.clearCallingIdentity();
9725            moveTaskBackwardsLocked(task);
9726            Binder.restoreCallingIdentity(origId);
9727        }
9728    }
9729
9730    private final void moveTaskBackwardsLocked(int task) {
9731        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9732    }
9733
9734    @Override
9735    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9736            IActivityContainerCallback callback) throws RemoteException {
9737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9738        synchronized (this) {
9739            if (parentActivityToken == null) {
9740                throw new IllegalArgumentException("parent token must not be null");
9741            }
9742            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9743            if (r == null) {
9744                return null;
9745            }
9746            if (callback == null) {
9747                throw new IllegalArgumentException("callback must not be null");
9748            }
9749            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9750        }
9751    }
9752
9753    @Override
9754    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9755        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9756        synchronized (this) {
9757            mStackSupervisor.deleteActivityContainer(container);
9758        }
9759    }
9760
9761    @Override
9762    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9764        synchronized (this) {
9765            final int stackId = mStackSupervisor.getNextStackId();
9766            final ActivityStack stack =
9767                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9768            if (stack == null) {
9769                return null;
9770            }
9771            return stack.mActivityContainer;
9772        }
9773    }
9774
9775    @Override
9776    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9777        synchronized (this) {
9778            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9779            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9780                return stack.mActivityContainer.getDisplayId();
9781            }
9782            return Display.DEFAULT_DISPLAY;
9783        }
9784    }
9785
9786    @Override
9787    public int getActivityStackId(IBinder token) throws RemoteException {
9788        synchronized (this) {
9789            ActivityStack stack = ActivityRecord.getStackLocked(token);
9790            if (stack == null) {
9791                return INVALID_STACK_ID;
9792            }
9793            return stack.mStackId;
9794        }
9795    }
9796
9797    @Override
9798    public void exitFreeformMode(IBinder token) throws RemoteException {
9799        synchronized (this) {
9800            long ident = Binder.clearCallingIdentity();
9801            try {
9802                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9803                if (r == null) {
9804                    throw new IllegalArgumentException(
9805                            "exitFreeformMode: No activity record matching token=" + token);
9806                }
9807                final ActivityStack stack = r.getStackLocked(token);
9808                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9809                    throw new IllegalStateException(
9810                            "exitFreeformMode: You can only go fullscreen from freeform.");
9811                }
9812                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9813                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9814                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9815            } finally {
9816                Binder.restoreCallingIdentity(ident);
9817            }
9818        }
9819    }
9820
9821    @Override
9822    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9823        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9824        if (stackId == HOME_STACK_ID) {
9825            throw new IllegalArgumentException(
9826                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9827        }
9828        synchronized (this) {
9829            long ident = Binder.clearCallingIdentity();
9830            try {
9831                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9832                        + " to stackId=" + stackId + " toTop=" + toTop);
9833                if (stackId == DOCKED_STACK_ID) {
9834                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9835                            null /* initialBounds */);
9836                }
9837                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9838                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9839                if (result && stackId == DOCKED_STACK_ID) {
9840                    // If task moved to docked stack - show recents if needed.
9841                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9842                            "moveTaskToDockedStack");
9843                }
9844            } finally {
9845                Binder.restoreCallingIdentity(ident);
9846            }
9847        }
9848    }
9849
9850    @Override
9851    public void swapDockedAndFullscreenStack() throws RemoteException {
9852        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9853        synchronized (this) {
9854            long ident = Binder.clearCallingIdentity();
9855            try {
9856                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9857                        FULLSCREEN_WORKSPACE_STACK_ID);
9858                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9859                        : null;
9860                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9861                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9862                        : null;
9863                if (topTask == null || tasks == null || tasks.size() == 0) {
9864                    Slog.w(TAG,
9865                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9866                    return;
9867                }
9868
9869                // TODO: App transition
9870                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9871
9872                // Defer the resume so resume/pausing while moving stacks is dangerous.
9873                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9874                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9875                        ANIMATE, true /* deferResume */);
9876                final int size = tasks.size();
9877                for (int i = 0; i < size; i++) {
9878                    final int id = tasks.get(i).taskId;
9879                    if (id == topTask.taskId) {
9880                        continue;
9881                    }
9882                    mStackSupervisor.moveTaskToStackLocked(id,
9883                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9884                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9885                }
9886
9887                // Because we deferred the resume, to avoid conflicts with stack switches while
9888                // resuming, we need to do it after all the tasks are moved.
9889                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9890                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9891
9892                mWindowManager.executeAppTransition();
9893            } finally {
9894                Binder.restoreCallingIdentity(ident);
9895            }
9896        }
9897    }
9898
9899    /**
9900     * Moves the input task to the docked stack.
9901     *
9902     * @param taskId Id of task to move.
9903     * @param createMode The mode the docked stack should be created in if it doesn't exist
9904     *                   already. See
9905     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9906     *                   and
9907     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9908     * @param toTop If the task and stack should be moved to the top.
9909     * @param animate Whether we should play an animation for the moving the task
9910     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9911     *                      docked stack. Pass {@code null} to use default bounds.
9912     */
9913    @Override
9914    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9915            Rect initialBounds, boolean moveHomeStackFront) {
9916        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9917        synchronized (this) {
9918            long ident = Binder.clearCallingIdentity();
9919            try {
9920                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9921                        + " to createMode=" + createMode + " toTop=" + toTop);
9922                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9923                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9924                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9925                        animate, DEFER_RESUME);
9926                if (moved) {
9927                    if (moveHomeStackFront) {
9928                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9929                    }
9930                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9931                }
9932                return moved;
9933            } finally {
9934                Binder.restoreCallingIdentity(ident);
9935            }
9936        }
9937    }
9938
9939    /**
9940     * Moves the top activity in the input stackId to the pinned stack.
9941     *
9942     * @param stackId Id of stack to move the top activity to pinned stack.
9943     * @param bounds Bounds to use for pinned stack.
9944     *
9945     * @return True if the top activity of the input stack was successfully moved to the pinned
9946     *          stack.
9947     */
9948    @Override
9949    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9950        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9951        synchronized (this) {
9952            if (!mSupportsPictureInPicture) {
9953                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9954                        + "Device doesn't support picture-in-pciture mode");
9955            }
9956
9957            long ident = Binder.clearCallingIdentity();
9958            try {
9959                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9960            } finally {
9961                Binder.restoreCallingIdentity(ident);
9962            }
9963        }
9964    }
9965
9966    @Override
9967    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9968            boolean preserveWindows, boolean animate, int animationDuration) {
9969        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9970        long ident = Binder.clearCallingIdentity();
9971        try {
9972            synchronized (this) {
9973                if (animate) {
9974                    if (stackId == PINNED_STACK_ID) {
9975                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9976                    } else {
9977                        throw new IllegalArgumentException("Stack: " + stackId
9978                                + " doesn't support animated resize.");
9979                    }
9980                } else {
9981                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9982                            null /* tempTaskInsetBounds */, preserveWindows,
9983                            allowResizeInDockedMode, !DEFER_RESUME);
9984                }
9985            }
9986        } finally {
9987            Binder.restoreCallingIdentity(ident);
9988        }
9989    }
9990
9991    @Override
9992    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9993            Rect tempDockedTaskInsetBounds,
9994            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9995        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9996                "resizeDockedStack()");
9997        long ident = Binder.clearCallingIdentity();
9998        try {
9999            synchronized (this) {
10000                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10001                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10002                        PRESERVE_WINDOWS);
10003            }
10004        } finally {
10005            Binder.restoreCallingIdentity(ident);
10006        }
10007    }
10008
10009    @Override
10010    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10011        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10012                "resizePinnedStack()");
10013        final long ident = Binder.clearCallingIdentity();
10014        try {
10015            synchronized (this) {
10016                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10017            }
10018        } finally {
10019            Binder.restoreCallingIdentity(ident);
10020        }
10021    }
10022
10023    @Override
10024    public void positionTaskInStack(int taskId, int stackId, int position) {
10025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10026        if (stackId == HOME_STACK_ID) {
10027            throw new IllegalArgumentException(
10028                    "positionTaskInStack: Attempt to change the position of task "
10029                    + taskId + " in/to home stack");
10030        }
10031        synchronized (this) {
10032            long ident = Binder.clearCallingIdentity();
10033            try {
10034                if (DEBUG_STACK) Slog.d(TAG_STACK,
10035                        "positionTaskInStack: positioning task=" + taskId
10036                        + " in stackId=" + stackId + " at position=" + position);
10037                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10038            } finally {
10039                Binder.restoreCallingIdentity(ident);
10040            }
10041        }
10042    }
10043
10044    @Override
10045    public List<StackInfo> getAllStackInfos() {
10046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10047        long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                return mStackSupervisor.getAllStackInfosLocked();
10051            }
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public StackInfo getStackInfo(int stackId) {
10059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10060        long ident = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                return mStackSupervisor.getStackInfoLocked(stackId);
10064            }
10065        } finally {
10066            Binder.restoreCallingIdentity(ident);
10067        }
10068    }
10069
10070    @Override
10071    public boolean isInHomeStack(int taskId) {
10072        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10073        long ident = Binder.clearCallingIdentity();
10074        try {
10075            synchronized (this) {
10076                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10077                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10078                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10079            }
10080        } finally {
10081            Binder.restoreCallingIdentity(ident);
10082        }
10083    }
10084
10085    @Override
10086    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10087        synchronized(this) {
10088            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10089        }
10090    }
10091
10092    @Override
10093    public void updateDeviceOwner(String packageName) {
10094        final int callingUid = Binder.getCallingUid();
10095        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10096            throw new SecurityException("updateDeviceOwner called from non-system process");
10097        }
10098        synchronized (this) {
10099            mDeviceOwnerName = packageName;
10100        }
10101    }
10102
10103    @Override
10104    public void updateLockTaskPackages(int userId, String[] packages) {
10105        final int callingUid = Binder.getCallingUid();
10106        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10107            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10108                    "updateLockTaskPackages()");
10109        }
10110        synchronized (this) {
10111            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10112                    Arrays.toString(packages));
10113            mLockTaskPackages.put(userId, packages);
10114            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10115        }
10116    }
10117
10118
10119    void startLockTaskModeLocked(TaskRecord task) {
10120        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10121        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10122            return;
10123        }
10124
10125        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10126        // is initiated by system after the pinning request was shown and locked mode is initiated
10127        // by an authorized app directly
10128        final int callingUid = Binder.getCallingUid();
10129        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10130        long ident = Binder.clearCallingIdentity();
10131        try {
10132            if (!isSystemInitiated) {
10133                task.mLockTaskUid = callingUid;
10134                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10135                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10136                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10137                    StatusBarManagerInternal statusBarManager =
10138                            LocalServices.getService(StatusBarManagerInternal.class);
10139                    if (statusBarManager != null) {
10140                        statusBarManager.showScreenPinningRequest(task.taskId);
10141                    }
10142                    return;
10143                }
10144
10145                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10146                if (stack == null || task != stack.topTask()) {
10147                    throw new IllegalArgumentException("Invalid task, not in foreground");
10148                }
10149            }
10150            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10151                    "Locking fully");
10152            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10153                    ActivityManager.LOCK_TASK_MODE_PINNED :
10154                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10155                    "startLockTask", true);
10156        } finally {
10157            Binder.restoreCallingIdentity(ident);
10158        }
10159    }
10160
10161    @Override
10162    public void startLockTaskMode(int taskId) {
10163        synchronized (this) {
10164            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10165            if (task != null) {
10166                startLockTaskModeLocked(task);
10167            }
10168        }
10169    }
10170
10171    @Override
10172    public void startLockTaskMode(IBinder token) {
10173        synchronized (this) {
10174            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10175            if (r == null) {
10176                return;
10177            }
10178            final TaskRecord task = r.task;
10179            if (task != null) {
10180                startLockTaskModeLocked(task);
10181            }
10182        }
10183    }
10184
10185    @Override
10186    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10187        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10188        // This makes inner call to look as if it was initiated by system.
10189        long ident = Binder.clearCallingIdentity();
10190        try {
10191            synchronized (this) {
10192                startLockTaskMode(taskId);
10193            }
10194        } finally {
10195            Binder.restoreCallingIdentity(ident);
10196        }
10197    }
10198
10199    @Override
10200    public void stopLockTaskMode() {
10201        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10202        if (lockTask == null) {
10203            // Our work here is done.
10204            return;
10205        }
10206
10207        final int callingUid = Binder.getCallingUid();
10208        final int lockTaskUid = lockTask.mLockTaskUid;
10209        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10210        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10211            // Done.
10212            return;
10213        } else {
10214            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10215            // It is possible lockTaskMode was started by the system process because
10216            // android:lockTaskMode is set to a locking value in the application manifest
10217            // instead of the app calling startLockTaskMode. In this case
10218            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10219            // {@link TaskRecord.effectiveUid} instead. Also caller with
10220            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10221            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10222                    && callingUid != lockTaskUid
10223                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10224                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10225                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10226            }
10227        }
10228        long ident = Binder.clearCallingIdentity();
10229        try {
10230            Log.d(TAG, "stopLockTaskMode");
10231            // Stop lock task
10232            synchronized (this) {
10233                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10234                        "stopLockTask", true);
10235            }
10236            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10237            if (tm != null) {
10238                tm.showInCallScreen(false);
10239            }
10240        } finally {
10241            Binder.restoreCallingIdentity(ident);
10242        }
10243    }
10244
10245    /**
10246     * This API should be called by SystemUI only when user perform certain action to dismiss
10247     * lock task mode. We should only dismiss pinned lock task mode in this case.
10248     */
10249    @Override
10250    public void stopSystemLockTaskMode() throws RemoteException {
10251        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10252            stopLockTaskMode();
10253        } else {
10254            mStackSupervisor.showLockTaskToast();
10255        }
10256    }
10257
10258    @Override
10259    public boolean isInLockTaskMode() {
10260        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10261    }
10262
10263    @Override
10264    public int getLockTaskModeState() {
10265        synchronized (this) {
10266            return mStackSupervisor.getLockTaskModeState();
10267        }
10268    }
10269
10270    @Override
10271    public void showLockTaskEscapeMessage(IBinder token) {
10272        synchronized (this) {
10273            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10274            if (r == null) {
10275                return;
10276            }
10277            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10278        }
10279    }
10280
10281    // =========================================================
10282    // CONTENT PROVIDERS
10283    // =========================================================
10284
10285    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10286        List<ProviderInfo> providers = null;
10287        try {
10288            providers = AppGlobals.getPackageManager()
10289                    .queryContentProviders(app.processName, app.uid,
10290                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10291                                    | MATCH_DEBUG_TRIAGED_MISSING)
10292                    .getList();
10293        } catch (RemoteException ex) {
10294        }
10295        if (DEBUG_MU) Slog.v(TAG_MU,
10296                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10297        int userId = app.userId;
10298        if (providers != null) {
10299            int N = providers.size();
10300            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10301            for (int i=0; i<N; i++) {
10302                // TODO: keep logic in sync with installEncryptionUnawareProviders
10303                ProviderInfo cpi =
10304                    (ProviderInfo)providers.get(i);
10305                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10306                        cpi.name, cpi.flags);
10307                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10308                    // This is a singleton provider, but a user besides the
10309                    // default user is asking to initialize a process it runs
10310                    // in...  well, no, it doesn't actually run in this process,
10311                    // it runs in the process of the default user.  Get rid of it.
10312                    providers.remove(i);
10313                    N--;
10314                    i--;
10315                    continue;
10316                }
10317
10318                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10319                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10320                if (cpr == null) {
10321                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10322                    mProviderMap.putProviderByClass(comp, cpr);
10323                }
10324                if (DEBUG_MU) Slog.v(TAG_MU,
10325                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10326                app.pubProviders.put(cpi.name, cpr);
10327                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10328                    // Don't add this if it is a platform component that is marked
10329                    // to run in multiple processes, because this is actually
10330                    // part of the framework so doesn't make sense to track as a
10331                    // separate apk in the process.
10332                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10333                            mProcessStats);
10334                }
10335                notifyPackageUse(cpi.applicationInfo.packageName,
10336                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10337            }
10338        }
10339        return providers;
10340    }
10341
10342    /**
10343     * Check if {@link ProcessRecord} has a possible chance at accessing the
10344     * given {@link ProviderInfo}. Final permission checking is always done
10345     * in {@link ContentProvider}.
10346     */
10347    private final String checkContentProviderPermissionLocked(
10348            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10349        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10350        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10351        boolean checkedGrants = false;
10352        if (checkUser) {
10353            // Looking for cross-user grants before enforcing the typical cross-users permissions
10354            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10355            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10356                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10357                    return null;
10358                }
10359                checkedGrants = true;
10360            }
10361            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10362                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10363            if (userId != tmpTargetUserId) {
10364                // When we actually went to determine the final targer user ID, this ended
10365                // up different than our initial check for the authority.  This is because
10366                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10367                // SELF.  So we need to re-check the grants again.
10368                checkedGrants = false;
10369            }
10370        }
10371        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10372                cpi.applicationInfo.uid, cpi.exported)
10373                == PackageManager.PERMISSION_GRANTED) {
10374            return null;
10375        }
10376        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10377                cpi.applicationInfo.uid, cpi.exported)
10378                == PackageManager.PERMISSION_GRANTED) {
10379            return null;
10380        }
10381
10382        PathPermission[] pps = cpi.pathPermissions;
10383        if (pps != null) {
10384            int i = pps.length;
10385            while (i > 0) {
10386                i--;
10387                PathPermission pp = pps[i];
10388                String pprperm = pp.getReadPermission();
10389                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10390                        cpi.applicationInfo.uid, cpi.exported)
10391                        == PackageManager.PERMISSION_GRANTED) {
10392                    return null;
10393                }
10394                String ppwperm = pp.getWritePermission();
10395                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10396                        cpi.applicationInfo.uid, cpi.exported)
10397                        == PackageManager.PERMISSION_GRANTED) {
10398                    return null;
10399                }
10400            }
10401        }
10402        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10403            return null;
10404        }
10405
10406        String msg;
10407        if (!cpi.exported) {
10408            msg = "Permission Denial: opening provider " + cpi.name
10409                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10410                    + ", uid=" + callingUid + ") that is not exported from uid "
10411                    + cpi.applicationInfo.uid;
10412        } else {
10413            msg = "Permission Denial: opening provider " + cpi.name
10414                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10415                    + ", uid=" + callingUid + ") requires "
10416                    + cpi.readPermission + " or " + cpi.writePermission;
10417        }
10418        Slog.w(TAG, msg);
10419        return msg;
10420    }
10421
10422    /**
10423     * Returns if the ContentProvider has granted a uri to callingUid
10424     */
10425    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10426        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10427        if (perms != null) {
10428            for (int i=perms.size()-1; i>=0; i--) {
10429                GrantUri grantUri = perms.keyAt(i);
10430                if (grantUri.sourceUserId == userId || !checkUser) {
10431                    if (matchesProvider(grantUri.uri, cpi)) {
10432                        return true;
10433                    }
10434                }
10435            }
10436        }
10437        return false;
10438    }
10439
10440    /**
10441     * Returns true if the uri authority is one of the authorities specified in the provider.
10442     */
10443    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10444        String uriAuth = uri.getAuthority();
10445        String cpiAuth = cpi.authority;
10446        if (cpiAuth.indexOf(';') == -1) {
10447            return cpiAuth.equals(uriAuth);
10448        }
10449        String[] cpiAuths = cpiAuth.split(";");
10450        int length = cpiAuths.length;
10451        for (int i = 0; i < length; i++) {
10452            if (cpiAuths[i].equals(uriAuth)) return true;
10453        }
10454        return false;
10455    }
10456
10457    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10458            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10459        if (r != null) {
10460            for (int i=0; i<r.conProviders.size(); i++) {
10461                ContentProviderConnection conn = r.conProviders.get(i);
10462                if (conn.provider == cpr) {
10463                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10464                            "Adding provider requested by "
10465                            + r.processName + " from process "
10466                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10467                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10468                    if (stable) {
10469                        conn.stableCount++;
10470                        conn.numStableIncs++;
10471                    } else {
10472                        conn.unstableCount++;
10473                        conn.numUnstableIncs++;
10474                    }
10475                    return conn;
10476                }
10477            }
10478            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10479            if (stable) {
10480                conn.stableCount = 1;
10481                conn.numStableIncs = 1;
10482            } else {
10483                conn.unstableCount = 1;
10484                conn.numUnstableIncs = 1;
10485            }
10486            cpr.connections.add(conn);
10487            r.conProviders.add(conn);
10488            startAssociationLocked(r.uid, r.processName, r.curProcState,
10489                    cpr.uid, cpr.name, cpr.info.processName);
10490            return conn;
10491        }
10492        cpr.addExternalProcessHandleLocked(externalProcessToken);
10493        return null;
10494    }
10495
10496    boolean decProviderCountLocked(ContentProviderConnection conn,
10497            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10498        if (conn != null) {
10499            cpr = conn.provider;
10500            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10501                    "Removing provider requested by "
10502                    + conn.client.processName + " from process "
10503                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10504                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10505            if (stable) {
10506                conn.stableCount--;
10507            } else {
10508                conn.unstableCount--;
10509            }
10510            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10511                cpr.connections.remove(conn);
10512                conn.client.conProviders.remove(conn);
10513                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10514                    // The client is more important than last activity -- note the time this
10515                    // is happening, so we keep the old provider process around a bit as last
10516                    // activity to avoid thrashing it.
10517                    if (cpr.proc != null) {
10518                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10519                    }
10520                }
10521                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10522                return true;
10523            }
10524            return false;
10525        }
10526        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10527        return false;
10528    }
10529
10530    private void checkTime(long startTime, String where) {
10531        long now = SystemClock.uptimeMillis();
10532        if ((now-startTime) > 50) {
10533            // If we are taking more than 50ms, log about it.
10534            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10535        }
10536    }
10537
10538    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10539            String name, IBinder token, boolean stable, int userId) {
10540        ContentProviderRecord cpr;
10541        ContentProviderConnection conn = null;
10542        ProviderInfo cpi = null;
10543
10544        synchronized(this) {
10545            long startTime = SystemClock.uptimeMillis();
10546
10547            ProcessRecord r = null;
10548            if (caller != null) {
10549                r = getRecordForAppLocked(caller);
10550                if (r == null) {
10551                    throw new SecurityException(
10552                            "Unable to find app for caller " + caller
10553                          + " (pid=" + Binder.getCallingPid()
10554                          + ") when getting content provider " + name);
10555                }
10556            }
10557
10558            boolean checkCrossUser = true;
10559
10560            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10561
10562            // First check if this content provider has been published...
10563            cpr = mProviderMap.getProviderByName(name, userId);
10564            // If that didn't work, check if it exists for user 0 and then
10565            // verify that it's a singleton provider before using it.
10566            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10567                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10568                if (cpr != null) {
10569                    cpi = cpr.info;
10570                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10571                            cpi.name, cpi.flags)
10572                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10573                        userId = UserHandle.USER_SYSTEM;
10574                        checkCrossUser = false;
10575                    } else {
10576                        cpr = null;
10577                        cpi = null;
10578                    }
10579                }
10580            }
10581
10582            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10583            if (providerRunning) {
10584                cpi = cpr.info;
10585                String msg;
10586                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10587                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10588                        != null) {
10589                    throw new SecurityException(msg);
10590                }
10591                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10592
10593                if (r != null && cpr.canRunHere(r)) {
10594                    // This provider has been published or is in the process
10595                    // of being published...  but it is also allowed to run
10596                    // in the caller's process, so don't make a connection
10597                    // and just let the caller instantiate its own instance.
10598                    ContentProviderHolder holder = cpr.newHolder(null);
10599                    // don't give caller the provider object, it needs
10600                    // to make its own.
10601                    holder.provider = null;
10602                    return holder;
10603                }
10604
10605                final long origId = Binder.clearCallingIdentity();
10606
10607                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10608
10609                // In this case the provider instance already exists, so we can
10610                // return it right away.
10611                conn = incProviderCountLocked(r, cpr, token, stable);
10612                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10613                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10614                        // If this is a perceptible app accessing the provider,
10615                        // make sure to count it as being accessed and thus
10616                        // back up on the LRU list.  This is good because
10617                        // content providers are often expensive to start.
10618                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10619                        updateLruProcessLocked(cpr.proc, false, null);
10620                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10621                    }
10622                }
10623
10624                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10625                boolean success = updateOomAdjLocked(cpr.proc);
10626                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10627                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10628                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10629                // NOTE: there is still a race here where a signal could be
10630                // pending on the process even though we managed to update its
10631                // adj level.  Not sure what to do about this, but at least
10632                // the race is now smaller.
10633                if (!success) {
10634                    // Uh oh...  it looks like the provider's process
10635                    // has been killed on us.  We need to wait for a new
10636                    // process to be started, and make sure its death
10637                    // doesn't kill our process.
10638                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10639                            + " is crashing; detaching " + r);
10640                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10641                    checkTime(startTime, "getContentProviderImpl: before appDied");
10642                    appDiedLocked(cpr.proc);
10643                    checkTime(startTime, "getContentProviderImpl: after appDied");
10644                    if (!lastRef) {
10645                        // This wasn't the last ref our process had on
10646                        // the provider...  we have now been killed, bail.
10647                        return null;
10648                    }
10649                    providerRunning = false;
10650                    conn = null;
10651                }
10652
10653                Binder.restoreCallingIdentity(origId);
10654            }
10655
10656            if (!providerRunning) {
10657                try {
10658                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10659                    cpi = AppGlobals.getPackageManager().
10660                        resolveContentProvider(name,
10661                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10662                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10663                } catch (RemoteException ex) {
10664                }
10665                if (cpi == null) {
10666                    return null;
10667                }
10668                // If the provider is a singleton AND
10669                // (it's a call within the same user || the provider is a
10670                // privileged app)
10671                // Then allow connecting to the singleton provider
10672                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10673                        cpi.name, cpi.flags)
10674                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10675                if (singleton) {
10676                    userId = UserHandle.USER_SYSTEM;
10677                }
10678                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10679                checkTime(startTime, "getContentProviderImpl: got app info for user");
10680
10681                String msg;
10682                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10683                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10684                        != null) {
10685                    throw new SecurityException(msg);
10686                }
10687                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10688
10689                if (!mProcessesReady
10690                        && !cpi.processName.equals("system")) {
10691                    // If this content provider does not run in the system
10692                    // process, and the system is not yet ready to run other
10693                    // processes, then fail fast instead of hanging.
10694                    throw new IllegalArgumentException(
10695                            "Attempt to launch content provider before system ready");
10696                }
10697
10698                // Make sure that the user who owns this provider is running.  If not,
10699                // we don't want to allow it to run.
10700                if (!mUserController.isUserRunningLocked(userId, 0)) {
10701                    Slog.w(TAG, "Unable to launch app "
10702                            + cpi.applicationInfo.packageName + "/"
10703                            + cpi.applicationInfo.uid + " for provider "
10704                            + name + ": user " + userId + " is stopped");
10705                    return null;
10706                }
10707
10708                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10709                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10710                cpr = mProviderMap.getProviderByClass(comp, userId);
10711                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10712                final boolean firstClass = cpr == null;
10713                if (firstClass) {
10714                    final long ident = Binder.clearCallingIdentity();
10715
10716                    // If permissions need a review before any of the app components can run,
10717                    // we return no provider and launch a review activity if the calling app
10718                    // is in the foreground.
10719                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10720                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10721                            return null;
10722                        }
10723                    }
10724
10725                    try {
10726                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10727                        ApplicationInfo ai =
10728                            AppGlobals.getPackageManager().
10729                                getApplicationInfo(
10730                                        cpi.applicationInfo.packageName,
10731                                        STOCK_PM_FLAGS, userId);
10732                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10733                        if (ai == null) {
10734                            Slog.w(TAG, "No package info for content provider "
10735                                    + cpi.name);
10736                            return null;
10737                        }
10738                        ai = getAppInfoForUser(ai, userId);
10739                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10740                    } catch (RemoteException ex) {
10741                        // pm is in same process, this will never happen.
10742                    } finally {
10743                        Binder.restoreCallingIdentity(ident);
10744                    }
10745                }
10746
10747                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10748
10749                if (r != null && cpr.canRunHere(r)) {
10750                    // If this is a multiprocess provider, then just return its
10751                    // info and allow the caller to instantiate it.  Only do
10752                    // this if the provider is the same user as the caller's
10753                    // process, or can run as root (so can be in any process).
10754                    return cpr.newHolder(null);
10755                }
10756
10757                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10758                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10759                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10760
10761                // This is single process, and our app is now connecting to it.
10762                // See if we are already in the process of launching this
10763                // provider.
10764                final int N = mLaunchingProviders.size();
10765                int i;
10766                for (i = 0; i < N; i++) {
10767                    if (mLaunchingProviders.get(i) == cpr) {
10768                        break;
10769                    }
10770                }
10771
10772                // If the provider is not already being launched, then get it
10773                // started.
10774                if (i >= N) {
10775                    final long origId = Binder.clearCallingIdentity();
10776
10777                    try {
10778                        // Content provider is now in use, its package can't be stopped.
10779                        try {
10780                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10781                            AppGlobals.getPackageManager().setPackageStoppedState(
10782                                    cpr.appInfo.packageName, false, userId);
10783                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10784                        } catch (RemoteException e) {
10785                        } catch (IllegalArgumentException e) {
10786                            Slog.w(TAG, "Failed trying to unstop package "
10787                                    + cpr.appInfo.packageName + ": " + e);
10788                        }
10789
10790                        // Use existing process if already started
10791                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10792                        ProcessRecord proc = getProcessRecordLocked(
10793                                cpi.processName, cpr.appInfo.uid, false);
10794                        if (proc != null && proc.thread != null && !proc.killed) {
10795                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10796                                    "Installing in existing process " + proc);
10797                            if (!proc.pubProviders.containsKey(cpi.name)) {
10798                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10799                                proc.pubProviders.put(cpi.name, cpr);
10800                                try {
10801                                    proc.thread.scheduleInstallProvider(cpi);
10802                                } catch (RemoteException e) {
10803                                }
10804                            }
10805                        } else {
10806                            checkTime(startTime, "getContentProviderImpl: before start process");
10807                            proc = startProcessLocked(cpi.processName,
10808                                    cpr.appInfo, false, 0, "content provider",
10809                                    new ComponentName(cpi.applicationInfo.packageName,
10810                                            cpi.name), false, false, false);
10811                            checkTime(startTime, "getContentProviderImpl: after start process");
10812                            if (proc == null) {
10813                                Slog.w(TAG, "Unable to launch app "
10814                                        + cpi.applicationInfo.packageName + "/"
10815                                        + cpi.applicationInfo.uid + " for provider "
10816                                        + name + ": process is bad");
10817                                return null;
10818                            }
10819                        }
10820                        cpr.launchingApp = proc;
10821                        mLaunchingProviders.add(cpr);
10822                    } finally {
10823                        Binder.restoreCallingIdentity(origId);
10824                    }
10825                }
10826
10827                checkTime(startTime, "getContentProviderImpl: updating data structures");
10828
10829                // Make sure the provider is published (the same provider class
10830                // may be published under multiple names).
10831                if (firstClass) {
10832                    mProviderMap.putProviderByClass(comp, cpr);
10833                }
10834
10835                mProviderMap.putProviderByName(name, cpr);
10836                conn = incProviderCountLocked(r, cpr, token, stable);
10837                if (conn != null) {
10838                    conn.waiting = true;
10839                }
10840            }
10841            checkTime(startTime, "getContentProviderImpl: done!");
10842        }
10843
10844        // Wait for the provider to be published...
10845        synchronized (cpr) {
10846            while (cpr.provider == null) {
10847                if (cpr.launchingApp == null) {
10848                    Slog.w(TAG, "Unable to launch app "
10849                            + cpi.applicationInfo.packageName + "/"
10850                            + cpi.applicationInfo.uid + " for provider "
10851                            + name + ": launching app became null");
10852                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10853                            UserHandle.getUserId(cpi.applicationInfo.uid),
10854                            cpi.applicationInfo.packageName,
10855                            cpi.applicationInfo.uid, name);
10856                    return null;
10857                }
10858                try {
10859                    if (DEBUG_MU) Slog.v(TAG_MU,
10860                            "Waiting to start provider " + cpr
10861                            + " launchingApp=" + cpr.launchingApp);
10862                    if (conn != null) {
10863                        conn.waiting = true;
10864                    }
10865                    cpr.wait();
10866                } catch (InterruptedException ex) {
10867                } finally {
10868                    if (conn != null) {
10869                        conn.waiting = false;
10870                    }
10871                }
10872            }
10873        }
10874        return cpr != null ? cpr.newHolder(conn) : null;
10875    }
10876
10877    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10878            ProcessRecord r, final int userId) {
10879        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10880                cpi.packageName, userId)) {
10881
10882            final boolean callerForeground = r == null || r.setSchedGroup
10883                    != ProcessList.SCHED_GROUP_BACKGROUND;
10884
10885            // Show a permission review UI only for starting from a foreground app
10886            if (!callerForeground) {
10887                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10888                        + cpi.packageName + " requires a permissions review");
10889                return false;
10890            }
10891
10892            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10893            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10894                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10895            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10896
10897            if (DEBUG_PERMISSIONS_REVIEW) {
10898                Slog.i(TAG, "u" + userId + " Launching permission review "
10899                        + "for package " + cpi.packageName);
10900            }
10901
10902            final UserHandle userHandle = new UserHandle(userId);
10903            mHandler.post(new Runnable() {
10904                @Override
10905                public void run() {
10906                    mContext.startActivityAsUser(intent, userHandle);
10907                }
10908            });
10909
10910            return false;
10911        }
10912
10913        return true;
10914    }
10915
10916    PackageManagerInternal getPackageManagerInternalLocked() {
10917        if (mPackageManagerInt == null) {
10918            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10919        }
10920        return mPackageManagerInt;
10921    }
10922
10923    @Override
10924    public final ContentProviderHolder getContentProvider(
10925            IApplicationThread caller, String name, int userId, boolean stable) {
10926        enforceNotIsolatedCaller("getContentProvider");
10927        if (caller == null) {
10928            String msg = "null IApplicationThread when getting content provider "
10929                    + name;
10930            Slog.w(TAG, msg);
10931            throw new SecurityException(msg);
10932        }
10933        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10934        // with cross-user grant.
10935        return getContentProviderImpl(caller, name, null, stable, userId);
10936    }
10937
10938    public ContentProviderHolder getContentProviderExternal(
10939            String name, int userId, IBinder token) {
10940        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10941            "Do not have permission in call getContentProviderExternal()");
10942        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10943                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10944        return getContentProviderExternalUnchecked(name, token, userId);
10945    }
10946
10947    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10948            IBinder token, int userId) {
10949        return getContentProviderImpl(null, name, token, true, userId);
10950    }
10951
10952    /**
10953     * Drop a content provider from a ProcessRecord's bookkeeping
10954     */
10955    public void removeContentProvider(IBinder connection, boolean stable) {
10956        enforceNotIsolatedCaller("removeContentProvider");
10957        long ident = Binder.clearCallingIdentity();
10958        try {
10959            synchronized (this) {
10960                ContentProviderConnection conn;
10961                try {
10962                    conn = (ContentProviderConnection)connection;
10963                } catch (ClassCastException e) {
10964                    String msg ="removeContentProvider: " + connection
10965                            + " not a ContentProviderConnection";
10966                    Slog.w(TAG, msg);
10967                    throw new IllegalArgumentException(msg);
10968                }
10969                if (conn == null) {
10970                    throw new NullPointerException("connection is null");
10971                }
10972                if (decProviderCountLocked(conn, null, null, stable)) {
10973                    updateOomAdjLocked();
10974                }
10975            }
10976        } finally {
10977            Binder.restoreCallingIdentity(ident);
10978        }
10979    }
10980
10981    public void removeContentProviderExternal(String name, IBinder token) {
10982        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10983            "Do not have permission in call removeContentProviderExternal()");
10984        int userId = UserHandle.getCallingUserId();
10985        long ident = Binder.clearCallingIdentity();
10986        try {
10987            removeContentProviderExternalUnchecked(name, token, userId);
10988        } finally {
10989            Binder.restoreCallingIdentity(ident);
10990        }
10991    }
10992
10993    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10994        synchronized (this) {
10995            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10996            if(cpr == null) {
10997                //remove from mProvidersByClass
10998                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10999                return;
11000            }
11001
11002            //update content provider record entry info
11003            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11004            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11005            if (localCpr.hasExternalProcessHandles()) {
11006                if (localCpr.removeExternalProcessHandleLocked(token)) {
11007                    updateOomAdjLocked();
11008                } else {
11009                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11010                            + " with no external reference for token: "
11011                            + token + ".");
11012                }
11013            } else {
11014                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11015                        + " with no external references.");
11016            }
11017        }
11018    }
11019
11020    public final void publishContentProviders(IApplicationThread caller,
11021            List<ContentProviderHolder> providers) {
11022        if (providers == null) {
11023            return;
11024        }
11025
11026        enforceNotIsolatedCaller("publishContentProviders");
11027        synchronized (this) {
11028            final ProcessRecord r = getRecordForAppLocked(caller);
11029            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11030            if (r == null) {
11031                throw new SecurityException(
11032                        "Unable to find app for caller " + caller
11033                      + " (pid=" + Binder.getCallingPid()
11034                      + ") when publishing content providers");
11035            }
11036
11037            final long origId = Binder.clearCallingIdentity();
11038
11039            final int N = providers.size();
11040            for (int i = 0; i < N; i++) {
11041                ContentProviderHolder src = providers.get(i);
11042                if (src == null || src.info == null || src.provider == null) {
11043                    continue;
11044                }
11045                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11046                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11047                if (dst != null) {
11048                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11049                    mProviderMap.putProviderByClass(comp, dst);
11050                    String names[] = dst.info.authority.split(";");
11051                    for (int j = 0; j < names.length; j++) {
11052                        mProviderMap.putProviderByName(names[j], dst);
11053                    }
11054
11055                    int launchingCount = mLaunchingProviders.size();
11056                    int j;
11057                    boolean wasInLaunchingProviders = false;
11058                    for (j = 0; j < launchingCount; j++) {
11059                        if (mLaunchingProviders.get(j) == dst) {
11060                            mLaunchingProviders.remove(j);
11061                            wasInLaunchingProviders = true;
11062                            j--;
11063                            launchingCount--;
11064                        }
11065                    }
11066                    if (wasInLaunchingProviders) {
11067                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11068                    }
11069                    synchronized (dst) {
11070                        dst.provider = src.provider;
11071                        dst.proc = r;
11072                        dst.notifyAll();
11073                    }
11074                    updateOomAdjLocked(r);
11075                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11076                            src.info.authority);
11077                }
11078            }
11079
11080            Binder.restoreCallingIdentity(origId);
11081        }
11082    }
11083
11084    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11085        ContentProviderConnection conn;
11086        try {
11087            conn = (ContentProviderConnection)connection;
11088        } catch (ClassCastException e) {
11089            String msg ="refContentProvider: " + connection
11090                    + " not a ContentProviderConnection";
11091            Slog.w(TAG, msg);
11092            throw new IllegalArgumentException(msg);
11093        }
11094        if (conn == null) {
11095            throw new NullPointerException("connection is null");
11096        }
11097
11098        synchronized (this) {
11099            if (stable > 0) {
11100                conn.numStableIncs += stable;
11101            }
11102            stable = conn.stableCount + stable;
11103            if (stable < 0) {
11104                throw new IllegalStateException("stableCount < 0: " + stable);
11105            }
11106
11107            if (unstable > 0) {
11108                conn.numUnstableIncs += unstable;
11109            }
11110            unstable = conn.unstableCount + unstable;
11111            if (unstable < 0) {
11112                throw new IllegalStateException("unstableCount < 0: " + unstable);
11113            }
11114
11115            if ((stable+unstable) <= 0) {
11116                throw new IllegalStateException("ref counts can't go to zero here: stable="
11117                        + stable + " unstable=" + unstable);
11118            }
11119            conn.stableCount = stable;
11120            conn.unstableCount = unstable;
11121            return !conn.dead;
11122        }
11123    }
11124
11125    public void unstableProviderDied(IBinder connection) {
11126        ContentProviderConnection conn;
11127        try {
11128            conn = (ContentProviderConnection)connection;
11129        } catch (ClassCastException e) {
11130            String msg ="refContentProvider: " + connection
11131                    + " not a ContentProviderConnection";
11132            Slog.w(TAG, msg);
11133            throw new IllegalArgumentException(msg);
11134        }
11135        if (conn == null) {
11136            throw new NullPointerException("connection is null");
11137        }
11138
11139        // Safely retrieve the content provider associated with the connection.
11140        IContentProvider provider;
11141        synchronized (this) {
11142            provider = conn.provider.provider;
11143        }
11144
11145        if (provider == null) {
11146            // Um, yeah, we're way ahead of you.
11147            return;
11148        }
11149
11150        // Make sure the caller is being honest with us.
11151        if (provider.asBinder().pingBinder()) {
11152            // Er, no, still looks good to us.
11153            synchronized (this) {
11154                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11155                        + " says " + conn + " died, but we don't agree");
11156                return;
11157            }
11158        }
11159
11160        // Well look at that!  It's dead!
11161        synchronized (this) {
11162            if (conn.provider.provider != provider) {
11163                // But something changed...  good enough.
11164                return;
11165            }
11166
11167            ProcessRecord proc = conn.provider.proc;
11168            if (proc == null || proc.thread == null) {
11169                // Seems like the process is already cleaned up.
11170                return;
11171            }
11172
11173            // As far as we're concerned, this is just like receiving a
11174            // death notification...  just a bit prematurely.
11175            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11176                    + ") early provider death");
11177            final long ident = Binder.clearCallingIdentity();
11178            try {
11179                appDiedLocked(proc);
11180            } finally {
11181                Binder.restoreCallingIdentity(ident);
11182            }
11183        }
11184    }
11185
11186    @Override
11187    public void appNotRespondingViaProvider(IBinder connection) {
11188        enforceCallingPermission(
11189                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11190
11191        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11192        if (conn == null) {
11193            Slog.w(TAG, "ContentProviderConnection is null");
11194            return;
11195        }
11196
11197        final ProcessRecord host = conn.provider.proc;
11198        if (host == null) {
11199            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11200            return;
11201        }
11202
11203        mHandler.post(new Runnable() {
11204            @Override
11205            public void run() {
11206                mAppErrors.appNotResponding(host, null, null, false,
11207                        "ContentProvider not responding");
11208            }
11209        });
11210    }
11211
11212    public final void installSystemProviders() {
11213        List<ProviderInfo> providers;
11214        synchronized (this) {
11215            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11216            providers = generateApplicationProvidersLocked(app);
11217            if (providers != null) {
11218                for (int i=providers.size()-1; i>=0; i--) {
11219                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11220                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11221                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11222                                + ": not system .apk");
11223                        providers.remove(i);
11224                    }
11225                }
11226            }
11227        }
11228        if (providers != null) {
11229            mSystemThread.installSystemProviders(providers);
11230        }
11231
11232        mCoreSettingsObserver = new CoreSettingsObserver(this);
11233        mFontScaleSettingObserver = new FontScaleSettingObserver();
11234
11235        //mUsageStatsService.monitorPackages();
11236    }
11237
11238    private void startPersistentApps(int matchFlags) {
11239        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11240
11241        synchronized (this) {
11242            try {
11243                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11244                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11245                for (ApplicationInfo app : apps) {
11246                    if (!"android".equals(app.packageName)) {
11247                        addAppLocked(app, false, null /* ABI override */);
11248                    }
11249                }
11250            } catch (RemoteException ex) {
11251            }
11252        }
11253    }
11254
11255    /**
11256     * When a user is unlocked, we need to install encryption-unaware providers
11257     * belonging to any running apps.
11258     */
11259    private void installEncryptionUnawareProviders(int userId) {
11260        // We're only interested in providers that are encryption unaware, and
11261        // we don't care about uninstalled apps, since there's no way they're
11262        // running at this point.
11263        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11264
11265        synchronized (this) {
11266            final int NP = mProcessNames.getMap().size();
11267            for (int ip = 0; ip < NP; ip++) {
11268                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11269                final int NA = apps.size();
11270                for (int ia = 0; ia < NA; ia++) {
11271                    final ProcessRecord app = apps.valueAt(ia);
11272                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11273
11274                    final int NG = app.pkgList.size();
11275                    for (int ig = 0; ig < NG; ig++) {
11276                        try {
11277                            final String pkgName = app.pkgList.keyAt(ig);
11278                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11279                                    .getPackageInfo(pkgName, matchFlags, userId);
11280                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11281                                for (ProviderInfo pi : pkgInfo.providers) {
11282                                    // TODO: keep in sync with generateApplicationProvidersLocked
11283                                    final boolean processMatch = Objects.equals(pi.processName,
11284                                            app.processName) || pi.multiprocess;
11285                                    final boolean userMatch = isSingleton(pi.processName,
11286                                            pi.applicationInfo, pi.name, pi.flags)
11287                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11288                                    if (processMatch && userMatch) {
11289                                        Log.v(TAG, "Installing " + pi);
11290                                        app.thread.scheduleInstallProvider(pi);
11291                                    } else {
11292                                        Log.v(TAG, "Skipping " + pi);
11293                                    }
11294                                }
11295                            }
11296                        } catch (RemoteException ignored) {
11297                        }
11298                    }
11299                }
11300            }
11301        }
11302    }
11303
11304    /**
11305     * Allows apps to retrieve the MIME type of a URI.
11306     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11307     * users, then it does not need permission to access the ContentProvider.
11308     * Either, it needs cross-user uri grants.
11309     *
11310     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11311     *
11312     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11313     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11314     */
11315    public String getProviderMimeType(Uri uri, int userId) {
11316        enforceNotIsolatedCaller("getProviderMimeType");
11317        final String name = uri.getAuthority();
11318        int callingUid = Binder.getCallingUid();
11319        int callingPid = Binder.getCallingPid();
11320        long ident = 0;
11321        boolean clearedIdentity = false;
11322        synchronized (this) {
11323            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11324        }
11325        if (canClearIdentity(callingPid, callingUid, userId)) {
11326            clearedIdentity = true;
11327            ident = Binder.clearCallingIdentity();
11328        }
11329        ContentProviderHolder holder = null;
11330        try {
11331            holder = getContentProviderExternalUnchecked(name, null, userId);
11332            if (holder != null) {
11333                return holder.provider.getType(uri);
11334            }
11335        } catch (RemoteException e) {
11336            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11337            return null;
11338        } catch (Exception e) {
11339            Log.w(TAG, "Exception while determining type of " + uri, e);
11340            return null;
11341        } finally {
11342            // We need to clear the identity to call removeContentProviderExternalUnchecked
11343            if (!clearedIdentity) {
11344                ident = Binder.clearCallingIdentity();
11345            }
11346            try {
11347                if (holder != null) {
11348                    removeContentProviderExternalUnchecked(name, null, userId);
11349                }
11350            } finally {
11351                Binder.restoreCallingIdentity(ident);
11352            }
11353        }
11354
11355        return null;
11356    }
11357
11358    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11359        if (UserHandle.getUserId(callingUid) == userId) {
11360            return true;
11361        }
11362        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11363                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11364                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11365                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11366                return true;
11367        }
11368        return false;
11369    }
11370
11371    // =========================================================
11372    // GLOBAL MANAGEMENT
11373    // =========================================================
11374
11375    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11376            boolean isolated, int isolatedUid) {
11377        String proc = customProcess != null ? customProcess : info.processName;
11378        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11379        final int userId = UserHandle.getUserId(info.uid);
11380        int uid = info.uid;
11381        if (isolated) {
11382            if (isolatedUid == 0) {
11383                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11384                while (true) {
11385                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11386                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11387                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11388                    }
11389                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11390                    mNextIsolatedProcessUid++;
11391                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11392                        // No process for this uid, use it.
11393                        break;
11394                    }
11395                    stepsLeft--;
11396                    if (stepsLeft <= 0) {
11397                        return null;
11398                    }
11399                }
11400            } else {
11401                // Special case for startIsolatedProcess (internal only), where
11402                // the uid of the isolated process is specified by the caller.
11403                uid = isolatedUid;
11404            }
11405        }
11406        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11407        if (!mBooted && !mBooting
11408                && userId == UserHandle.USER_SYSTEM
11409                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11410            r.persistent = true;
11411        }
11412        addProcessNameLocked(r);
11413        return r;
11414    }
11415
11416    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11417            String abiOverride) {
11418        ProcessRecord app;
11419        if (!isolated) {
11420            app = getProcessRecordLocked(info.processName, info.uid, true);
11421        } else {
11422            app = null;
11423        }
11424
11425        if (app == null) {
11426            app = newProcessRecordLocked(info, null, isolated, 0);
11427            updateLruProcessLocked(app, false, null);
11428            updateOomAdjLocked();
11429        }
11430
11431        // This package really, really can not be stopped.
11432        try {
11433            AppGlobals.getPackageManager().setPackageStoppedState(
11434                    info.packageName, false, UserHandle.getUserId(app.uid));
11435        } catch (RemoteException e) {
11436        } catch (IllegalArgumentException e) {
11437            Slog.w(TAG, "Failed trying to unstop package "
11438                    + info.packageName + ": " + e);
11439        }
11440
11441        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11442            app.persistent = true;
11443            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11444        }
11445        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11446            mPersistentStartingProcesses.add(app);
11447            startProcessLocked(app, "added application", app.processName, abiOverride,
11448                    null /* entryPoint */, null /* entryPointArgs */);
11449        }
11450
11451        return app;
11452    }
11453
11454    public void unhandledBack() {
11455        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11456                "unhandledBack()");
11457
11458        synchronized(this) {
11459            final long origId = Binder.clearCallingIdentity();
11460            try {
11461                getFocusedStack().unhandledBackLocked();
11462            } finally {
11463                Binder.restoreCallingIdentity(origId);
11464            }
11465        }
11466    }
11467
11468    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11469        enforceNotIsolatedCaller("openContentUri");
11470        final int userId = UserHandle.getCallingUserId();
11471        String name = uri.getAuthority();
11472        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11473        ParcelFileDescriptor pfd = null;
11474        if (cph != null) {
11475            // We record the binder invoker's uid in thread-local storage before
11476            // going to the content provider to open the file.  Later, in the code
11477            // that handles all permissions checks, we look for this uid and use
11478            // that rather than the Activity Manager's own uid.  The effect is that
11479            // we do the check against the caller's permissions even though it looks
11480            // to the content provider like the Activity Manager itself is making
11481            // the request.
11482            Binder token = new Binder();
11483            sCallerIdentity.set(new Identity(
11484                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11485            try {
11486                pfd = cph.provider.openFile(null, uri, "r", null, token);
11487            } catch (FileNotFoundException e) {
11488                // do nothing; pfd will be returned null
11489            } finally {
11490                // Ensure that whatever happens, we clean up the identity state
11491                sCallerIdentity.remove();
11492                // Ensure we're done with the provider.
11493                removeContentProviderExternalUnchecked(name, null, userId);
11494            }
11495        } else {
11496            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11497        }
11498        return pfd;
11499    }
11500
11501    // Actually is sleeping or shutting down or whatever else in the future
11502    // is an inactive state.
11503    boolean isSleepingOrShuttingDownLocked() {
11504        return isSleepingLocked() || mShuttingDown;
11505    }
11506
11507    boolean isShuttingDownLocked() {
11508        return mShuttingDown;
11509    }
11510
11511    boolean isSleepingLocked() {
11512        return mSleeping;
11513    }
11514
11515    void onWakefulnessChanged(int wakefulness) {
11516        synchronized(this) {
11517            mWakefulness = wakefulness;
11518            updateSleepIfNeededLocked();
11519        }
11520    }
11521
11522    void finishRunningVoiceLocked() {
11523        if (mRunningVoice != null) {
11524            mRunningVoice = null;
11525            mVoiceWakeLock.release();
11526            updateSleepIfNeededLocked();
11527        }
11528    }
11529
11530    void startTimeTrackingFocusedActivityLocked() {
11531        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11532            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11533        }
11534    }
11535
11536    void updateSleepIfNeededLocked() {
11537        if (mSleeping && !shouldSleepLocked()) {
11538            mSleeping = false;
11539            startTimeTrackingFocusedActivityLocked();
11540            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11541            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11542            updateOomAdjLocked();
11543        } else if (!mSleeping && shouldSleepLocked()) {
11544            mSleeping = true;
11545            if (mCurAppTimeTracker != null) {
11546                mCurAppTimeTracker.stop();
11547            }
11548            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11549            mStackSupervisor.goingToSleepLocked();
11550            updateOomAdjLocked();
11551
11552            // Initialize the wake times of all processes.
11553            checkExcessivePowerUsageLocked(false);
11554            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11555            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11556            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11557        }
11558    }
11559
11560    private boolean shouldSleepLocked() {
11561        // Resume applications while running a voice interactor.
11562        if (mRunningVoice != null) {
11563            return false;
11564        }
11565
11566        // TODO: Transform the lock screen state into a sleep token instead.
11567        switch (mWakefulness) {
11568            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11569            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11570            case PowerManagerInternal.WAKEFULNESS_DOZING:
11571                // Pause applications whenever the lock screen is shown or any sleep
11572                // tokens have been acquired.
11573                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11574            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11575            default:
11576                // If we're asleep then pause applications unconditionally.
11577                return true;
11578        }
11579    }
11580
11581    /** Pokes the task persister. */
11582    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11583        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11584    }
11585
11586    /** Notifies all listeners when the task stack has changed. */
11587    void notifyTaskStackChangedLocked() {
11588        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11589        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11590        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11591        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11592    }
11593
11594    /** Notifies all listeners when an Activity is pinned. */
11595    void notifyActivityPinnedLocked() {
11596        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11597        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11598    }
11599
11600    /**
11601     * Notifies all listeners when an attempt was made to start an an activity that is already
11602     * running in the pinned stack and the activity was not actually started, but the task is
11603     * either brought to the front or a new Intent is delivered to it.
11604     */
11605    void notifyPinnedActivityRestartAttemptLocked() {
11606        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11607        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11608    }
11609
11610    /** Notifies all listeners when the pinned stack animation ends. */
11611    @Override
11612    public void notifyPinnedStackAnimationEnded() {
11613        synchronized (this) {
11614            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11615            mHandler.obtainMessage(
11616                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11617        }
11618    }
11619
11620    @Override
11621    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11622        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11623    }
11624
11625    @Override
11626    public boolean shutdown(int timeout) {
11627        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11628                != PackageManager.PERMISSION_GRANTED) {
11629            throw new SecurityException("Requires permission "
11630                    + android.Manifest.permission.SHUTDOWN);
11631        }
11632
11633        boolean timedout = false;
11634
11635        synchronized(this) {
11636            mShuttingDown = true;
11637            updateEventDispatchingLocked();
11638            timedout = mStackSupervisor.shutdownLocked(timeout);
11639        }
11640
11641        mAppOpsService.shutdown();
11642        if (mUsageStatsService != null) {
11643            mUsageStatsService.prepareShutdown();
11644        }
11645        mBatteryStatsService.shutdown();
11646        synchronized (this) {
11647            mProcessStats.shutdownLocked();
11648            notifyTaskPersisterLocked(null, true);
11649        }
11650
11651        return timedout;
11652    }
11653
11654    public final void activitySlept(IBinder token) {
11655        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11656
11657        final long origId = Binder.clearCallingIdentity();
11658
11659        synchronized (this) {
11660            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11661            if (r != null) {
11662                mStackSupervisor.activitySleptLocked(r);
11663            }
11664        }
11665
11666        Binder.restoreCallingIdentity(origId);
11667    }
11668
11669    private String lockScreenShownToString() {
11670        switch (mLockScreenShown) {
11671            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11672            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11673            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11674            default: return "Unknown=" + mLockScreenShown;
11675        }
11676    }
11677
11678    void logLockScreen(String msg) {
11679        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11680                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11681                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11682                + " mSleeping=" + mSleeping);
11683    }
11684
11685    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11686        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11687        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11688        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11689            boolean wasRunningVoice = mRunningVoice != null;
11690            mRunningVoice = session;
11691            if (!wasRunningVoice) {
11692                mVoiceWakeLock.acquire();
11693                updateSleepIfNeededLocked();
11694            }
11695        }
11696    }
11697
11698    private void updateEventDispatchingLocked() {
11699        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11700    }
11701
11702    public void setLockScreenShown(boolean showing, boolean occluded) {
11703        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11704                != PackageManager.PERMISSION_GRANTED) {
11705            throw new SecurityException("Requires permission "
11706                    + android.Manifest.permission.DEVICE_POWER);
11707        }
11708
11709        synchronized(this) {
11710            long ident = Binder.clearCallingIdentity();
11711            try {
11712                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11713                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11714                if (showing && occluded) {
11715                    // The lock screen is currently showing, but is occluded by a window that can
11716                    // show on top of the lock screen. In this can we want to dismiss the docked
11717                    // stack since it will be complicated/risky to try to put the activity on top
11718                    // of the lock screen in the right fullscreen configuration.
11719                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11720                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11721                }
11722
11723                updateSleepIfNeededLocked();
11724            } finally {
11725                Binder.restoreCallingIdentity(ident);
11726            }
11727        }
11728    }
11729
11730    @Override
11731    public void notifyLockedProfile(@UserIdInt int userId) {
11732        try {
11733            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11734                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11735            }
11736        } catch (RemoteException ex) {
11737            throw new SecurityException("Fail to check is caller a privileged app", ex);
11738        }
11739
11740        synchronized (this) {
11741            if (mStackSupervisor.isUserLockedProfile(userId)) {
11742                final long ident = Binder.clearCallingIdentity();
11743                try {
11744                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11745                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11746                        // If there is no device lock, we will show the profile's credential page.
11747                        mActivityStarter.showConfirmDeviceCredential(userId);
11748                    } else {
11749                        // Showing launcher to avoid user entering credential twice.
11750                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11751                    }
11752                } finally {
11753                    Binder.restoreCallingIdentity(ident);
11754                }
11755            }
11756        }
11757    }
11758
11759    @Override
11760    public void startConfirmDeviceCredentialIntent(Intent intent) {
11761        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11762        synchronized (this) {
11763            final long ident = Binder.clearCallingIdentity();
11764            try {
11765                mActivityStarter.startConfirmCredentialIntent(intent);
11766            } finally {
11767                Binder.restoreCallingIdentity(ident);
11768            }
11769        }
11770    }
11771
11772    @Override
11773    public void stopAppSwitches() {
11774        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11775                != PackageManager.PERMISSION_GRANTED) {
11776            throw new SecurityException("viewquires permission "
11777                    + android.Manifest.permission.STOP_APP_SWITCHES);
11778        }
11779
11780        synchronized(this) {
11781            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11782                    + APP_SWITCH_DELAY_TIME;
11783            mDidAppSwitch = false;
11784            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11785            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11786            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11787        }
11788    }
11789
11790    public void resumeAppSwitches() {
11791        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11792                != PackageManager.PERMISSION_GRANTED) {
11793            throw new SecurityException("Requires permission "
11794                    + android.Manifest.permission.STOP_APP_SWITCHES);
11795        }
11796
11797        synchronized(this) {
11798            // Note that we don't execute any pending app switches... we will
11799            // let those wait until either the timeout, or the next start
11800            // activity request.
11801            mAppSwitchesAllowedTime = 0;
11802        }
11803    }
11804
11805    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11806            int callingPid, int callingUid, String name) {
11807        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11808            return true;
11809        }
11810
11811        int perm = checkComponentPermission(
11812                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11813                sourceUid, -1, true);
11814        if (perm == PackageManager.PERMISSION_GRANTED) {
11815            return true;
11816        }
11817
11818        // If the actual IPC caller is different from the logical source, then
11819        // also see if they are allowed to control app switches.
11820        if (callingUid != -1 && callingUid != sourceUid) {
11821            perm = checkComponentPermission(
11822                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11823                    callingUid, -1, true);
11824            if (perm == PackageManager.PERMISSION_GRANTED) {
11825                return true;
11826            }
11827        }
11828
11829        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11830        return false;
11831    }
11832
11833    public void setDebugApp(String packageName, boolean waitForDebugger,
11834            boolean persistent) {
11835        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11836                "setDebugApp()");
11837
11838        long ident = Binder.clearCallingIdentity();
11839        try {
11840            // Note that this is not really thread safe if there are multiple
11841            // callers into it at the same time, but that's not a situation we
11842            // care about.
11843            if (persistent) {
11844                final ContentResolver resolver = mContext.getContentResolver();
11845                Settings.Global.putString(
11846                    resolver, Settings.Global.DEBUG_APP,
11847                    packageName);
11848                Settings.Global.putInt(
11849                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11850                    waitForDebugger ? 1 : 0);
11851            }
11852
11853            synchronized (this) {
11854                if (!persistent) {
11855                    mOrigDebugApp = mDebugApp;
11856                    mOrigWaitForDebugger = mWaitForDebugger;
11857                }
11858                mDebugApp = packageName;
11859                mWaitForDebugger = waitForDebugger;
11860                mDebugTransient = !persistent;
11861                if (packageName != null) {
11862                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11863                            false, UserHandle.USER_ALL, "set debug app");
11864                }
11865            }
11866        } finally {
11867            Binder.restoreCallingIdentity(ident);
11868        }
11869    }
11870
11871    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11872        synchronized (this) {
11873            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11874            if (!isDebuggable) {
11875                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11876                    throw new SecurityException("Process not debuggable: " + app.packageName);
11877                }
11878            }
11879
11880            mTrackAllocationApp = processName;
11881        }
11882    }
11883
11884    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11885        synchronized (this) {
11886            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11887            if (!isDebuggable) {
11888                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11889                    throw new SecurityException("Process not debuggable: " + app.packageName);
11890                }
11891            }
11892            mProfileApp = processName;
11893            mProfileFile = profilerInfo.profileFile;
11894            if (mProfileFd != null) {
11895                try {
11896                    mProfileFd.close();
11897                } catch (IOException e) {
11898                }
11899                mProfileFd = null;
11900            }
11901            mProfileFd = profilerInfo.profileFd;
11902            mSamplingInterval = profilerInfo.samplingInterval;
11903            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11904            mProfileType = 0;
11905        }
11906    }
11907
11908    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11909        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11910        if (!isDebuggable) {
11911            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11912                throw new SecurityException("Process not debuggable: " + app.packageName);
11913            }
11914        }
11915        mNativeDebuggingApp = processName;
11916    }
11917
11918    @Override
11919    public void setAlwaysFinish(boolean enabled) {
11920        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11921                "setAlwaysFinish()");
11922
11923        long ident = Binder.clearCallingIdentity();
11924        try {
11925            Settings.Global.putInt(
11926                    mContext.getContentResolver(),
11927                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11928
11929            synchronized (this) {
11930                mAlwaysFinishActivities = enabled;
11931            }
11932        } finally {
11933            Binder.restoreCallingIdentity(ident);
11934        }
11935    }
11936
11937    @Override
11938    public void setLenientBackgroundCheck(boolean enabled) {
11939        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11940                "setLenientBackgroundCheck()");
11941
11942        long ident = Binder.clearCallingIdentity();
11943        try {
11944            Settings.Global.putInt(
11945                    mContext.getContentResolver(),
11946                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11947
11948            synchronized (this) {
11949                mLenientBackgroundCheck = enabled;
11950            }
11951        } finally {
11952            Binder.restoreCallingIdentity(ident);
11953        }
11954    }
11955
11956    @Override
11957    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11958        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11959                "setActivityController()");
11960        synchronized (this) {
11961            mController = controller;
11962            mControllerIsAMonkey = imAMonkey;
11963            Watchdog.getInstance().setActivityController(controller);
11964        }
11965    }
11966
11967    @Override
11968    public void setUserIsMonkey(boolean userIsMonkey) {
11969        synchronized (this) {
11970            synchronized (mPidsSelfLocked) {
11971                final int callingPid = Binder.getCallingPid();
11972                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11973                if (precessRecord == null) {
11974                    throw new SecurityException("Unknown process: " + callingPid);
11975                }
11976                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11977                    throw new SecurityException("Only an instrumentation process "
11978                            + "with a UiAutomation can call setUserIsMonkey");
11979                }
11980            }
11981            mUserIsMonkey = userIsMonkey;
11982        }
11983    }
11984
11985    @Override
11986    public boolean isUserAMonkey() {
11987        synchronized (this) {
11988            // If there is a controller also implies the user is a monkey.
11989            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11990        }
11991    }
11992
11993    public void requestBugReport(int bugreportType) {
11994        String service = null;
11995        switch (bugreportType) {
11996            case ActivityManager.BUGREPORT_OPTION_FULL:
11997                service = "bugreport";
11998                break;
11999            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12000                service = "bugreportplus";
12001                break;
12002            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12003                service = "bugreportremote";
12004                break;
12005        }
12006        if (service == null) {
12007            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12008                    + bugreportType);
12009        }
12010        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12011        SystemProperties.set("ctl.start", service);
12012    }
12013
12014    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12015        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12016    }
12017
12018    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12019        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12020            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12021        }
12022        return KEY_DISPATCHING_TIMEOUT;
12023    }
12024
12025    @Override
12026    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12027        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12028                != PackageManager.PERMISSION_GRANTED) {
12029            throw new SecurityException("Requires permission "
12030                    + android.Manifest.permission.FILTER_EVENTS);
12031        }
12032        ProcessRecord proc;
12033        long timeout;
12034        synchronized (this) {
12035            synchronized (mPidsSelfLocked) {
12036                proc = mPidsSelfLocked.get(pid);
12037            }
12038            timeout = getInputDispatchingTimeoutLocked(proc);
12039        }
12040
12041        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12042            return -1;
12043        }
12044
12045        return timeout;
12046    }
12047
12048    /**
12049     * Handle input dispatching timeouts.
12050     * Returns whether input dispatching should be aborted or not.
12051     */
12052    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12053            final ActivityRecord activity, final ActivityRecord parent,
12054            final boolean aboveSystem, String reason) {
12055        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12056                != PackageManager.PERMISSION_GRANTED) {
12057            throw new SecurityException("Requires permission "
12058                    + android.Manifest.permission.FILTER_EVENTS);
12059        }
12060
12061        final String annotation;
12062        if (reason == null) {
12063            annotation = "Input dispatching timed out";
12064        } else {
12065            annotation = "Input dispatching timed out (" + reason + ")";
12066        }
12067
12068        if (proc != null) {
12069            synchronized (this) {
12070                if (proc.debugging) {
12071                    return false;
12072                }
12073
12074                if (mDidDexOpt) {
12075                    // Give more time since we were dexopting.
12076                    mDidDexOpt = false;
12077                    return false;
12078                }
12079
12080                if (proc.instrumentationClass != null) {
12081                    Bundle info = new Bundle();
12082                    info.putString("shortMsg", "keyDispatchingTimedOut");
12083                    info.putString("longMsg", annotation);
12084                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12085                    return true;
12086                }
12087            }
12088            mHandler.post(new Runnable() {
12089                @Override
12090                public void run() {
12091                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12092                }
12093            });
12094        }
12095
12096        return true;
12097    }
12098
12099    @Override
12100    public Bundle getAssistContextExtras(int requestType) {
12101        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12102                null, null, true /* focused */, true /* newSessionId */,
12103                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12104        if (pae == null) {
12105            return null;
12106        }
12107        synchronized (pae) {
12108            while (!pae.haveResult) {
12109                try {
12110                    pae.wait();
12111                } catch (InterruptedException e) {
12112                }
12113            }
12114        }
12115        synchronized (this) {
12116            buildAssistBundleLocked(pae, pae.result);
12117            mPendingAssistExtras.remove(pae);
12118            mUiHandler.removeCallbacks(pae);
12119        }
12120        return pae.extras;
12121    }
12122
12123    @Override
12124    public boolean isAssistDataAllowedOnCurrentActivity() {
12125        int userId;
12126        synchronized (this) {
12127            userId = mUserController.getCurrentUserIdLocked();
12128            ActivityRecord activity = getFocusedStack().topActivity();
12129            if (activity == null) {
12130                return false;
12131            }
12132            userId = activity.userId;
12133        }
12134        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12135                Context.DEVICE_POLICY_SERVICE);
12136        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12137    }
12138
12139    @Override
12140    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12141        long ident = Binder.clearCallingIdentity();
12142        try {
12143            synchronized (this) {
12144                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12145                ActivityRecord top = getFocusedStack().topActivity();
12146                if (top != caller) {
12147                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12148                            + " is not current top " + top);
12149                    return false;
12150                }
12151                if (!top.nowVisible) {
12152                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12153                            + " is not visible");
12154                    return false;
12155                }
12156            }
12157            AssistUtils utils = new AssistUtils(mContext);
12158            return utils.showSessionForActiveService(args,
12159                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12160        } finally {
12161            Binder.restoreCallingIdentity(ident);
12162        }
12163    }
12164
12165    @Override
12166    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12167            Bundle receiverExtras,
12168            IBinder activityToken, boolean focused, boolean newSessionId) {
12169        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12170                activityToken, focused, newSessionId,
12171                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12172                != null;
12173    }
12174
12175    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12176            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12177            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12178        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12179                "enqueueAssistContext()");
12180        synchronized (this) {
12181            ActivityRecord activity = getFocusedStack().topActivity();
12182            if (activity == null) {
12183                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12184                return null;
12185            }
12186            if (activity.app == null || activity.app.thread == null) {
12187                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12188                return null;
12189            }
12190            if (focused) {
12191                if (activityToken != null) {
12192                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12193                    if (activity != caller) {
12194                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12195                                + " is not current top " + activity);
12196                        return null;
12197                    }
12198                }
12199            } else {
12200                activity = ActivityRecord.forTokenLocked(activityToken);
12201                if (activity == null) {
12202                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12203                            + " couldn't be found");
12204                    return null;
12205                }
12206            }
12207
12208            PendingAssistExtras pae;
12209            Bundle extras = new Bundle();
12210            if (args != null) {
12211                extras.putAll(args);
12212            }
12213            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12214            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12215            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12216                    userHandle);
12217            // Increment the sessionId if necessary
12218            if (newSessionId) {
12219                mViSessionId++;
12220            }
12221            try {
12222                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12223                        requestType, mViSessionId);
12224                mPendingAssistExtras.add(pae);
12225                mUiHandler.postDelayed(pae, timeout);
12226            } catch (RemoteException e) {
12227                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12228                return null;
12229            }
12230            return pae;
12231        }
12232    }
12233
12234    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12235        IResultReceiver receiver;
12236        synchronized (this) {
12237            mPendingAssistExtras.remove(pae);
12238            receiver = pae.receiver;
12239        }
12240        if (receiver != null) {
12241            // Caller wants result sent back to them.
12242            Bundle sendBundle = new Bundle();
12243            // At least return the receiver extras
12244            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12245                    pae.receiverExtras);
12246            try {
12247                pae.receiver.send(0, sendBundle);
12248            } catch (RemoteException e) {
12249            }
12250        }
12251    }
12252
12253    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12254        if (result != null) {
12255            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12256        }
12257        if (pae.hint != null) {
12258            pae.extras.putBoolean(pae.hint, true);
12259        }
12260    }
12261
12262    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12263            AssistContent content, Uri referrer) {
12264        PendingAssistExtras pae = (PendingAssistExtras)token;
12265        synchronized (pae) {
12266            pae.result = extras;
12267            pae.structure = structure;
12268            pae.content = content;
12269            if (referrer != null) {
12270                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12271            }
12272            pae.haveResult = true;
12273            pae.notifyAll();
12274            if (pae.intent == null && pae.receiver == null) {
12275                // Caller is just waiting for the result.
12276                return;
12277            }
12278        }
12279
12280        // We are now ready to launch the assist activity.
12281        IResultReceiver sendReceiver = null;
12282        Bundle sendBundle = null;
12283        synchronized (this) {
12284            buildAssistBundleLocked(pae, extras);
12285            boolean exists = mPendingAssistExtras.remove(pae);
12286            mUiHandler.removeCallbacks(pae);
12287            if (!exists) {
12288                // Timed out.
12289                return;
12290            }
12291            if ((sendReceiver=pae.receiver) != null) {
12292                // Caller wants result sent back to them.
12293                sendBundle = new Bundle();
12294                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12295                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12296                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12297                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12298                        pae.receiverExtras);
12299            }
12300        }
12301        if (sendReceiver != null) {
12302            try {
12303                sendReceiver.send(0, sendBundle);
12304            } catch (RemoteException e) {
12305            }
12306            return;
12307        }
12308
12309        long ident = Binder.clearCallingIdentity();
12310        try {
12311            pae.intent.replaceExtras(pae.extras);
12312            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12313                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12314                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12315            closeSystemDialogs("assist");
12316            try {
12317                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12318            } catch (ActivityNotFoundException e) {
12319                Slog.w(TAG, "No activity to handle assist action.", e);
12320            }
12321        } finally {
12322            Binder.restoreCallingIdentity(ident);
12323        }
12324    }
12325
12326    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12327            Bundle args) {
12328        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12329                true /* focused */, true /* newSessionId */,
12330                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12331    }
12332
12333    public void registerProcessObserver(IProcessObserver observer) {
12334        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12335                "registerProcessObserver()");
12336        synchronized (this) {
12337            mProcessObservers.register(observer);
12338        }
12339    }
12340
12341    @Override
12342    public void unregisterProcessObserver(IProcessObserver observer) {
12343        synchronized (this) {
12344            mProcessObservers.unregister(observer);
12345        }
12346    }
12347
12348    @Override
12349    public void registerUidObserver(IUidObserver observer, int which) {
12350        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12351                "registerUidObserver()");
12352        synchronized (this) {
12353            mUidObservers.register(observer, which);
12354        }
12355    }
12356
12357    @Override
12358    public void unregisterUidObserver(IUidObserver observer) {
12359        synchronized (this) {
12360            mUidObservers.unregister(observer);
12361        }
12362    }
12363
12364    @Override
12365    public boolean convertFromTranslucent(IBinder token) {
12366        final long origId = Binder.clearCallingIdentity();
12367        try {
12368            synchronized (this) {
12369                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12370                if (r == null) {
12371                    return false;
12372                }
12373                final boolean translucentChanged = r.changeWindowTranslucency(true);
12374                if (translucentChanged) {
12375                    r.task.stack.releaseBackgroundResources(r);
12376                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12377                }
12378                mWindowManager.setAppFullscreen(token, true);
12379                return translucentChanged;
12380            }
12381        } finally {
12382            Binder.restoreCallingIdentity(origId);
12383        }
12384    }
12385
12386    @Override
12387    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12388        final long origId = Binder.clearCallingIdentity();
12389        try {
12390            synchronized (this) {
12391                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12392                if (r == null) {
12393                    return false;
12394                }
12395                int index = r.task.mActivities.lastIndexOf(r);
12396                if (index > 0) {
12397                    ActivityRecord under = r.task.mActivities.get(index - 1);
12398                    under.returningOptions = options;
12399                }
12400                final boolean translucentChanged = r.changeWindowTranslucency(false);
12401                if (translucentChanged) {
12402                    r.task.stack.convertActivityToTranslucent(r);
12403                }
12404                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12405                mWindowManager.setAppFullscreen(token, false);
12406                return translucentChanged;
12407            }
12408        } finally {
12409            Binder.restoreCallingIdentity(origId);
12410        }
12411    }
12412
12413    @Override
12414    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12415        final long origId = Binder.clearCallingIdentity();
12416        try {
12417            synchronized (this) {
12418                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12419                if (r != null) {
12420                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12421                }
12422            }
12423            return false;
12424        } finally {
12425            Binder.restoreCallingIdentity(origId);
12426        }
12427    }
12428
12429    @Override
12430    public boolean isBackgroundVisibleBehind(IBinder token) {
12431        final long origId = Binder.clearCallingIdentity();
12432        try {
12433            synchronized (this) {
12434                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12435                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12436                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12437                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12438                return visible;
12439            }
12440        } finally {
12441            Binder.restoreCallingIdentity(origId);
12442        }
12443    }
12444
12445    @Override
12446    public ActivityOptions getActivityOptions(IBinder token) {
12447        final long origId = Binder.clearCallingIdentity();
12448        try {
12449            synchronized (this) {
12450                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12451                if (r != null) {
12452                    final ActivityOptions activityOptions = r.pendingOptions;
12453                    r.pendingOptions = null;
12454                    return activityOptions;
12455                }
12456                return null;
12457            }
12458        } finally {
12459            Binder.restoreCallingIdentity(origId);
12460        }
12461    }
12462
12463    @Override
12464    public void setImmersive(IBinder token, boolean immersive) {
12465        synchronized(this) {
12466            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12467            if (r == null) {
12468                throw new IllegalArgumentException();
12469            }
12470            r.immersive = immersive;
12471
12472            // update associated state if we're frontmost
12473            if (r == mFocusedActivity) {
12474                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12475                applyUpdateLockStateLocked(r);
12476            }
12477        }
12478    }
12479
12480    @Override
12481    public boolean isImmersive(IBinder token) {
12482        synchronized (this) {
12483            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12484            if (r == null) {
12485                throw new IllegalArgumentException();
12486            }
12487            return r.immersive;
12488        }
12489    }
12490
12491    @Override
12492    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12493        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12494            throw new UnsupportedOperationException("VR mode not supported on this device!");
12495        }
12496
12497        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12498
12499        ActivityRecord r;
12500        synchronized (this) {
12501            r = ActivityRecord.isInStackLocked(token);
12502        }
12503
12504        if (r == null) {
12505            throw new IllegalArgumentException();
12506        }
12507
12508        int err;
12509        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12510                VrManagerInternal.NO_ERROR) {
12511            return err;
12512        }
12513
12514        synchronized(this) {
12515            r.requestedVrComponent = (enabled) ? packageName : null;
12516
12517            // Update associated state if this activity is currently focused
12518            if (r == mFocusedActivity) {
12519                applyUpdateVrModeLocked(r);
12520            }
12521            return 0;
12522        }
12523    }
12524
12525    @Override
12526    public boolean isVrModePackageEnabled(ComponentName packageName) {
12527        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12528            throw new UnsupportedOperationException("VR mode not supported on this device!");
12529        }
12530
12531        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12532
12533        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12534                VrManagerInternal.NO_ERROR;
12535    }
12536
12537    public boolean isTopActivityImmersive() {
12538        enforceNotIsolatedCaller("startActivity");
12539        synchronized (this) {
12540            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12541            return (r != null) ? r.immersive : false;
12542        }
12543    }
12544
12545    @Override
12546    public boolean isTopOfTask(IBinder token) {
12547        synchronized (this) {
12548            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12549            if (r == null) {
12550                throw new IllegalArgumentException();
12551            }
12552            return r.task.getTopActivity() == r;
12553        }
12554    }
12555
12556    public final void enterSafeMode() {
12557        synchronized(this) {
12558            // It only makes sense to do this before the system is ready
12559            // and started launching other packages.
12560            if (!mSystemReady) {
12561                try {
12562                    AppGlobals.getPackageManager().enterSafeMode();
12563                } catch (RemoteException e) {
12564                }
12565            }
12566
12567            mSafeMode = true;
12568        }
12569    }
12570
12571    public final void showSafeModeOverlay() {
12572        View v = LayoutInflater.from(mContext).inflate(
12573                com.android.internal.R.layout.safe_mode, null);
12574        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12575        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12576        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12577        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12578        lp.gravity = Gravity.BOTTOM | Gravity.START;
12579        lp.format = v.getBackground().getOpacity();
12580        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12581                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12582        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12583        ((WindowManager)mContext.getSystemService(
12584                Context.WINDOW_SERVICE)).addView(v, lp);
12585    }
12586
12587    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12588        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12589            return;
12590        }
12591        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12592        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12593        synchronized (stats) {
12594            if (mBatteryStatsService.isOnBattery()) {
12595                mBatteryStatsService.enforceCallingPermission();
12596                int MY_UID = Binder.getCallingUid();
12597                final int uid;
12598                if (sender == null) {
12599                    uid = sourceUid;
12600                } else {
12601                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12602                }
12603                BatteryStatsImpl.Uid.Pkg pkg =
12604                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12605                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12606                pkg.noteWakeupAlarmLocked(tag);
12607            }
12608        }
12609    }
12610
12611    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12612        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12613            return;
12614        }
12615        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12616        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12617        synchronized (stats) {
12618            mBatteryStatsService.enforceCallingPermission();
12619            int MY_UID = Binder.getCallingUid();
12620            final int uid;
12621            if (sender == null) {
12622                uid = sourceUid;
12623            } else {
12624                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12625            }
12626            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12627        }
12628    }
12629
12630    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12631        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12632            return;
12633        }
12634        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12635        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12636        synchronized (stats) {
12637            mBatteryStatsService.enforceCallingPermission();
12638            int MY_UID = Binder.getCallingUid();
12639            final int uid;
12640            if (sender == null) {
12641                uid = sourceUid;
12642            } else {
12643                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12644            }
12645            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12646        }
12647    }
12648
12649    public boolean killPids(int[] pids, String pReason, boolean secure) {
12650        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12651            throw new SecurityException("killPids only available to the system");
12652        }
12653        String reason = (pReason == null) ? "Unknown" : pReason;
12654        // XXX Note: don't acquire main activity lock here, because the window
12655        // manager calls in with its locks held.
12656
12657        boolean killed = false;
12658        synchronized (mPidsSelfLocked) {
12659            int worstType = 0;
12660            for (int i=0; i<pids.length; i++) {
12661                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12662                if (proc != null) {
12663                    int type = proc.setAdj;
12664                    if (type > worstType) {
12665                        worstType = type;
12666                    }
12667                }
12668            }
12669
12670            // If the worst oom_adj is somewhere in the cached proc LRU range,
12671            // then constrain it so we will kill all cached procs.
12672            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12673                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12674                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12675            }
12676
12677            // If this is not a secure call, don't let it kill processes that
12678            // are important.
12679            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12680                worstType = ProcessList.SERVICE_ADJ;
12681            }
12682
12683            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12684            for (int i=0; i<pids.length; i++) {
12685                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12686                if (proc == null) {
12687                    continue;
12688                }
12689                int adj = proc.setAdj;
12690                if (adj >= worstType && !proc.killedByAm) {
12691                    proc.kill(reason, true);
12692                    killed = true;
12693                }
12694            }
12695        }
12696        return killed;
12697    }
12698
12699    @Override
12700    public void killUid(int appId, int userId, String reason) {
12701        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12702        synchronized (this) {
12703            final long identity = Binder.clearCallingIdentity();
12704            try {
12705                killPackageProcessesLocked(null, appId, userId,
12706                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12707                        reason != null ? reason : "kill uid");
12708            } finally {
12709                Binder.restoreCallingIdentity(identity);
12710            }
12711        }
12712    }
12713
12714    @Override
12715    public boolean killProcessesBelowForeground(String reason) {
12716        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12717            throw new SecurityException("killProcessesBelowForeground() only available to system");
12718        }
12719
12720        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12721    }
12722
12723    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12724        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12725            throw new SecurityException("killProcessesBelowAdj() only available to system");
12726        }
12727
12728        boolean killed = false;
12729        synchronized (mPidsSelfLocked) {
12730            final int size = mPidsSelfLocked.size();
12731            for (int i = 0; i < size; i++) {
12732                final int pid = mPidsSelfLocked.keyAt(i);
12733                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12734                if (proc == null) continue;
12735
12736                final int adj = proc.setAdj;
12737                if (adj > belowAdj && !proc.killedByAm) {
12738                    proc.kill(reason, true);
12739                    killed = true;
12740                }
12741            }
12742        }
12743        return killed;
12744    }
12745
12746    @Override
12747    public void hang(final IBinder who, boolean allowRestart) {
12748        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12749                != PackageManager.PERMISSION_GRANTED) {
12750            throw new SecurityException("Requires permission "
12751                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12752        }
12753
12754        final IBinder.DeathRecipient death = new DeathRecipient() {
12755            @Override
12756            public void binderDied() {
12757                synchronized (this) {
12758                    notifyAll();
12759                }
12760            }
12761        };
12762
12763        try {
12764            who.linkToDeath(death, 0);
12765        } catch (RemoteException e) {
12766            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12767            return;
12768        }
12769
12770        synchronized (this) {
12771            Watchdog.getInstance().setAllowRestart(allowRestart);
12772            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12773            synchronized (death) {
12774                while (who.isBinderAlive()) {
12775                    try {
12776                        death.wait();
12777                    } catch (InterruptedException e) {
12778                    }
12779                }
12780            }
12781            Watchdog.getInstance().setAllowRestart(true);
12782        }
12783    }
12784
12785    @Override
12786    public void restart() {
12787        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12788                != PackageManager.PERMISSION_GRANTED) {
12789            throw new SecurityException("Requires permission "
12790                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12791        }
12792
12793        Log.i(TAG, "Sending shutdown broadcast...");
12794
12795        BroadcastReceiver br = new BroadcastReceiver() {
12796            @Override public void onReceive(Context context, Intent intent) {
12797                // Now the broadcast is done, finish up the low-level shutdown.
12798                Log.i(TAG, "Shutting down activity manager...");
12799                shutdown(10000);
12800                Log.i(TAG, "Shutdown complete, restarting!");
12801                Process.killProcess(Process.myPid());
12802                System.exit(10);
12803            }
12804        };
12805
12806        // First send the high-level shut down broadcast.
12807        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12808        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12809        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12810        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12811        mContext.sendOrderedBroadcastAsUser(intent,
12812                UserHandle.ALL, null, br, mHandler, 0, null, null);
12813        */
12814        br.onReceive(mContext, intent);
12815    }
12816
12817    private long getLowRamTimeSinceIdle(long now) {
12818        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12819    }
12820
12821    @Override
12822    public void performIdleMaintenance() {
12823        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12824                != PackageManager.PERMISSION_GRANTED) {
12825            throw new SecurityException("Requires permission "
12826                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12827        }
12828
12829        synchronized (this) {
12830            final long now = SystemClock.uptimeMillis();
12831            final long timeSinceLastIdle = now - mLastIdleTime;
12832            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12833            mLastIdleTime = now;
12834            mLowRamTimeSinceLastIdle = 0;
12835            if (mLowRamStartTime != 0) {
12836                mLowRamStartTime = now;
12837            }
12838
12839            StringBuilder sb = new StringBuilder(128);
12840            sb.append("Idle maintenance over ");
12841            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12842            sb.append(" low RAM for ");
12843            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12844            Slog.i(TAG, sb.toString());
12845
12846            // If at least 1/3 of our time since the last idle period has been spent
12847            // with RAM low, then we want to kill processes.
12848            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12849
12850            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12851                ProcessRecord proc = mLruProcesses.get(i);
12852                if (proc.notCachedSinceIdle) {
12853                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12854                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12855                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12856                        if (doKilling && proc.initialIdlePss != 0
12857                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12858                            sb = new StringBuilder(128);
12859                            sb.append("Kill");
12860                            sb.append(proc.processName);
12861                            sb.append(" in idle maint: pss=");
12862                            sb.append(proc.lastPss);
12863                            sb.append(", swapPss=");
12864                            sb.append(proc.lastSwapPss);
12865                            sb.append(", initialPss=");
12866                            sb.append(proc.initialIdlePss);
12867                            sb.append(", period=");
12868                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12869                            sb.append(", lowRamPeriod=");
12870                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12871                            Slog.wtfQuiet(TAG, sb.toString());
12872                            proc.kill("idle maint (pss " + proc.lastPss
12873                                    + " from " + proc.initialIdlePss + ")", true);
12874                        }
12875                    }
12876                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12877                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12878                    proc.notCachedSinceIdle = true;
12879                    proc.initialIdlePss = 0;
12880                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12881                            mTestPssMode, isSleepingLocked(), now);
12882                }
12883            }
12884
12885            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12886            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12887        }
12888    }
12889
12890    @Override
12891    public void sendIdleJobTrigger() {
12892        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12893                != PackageManager.PERMISSION_GRANTED) {
12894            throw new SecurityException("Requires permission "
12895                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12896        }
12897
12898        final long ident = Binder.clearCallingIdentity();
12899        try {
12900            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12901                    .setPackage("android")
12902                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12903            broadcastIntent(null, intent, null, null, 0, null, null, null,
12904                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12905        } finally {
12906            Binder.restoreCallingIdentity(ident);
12907        }
12908    }
12909
12910    private void retrieveSettings() {
12911        final ContentResolver resolver = mContext.getContentResolver();
12912        final boolean freeformWindowManagement =
12913                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12914                        || Settings.Global.getInt(
12915                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12916        final boolean supportsPictureInPicture =
12917                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12918
12919        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12920        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12921        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12922        final boolean alwaysFinishActivities =
12923                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12924        final boolean lenientBackgroundCheck =
12925                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12926        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12927        final boolean forceResizable = Settings.Global.getInt(
12928                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12929        final boolean supportsLeanbackOnly =
12930                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12931
12932        // Transfer any global setting for forcing RTL layout, into a System Property
12933        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12934
12935        final Configuration configuration = new Configuration();
12936        Settings.System.getConfiguration(resolver, configuration);
12937        if (forceRtl) {
12938            // This will take care of setting the correct layout direction flags
12939            configuration.setLayoutDirection(configuration.locale);
12940        }
12941
12942        synchronized (this) {
12943            mDebugApp = mOrigDebugApp = debugApp;
12944            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12945            mAlwaysFinishActivities = alwaysFinishActivities;
12946            mLenientBackgroundCheck = lenientBackgroundCheck;
12947            mSupportsLeanbackOnly = supportsLeanbackOnly;
12948            mForceResizableActivities = forceResizable;
12949            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12950            if (supportsMultiWindow || forceResizable) {
12951                mSupportsMultiWindow = true;
12952                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12953                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12954            } else {
12955                mSupportsMultiWindow = false;
12956                mSupportsFreeformWindowManagement = false;
12957                mSupportsPictureInPicture = false;
12958            }
12959            // This happens before any activities are started, so we can
12960            // change mConfiguration in-place.
12961            updateConfigurationLocked(configuration, null, true);
12962            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12963                    "Initial config: " + mConfiguration);
12964
12965            // Load resources only after the current configuration has been set.
12966            final Resources res = mContext.getResources();
12967            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12968            mThumbnailWidth = res.getDimensionPixelSize(
12969                    com.android.internal.R.dimen.thumbnail_width);
12970            mThumbnailHeight = res.getDimensionPixelSize(
12971                    com.android.internal.R.dimen.thumbnail_height);
12972            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12973                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12974            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12975                    com.android.internal.R.string.config_appsNotReportingCrashes));
12976            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12977                mFullscreenThumbnailScale = (float) res
12978                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12979                    (float) mConfiguration.screenWidthDp;
12980            } else {
12981                mFullscreenThumbnailScale = res.getFraction(
12982                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12983            }
12984        }
12985    }
12986
12987    public boolean testIsSystemReady() {
12988        // no need to synchronize(this) just to read & return the value
12989        return mSystemReady;
12990    }
12991
12992    public void systemReady(final Runnable goingCallback) {
12993        synchronized(this) {
12994            if (mSystemReady) {
12995                // If we're done calling all the receivers, run the next "boot phase" passed in
12996                // by the SystemServer
12997                if (goingCallback != null) {
12998                    goingCallback.run();
12999                }
13000                return;
13001            }
13002
13003            mLocalDeviceIdleController
13004                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13005
13006            // Make sure we have the current profile info, since it is needed for security checks.
13007            mUserController.onSystemReady();
13008            mRecentTasks.onSystemReadyLocked();
13009            mAppOpsService.systemReady();
13010            mSystemReady = true;
13011        }
13012
13013        ArrayList<ProcessRecord> procsToKill = null;
13014        synchronized(mPidsSelfLocked) {
13015            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13016                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13017                if (!isAllowedWhileBooting(proc.info)){
13018                    if (procsToKill == null) {
13019                        procsToKill = new ArrayList<ProcessRecord>();
13020                    }
13021                    procsToKill.add(proc);
13022                }
13023            }
13024        }
13025
13026        synchronized(this) {
13027            if (procsToKill != null) {
13028                for (int i=procsToKill.size()-1; i>=0; i--) {
13029                    ProcessRecord proc = procsToKill.get(i);
13030                    Slog.i(TAG, "Removing system update proc: " + proc);
13031                    removeProcessLocked(proc, true, false, "system update done");
13032                }
13033            }
13034
13035            // Now that we have cleaned up any update processes, we
13036            // are ready to start launching real processes and know that
13037            // we won't trample on them any more.
13038            mProcessesReady = true;
13039        }
13040
13041        Slog.i(TAG, "System now ready");
13042        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13043            SystemClock.uptimeMillis());
13044
13045        synchronized(this) {
13046            // Make sure we have no pre-ready processes sitting around.
13047
13048            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13049                ResolveInfo ri = mContext.getPackageManager()
13050                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13051                                STOCK_PM_FLAGS);
13052                CharSequence errorMsg = null;
13053                if (ri != null) {
13054                    ActivityInfo ai = ri.activityInfo;
13055                    ApplicationInfo app = ai.applicationInfo;
13056                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13057                        mTopAction = Intent.ACTION_FACTORY_TEST;
13058                        mTopData = null;
13059                        mTopComponent = new ComponentName(app.packageName,
13060                                ai.name);
13061                    } else {
13062                        errorMsg = mContext.getResources().getText(
13063                                com.android.internal.R.string.factorytest_not_system);
13064                    }
13065                } else {
13066                    errorMsg = mContext.getResources().getText(
13067                            com.android.internal.R.string.factorytest_no_action);
13068                }
13069                if (errorMsg != null) {
13070                    mTopAction = null;
13071                    mTopData = null;
13072                    mTopComponent = null;
13073                    Message msg = Message.obtain();
13074                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13075                    msg.getData().putCharSequence("msg", errorMsg);
13076                    mUiHandler.sendMessage(msg);
13077                }
13078            }
13079        }
13080
13081        retrieveSettings();
13082        final int currentUserId;
13083        synchronized (this) {
13084            currentUserId = mUserController.getCurrentUserIdLocked();
13085            readGrantedUriPermissionsLocked();
13086        }
13087
13088        if (goingCallback != null) goingCallback.run();
13089
13090        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13091                Integer.toString(currentUserId), currentUserId);
13092        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13093                Integer.toString(currentUserId), currentUserId);
13094        mSystemServiceManager.startUser(currentUserId);
13095
13096        synchronized (this) {
13097            // Only start up encryption-aware persistent apps; once user is
13098            // unlocked we'll come back around and start unaware apps
13099            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13100
13101            // Start up initial activity.
13102            mBooting = true;
13103            // Enable home activity for system user, so that the system can always boot
13104            if (UserManager.isSplitSystemUser()) {
13105                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13106                try {
13107                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13108                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13109                            UserHandle.USER_SYSTEM);
13110                } catch (RemoteException e) {
13111                    throw e.rethrowAsRuntimeException();
13112                }
13113            }
13114            startHomeActivityLocked(currentUserId, "systemReady");
13115
13116            try {
13117                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13118                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13119                            + " data partition or your device will be unstable.");
13120                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13121                }
13122            } catch (RemoteException e) {
13123            }
13124
13125            if (!Build.isBuildConsistent()) {
13126                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13127                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13128            }
13129
13130            long ident = Binder.clearCallingIdentity();
13131            try {
13132                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13133                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13134                        | Intent.FLAG_RECEIVER_FOREGROUND);
13135                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13136                broadcastIntentLocked(null, null, intent,
13137                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13138                        null, false, false, MY_PID, Process.SYSTEM_UID,
13139                        currentUserId);
13140                intent = new Intent(Intent.ACTION_USER_STARTING);
13141                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13142                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13143                broadcastIntentLocked(null, null, intent,
13144                        null, new IIntentReceiver.Stub() {
13145                            @Override
13146                            public void performReceive(Intent intent, int resultCode, String data,
13147                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13148                                    throws RemoteException {
13149                            }
13150                        }, 0, null, null,
13151                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13152                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13153            } catch (Throwable t) {
13154                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13155            } finally {
13156                Binder.restoreCallingIdentity(ident);
13157            }
13158            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13159            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13160        }
13161    }
13162
13163    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13164        synchronized (this) {
13165            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13166        }
13167    }
13168
13169    void skipCurrentReceiverLocked(ProcessRecord app) {
13170        for (BroadcastQueue queue : mBroadcastQueues) {
13171            queue.skipCurrentReceiverLocked(app);
13172        }
13173    }
13174
13175    /**
13176     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13177     * The application process will exit immediately after this call returns.
13178     * @param app object of the crashing app, null for the system server
13179     * @param crashInfo describing the exception
13180     */
13181    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13182        ProcessRecord r = findAppProcess(app, "Crash");
13183        final String processName = app == null ? "system_server"
13184                : (r == null ? "unknown" : r.processName);
13185
13186        handleApplicationCrashInner("crash", r, processName, crashInfo);
13187    }
13188
13189    /* Native crash reporting uses this inner version because it needs to be somewhat
13190     * decoupled from the AM-managed cleanup lifecycle
13191     */
13192    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13193            ApplicationErrorReport.CrashInfo crashInfo) {
13194        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13195                UserHandle.getUserId(Binder.getCallingUid()), processName,
13196                r == null ? -1 : r.info.flags,
13197                crashInfo.exceptionClassName,
13198                crashInfo.exceptionMessage,
13199                crashInfo.throwFileName,
13200                crashInfo.throwLineNumber);
13201
13202        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13203
13204        mAppErrors.crashApplication(r, crashInfo);
13205    }
13206
13207    public void handleApplicationStrictModeViolation(
13208            IBinder app,
13209            int violationMask,
13210            StrictMode.ViolationInfo info) {
13211        ProcessRecord r = findAppProcess(app, "StrictMode");
13212        if (r == null) {
13213            return;
13214        }
13215
13216        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13217            Integer stackFingerprint = info.hashCode();
13218            boolean logIt = true;
13219            synchronized (mAlreadyLoggedViolatedStacks) {
13220                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13221                    logIt = false;
13222                    // TODO: sub-sample into EventLog for these, with
13223                    // the info.durationMillis?  Then we'd get
13224                    // the relative pain numbers, without logging all
13225                    // the stack traces repeatedly.  We'd want to do
13226                    // likewise in the client code, which also does
13227                    // dup suppression, before the Binder call.
13228                } else {
13229                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13230                        mAlreadyLoggedViolatedStacks.clear();
13231                    }
13232                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13233                }
13234            }
13235            if (logIt) {
13236                logStrictModeViolationToDropBox(r, info);
13237            }
13238        }
13239
13240        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13241            AppErrorResult result = new AppErrorResult();
13242            synchronized (this) {
13243                final long origId = Binder.clearCallingIdentity();
13244
13245                Message msg = Message.obtain();
13246                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13247                HashMap<String, Object> data = new HashMap<String, Object>();
13248                data.put("result", result);
13249                data.put("app", r);
13250                data.put("violationMask", violationMask);
13251                data.put("info", info);
13252                msg.obj = data;
13253                mUiHandler.sendMessage(msg);
13254
13255                Binder.restoreCallingIdentity(origId);
13256            }
13257            int res = result.get();
13258            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13259        }
13260    }
13261
13262    // Depending on the policy in effect, there could be a bunch of
13263    // these in quick succession so we try to batch these together to
13264    // minimize disk writes, number of dropbox entries, and maximize
13265    // compression, by having more fewer, larger records.
13266    private void logStrictModeViolationToDropBox(
13267            ProcessRecord process,
13268            StrictMode.ViolationInfo info) {
13269        if (info == null) {
13270            return;
13271        }
13272        final boolean isSystemApp = process == null ||
13273                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13274                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13275        final String processName = process == null ? "unknown" : process.processName;
13276        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13277        final DropBoxManager dbox = (DropBoxManager)
13278                mContext.getSystemService(Context.DROPBOX_SERVICE);
13279
13280        // Exit early if the dropbox isn't configured to accept this report type.
13281        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13282
13283        boolean bufferWasEmpty;
13284        boolean needsFlush;
13285        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13286        synchronized (sb) {
13287            bufferWasEmpty = sb.length() == 0;
13288            appendDropBoxProcessHeaders(process, processName, sb);
13289            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13290            sb.append("System-App: ").append(isSystemApp).append("\n");
13291            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13292            if (info.violationNumThisLoop != 0) {
13293                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13294            }
13295            if (info.numAnimationsRunning != 0) {
13296                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13297            }
13298            if (info.broadcastIntentAction != null) {
13299                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13300            }
13301            if (info.durationMillis != -1) {
13302                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13303            }
13304            if (info.numInstances != -1) {
13305                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13306            }
13307            if (info.tags != null) {
13308                for (String tag : info.tags) {
13309                    sb.append("Span-Tag: ").append(tag).append("\n");
13310                }
13311            }
13312            sb.append("\n");
13313            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13314                sb.append(info.crashInfo.stackTrace);
13315                sb.append("\n");
13316            }
13317            if (info.message != null) {
13318                sb.append(info.message);
13319                sb.append("\n");
13320            }
13321
13322            // Only buffer up to ~64k.  Various logging bits truncate
13323            // things at 128k.
13324            needsFlush = (sb.length() > 64 * 1024);
13325        }
13326
13327        // Flush immediately if the buffer's grown too large, or this
13328        // is a non-system app.  Non-system apps are isolated with a
13329        // different tag & policy and not batched.
13330        //
13331        // Batching is useful during internal testing with
13332        // StrictMode settings turned up high.  Without batching,
13333        // thousands of separate files could be created on boot.
13334        if (!isSystemApp || needsFlush) {
13335            new Thread("Error dump: " + dropboxTag) {
13336                @Override
13337                public void run() {
13338                    String report;
13339                    synchronized (sb) {
13340                        report = sb.toString();
13341                        sb.delete(0, sb.length());
13342                        sb.trimToSize();
13343                    }
13344                    if (report.length() != 0) {
13345                        dbox.addText(dropboxTag, report);
13346                    }
13347                }
13348            }.start();
13349            return;
13350        }
13351
13352        // System app batching:
13353        if (!bufferWasEmpty) {
13354            // An existing dropbox-writing thread is outstanding, so
13355            // we don't need to start it up.  The existing thread will
13356            // catch the buffer appends we just did.
13357            return;
13358        }
13359
13360        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13361        // (After this point, we shouldn't access AMS internal data structures.)
13362        new Thread("Error dump: " + dropboxTag) {
13363            @Override
13364            public void run() {
13365                // 5 second sleep to let stacks arrive and be batched together
13366                try {
13367                    Thread.sleep(5000);  // 5 seconds
13368                } catch (InterruptedException e) {}
13369
13370                String errorReport;
13371                synchronized (mStrictModeBuffer) {
13372                    errorReport = mStrictModeBuffer.toString();
13373                    if (errorReport.length() == 0) {
13374                        return;
13375                    }
13376                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13377                    mStrictModeBuffer.trimToSize();
13378                }
13379                dbox.addText(dropboxTag, errorReport);
13380            }
13381        }.start();
13382    }
13383
13384    /**
13385     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13386     * @param app object of the crashing app, null for the system server
13387     * @param tag reported by the caller
13388     * @param system whether this wtf is coming from the system
13389     * @param crashInfo describing the context of the error
13390     * @return true if the process should exit immediately (WTF is fatal)
13391     */
13392    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13393            final ApplicationErrorReport.CrashInfo crashInfo) {
13394        final int callingUid = Binder.getCallingUid();
13395        final int callingPid = Binder.getCallingPid();
13396
13397        if (system) {
13398            // If this is coming from the system, we could very well have low-level
13399            // system locks held, so we want to do this all asynchronously.  And we
13400            // never want this to become fatal, so there is that too.
13401            mHandler.post(new Runnable() {
13402                @Override public void run() {
13403                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13404                }
13405            });
13406            return false;
13407        }
13408
13409        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13410                crashInfo);
13411
13412        if (r != null && r.pid != Process.myPid() &&
13413                Settings.Global.getInt(mContext.getContentResolver(),
13414                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13415            mAppErrors.crashApplication(r, crashInfo);
13416            return true;
13417        } else {
13418            return false;
13419        }
13420    }
13421
13422    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13423            final ApplicationErrorReport.CrashInfo crashInfo) {
13424        final ProcessRecord r = findAppProcess(app, "WTF");
13425        final String processName = app == null ? "system_server"
13426                : (r == null ? "unknown" : r.processName);
13427
13428        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13429                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13430
13431        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13432
13433        return r;
13434    }
13435
13436    /**
13437     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13438     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13439     */
13440    private ProcessRecord findAppProcess(IBinder app, String reason) {
13441        if (app == null) {
13442            return null;
13443        }
13444
13445        synchronized (this) {
13446            final int NP = mProcessNames.getMap().size();
13447            for (int ip=0; ip<NP; ip++) {
13448                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13449                final int NA = apps.size();
13450                for (int ia=0; ia<NA; ia++) {
13451                    ProcessRecord p = apps.valueAt(ia);
13452                    if (p.thread != null && p.thread.asBinder() == app) {
13453                        return p;
13454                    }
13455                }
13456            }
13457
13458            Slog.w(TAG, "Can't find mystery application for " + reason
13459                    + " from pid=" + Binder.getCallingPid()
13460                    + " uid=" + Binder.getCallingUid() + ": " + app);
13461            return null;
13462        }
13463    }
13464
13465    /**
13466     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13467     * to append various headers to the dropbox log text.
13468     */
13469    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13470            StringBuilder sb) {
13471        // Watchdog thread ends up invoking this function (with
13472        // a null ProcessRecord) to add the stack file to dropbox.
13473        // Do not acquire a lock on this (am) in such cases, as it
13474        // could cause a potential deadlock, if and when watchdog
13475        // is invoked due to unavailability of lock on am and it
13476        // would prevent watchdog from killing system_server.
13477        if (process == null) {
13478            sb.append("Process: ").append(processName).append("\n");
13479            return;
13480        }
13481        // Note: ProcessRecord 'process' is guarded by the service
13482        // instance.  (notably process.pkgList, which could otherwise change
13483        // concurrently during execution of this method)
13484        synchronized (this) {
13485            sb.append("Process: ").append(processName).append("\n");
13486            int flags = process.info.flags;
13487            IPackageManager pm = AppGlobals.getPackageManager();
13488            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13489            for (int ip=0; ip<process.pkgList.size(); ip++) {
13490                String pkg = process.pkgList.keyAt(ip);
13491                sb.append("Package: ").append(pkg);
13492                try {
13493                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13494                    if (pi != null) {
13495                        sb.append(" v").append(pi.versionCode);
13496                        if (pi.versionName != null) {
13497                            sb.append(" (").append(pi.versionName).append(")");
13498                        }
13499                    }
13500                } catch (RemoteException e) {
13501                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13502                }
13503                sb.append("\n");
13504            }
13505        }
13506    }
13507
13508    private static String processClass(ProcessRecord process) {
13509        if (process == null || process.pid == MY_PID) {
13510            return "system_server";
13511        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13512            return "system_app";
13513        } else {
13514            return "data_app";
13515        }
13516    }
13517
13518    private volatile long mWtfClusterStart;
13519    private volatile int mWtfClusterCount;
13520
13521    /**
13522     * Write a description of an error (crash, WTF, ANR) to the drop box.
13523     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13524     * @param process which caused the error, null means the system server
13525     * @param activity which triggered the error, null if unknown
13526     * @param parent activity related to the error, null if unknown
13527     * @param subject line related to the error, null if absent
13528     * @param report in long form describing the error, null if absent
13529     * @param logFile to include in the report, null if none
13530     * @param crashInfo giving an application stack trace, null if absent
13531     */
13532    public void addErrorToDropBox(String eventType,
13533            ProcessRecord process, String processName, ActivityRecord activity,
13534            ActivityRecord parent, String subject,
13535            final String report, final File logFile,
13536            final ApplicationErrorReport.CrashInfo crashInfo) {
13537        // NOTE -- this must never acquire the ActivityManagerService lock,
13538        // otherwise the watchdog may be prevented from resetting the system.
13539
13540        final String dropboxTag = processClass(process) + "_" + eventType;
13541        final DropBoxManager dbox = (DropBoxManager)
13542                mContext.getSystemService(Context.DROPBOX_SERVICE);
13543
13544        // Exit early if the dropbox isn't configured to accept this report type.
13545        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13546
13547        // Rate-limit how often we're willing to do the heavy lifting below to
13548        // collect and record logs; currently 5 logs per 10 second period.
13549        final long now = SystemClock.elapsedRealtime();
13550        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13551            mWtfClusterStart = now;
13552            mWtfClusterCount = 1;
13553        } else {
13554            if (mWtfClusterCount++ >= 5) return;
13555        }
13556
13557        final StringBuilder sb = new StringBuilder(1024);
13558        appendDropBoxProcessHeaders(process, processName, sb);
13559        if (process != null) {
13560            sb.append("Foreground: ")
13561                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13562                    .append("\n");
13563        }
13564        if (activity != null) {
13565            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13566        }
13567        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13568            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13569        }
13570        if (parent != null && parent != activity) {
13571            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13572        }
13573        if (subject != null) {
13574            sb.append("Subject: ").append(subject).append("\n");
13575        }
13576        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13577        if (Debug.isDebuggerConnected()) {
13578            sb.append("Debugger: Connected\n");
13579        }
13580        sb.append("\n");
13581
13582        // Do the rest in a worker thread to avoid blocking the caller on I/O
13583        // (After this point, we shouldn't access AMS internal data structures.)
13584        Thread worker = new Thread("Error dump: " + dropboxTag) {
13585            @Override
13586            public void run() {
13587                if (report != null) {
13588                    sb.append(report);
13589                }
13590                if (logFile != null) {
13591                    try {
13592                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13593                                    "\n\n[[TRUNCATED]]"));
13594                    } catch (IOException e) {
13595                        Slog.e(TAG, "Error reading " + logFile, e);
13596                    }
13597                }
13598                if (crashInfo != null && crashInfo.stackTrace != null) {
13599                    sb.append(crashInfo.stackTrace);
13600                }
13601
13602                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13603                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13604                if (lines > 0) {
13605                    sb.append("\n");
13606
13607                    // Merge several logcat streams, and take the last N lines
13608                    InputStreamReader input = null;
13609                    try {
13610                        java.lang.Process logcat = new ProcessBuilder(
13611                                "/system/bin/timeout", "-k", "15s", "10s",
13612                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13613                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13614                                        .redirectErrorStream(true).start();
13615
13616                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13617                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13618                        input = new InputStreamReader(logcat.getInputStream());
13619
13620                        int num;
13621                        char[] buf = new char[8192];
13622                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13623                    } catch (IOException e) {
13624                        Slog.e(TAG, "Error running logcat", e);
13625                    } finally {
13626                        if (input != null) try { input.close(); } catch (IOException e) {}
13627                    }
13628                }
13629
13630                dbox.addText(dropboxTag, sb.toString());
13631            }
13632        };
13633
13634        if (process == null) {
13635            // If process is null, we are being called from some internal code
13636            // and may be about to die -- run this synchronously.
13637            worker.run();
13638        } else {
13639            worker.start();
13640        }
13641    }
13642
13643    @Override
13644    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13645        enforceNotIsolatedCaller("getProcessesInErrorState");
13646        // assume our apps are happy - lazy create the list
13647        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13648
13649        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13650                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13651        int userId = UserHandle.getUserId(Binder.getCallingUid());
13652
13653        synchronized (this) {
13654
13655            // iterate across all processes
13656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13657                ProcessRecord app = mLruProcesses.get(i);
13658                if (!allUsers && app.userId != userId) {
13659                    continue;
13660                }
13661                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13662                    // This one's in trouble, so we'll generate a report for it
13663                    // crashes are higher priority (in case there's a crash *and* an anr)
13664                    ActivityManager.ProcessErrorStateInfo report = null;
13665                    if (app.crashing) {
13666                        report = app.crashingReport;
13667                    } else if (app.notResponding) {
13668                        report = app.notRespondingReport;
13669                    }
13670
13671                    if (report != null) {
13672                        if (errList == null) {
13673                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13674                        }
13675                        errList.add(report);
13676                    } else {
13677                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13678                                " crashing = " + app.crashing +
13679                                " notResponding = " + app.notResponding);
13680                    }
13681                }
13682            }
13683        }
13684
13685        return errList;
13686    }
13687
13688    static int procStateToImportance(int procState, int memAdj,
13689            ActivityManager.RunningAppProcessInfo currApp) {
13690        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13691        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13692            currApp.lru = memAdj;
13693        } else {
13694            currApp.lru = 0;
13695        }
13696        return imp;
13697    }
13698
13699    private void fillInProcMemInfo(ProcessRecord app,
13700            ActivityManager.RunningAppProcessInfo outInfo) {
13701        outInfo.pid = app.pid;
13702        outInfo.uid = app.info.uid;
13703        if (mHeavyWeightProcess == app) {
13704            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13705        }
13706        if (app.persistent) {
13707            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13708        }
13709        if (app.activities.size() > 0) {
13710            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13711        }
13712        outInfo.lastTrimLevel = app.trimMemoryLevel;
13713        int adj = app.curAdj;
13714        int procState = app.curProcState;
13715        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13716        outInfo.importanceReasonCode = app.adjTypeCode;
13717        outInfo.processState = app.curProcState;
13718    }
13719
13720    @Override
13721    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13722        enforceNotIsolatedCaller("getRunningAppProcesses");
13723
13724        final int callingUid = Binder.getCallingUid();
13725
13726        // Lazy instantiation of list
13727        List<ActivityManager.RunningAppProcessInfo> runList = null;
13728        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13729                callingUid) == PackageManager.PERMISSION_GRANTED;
13730        final int userId = UserHandle.getUserId(callingUid);
13731        final boolean allUids = isGetTasksAllowed(
13732                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13733
13734        synchronized (this) {
13735            // Iterate across all processes
13736            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13737                ProcessRecord app = mLruProcesses.get(i);
13738                if ((!allUsers && app.userId != userId)
13739                        || (!allUids && app.uid != callingUid)) {
13740                    continue;
13741                }
13742                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13743                    // Generate process state info for running application
13744                    ActivityManager.RunningAppProcessInfo currApp =
13745                        new ActivityManager.RunningAppProcessInfo(app.processName,
13746                                app.pid, app.getPackageList());
13747                    fillInProcMemInfo(app, currApp);
13748                    if (app.adjSource instanceof ProcessRecord) {
13749                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13750                        currApp.importanceReasonImportance =
13751                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13752                                        app.adjSourceProcState);
13753                    } else if (app.adjSource instanceof ActivityRecord) {
13754                        ActivityRecord r = (ActivityRecord)app.adjSource;
13755                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13756                    }
13757                    if (app.adjTarget instanceof ComponentName) {
13758                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13759                    }
13760                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13761                    //        + " lru=" + currApp.lru);
13762                    if (runList == null) {
13763                        runList = new ArrayList<>();
13764                    }
13765                    runList.add(currApp);
13766                }
13767            }
13768        }
13769        return runList;
13770    }
13771
13772    @Override
13773    public List<ApplicationInfo> getRunningExternalApplications() {
13774        enforceNotIsolatedCaller("getRunningExternalApplications");
13775        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13776        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13777        if (runningApps != null && runningApps.size() > 0) {
13778            Set<String> extList = new HashSet<String>();
13779            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13780                if (app.pkgList != null) {
13781                    for (String pkg : app.pkgList) {
13782                        extList.add(pkg);
13783                    }
13784                }
13785            }
13786            IPackageManager pm = AppGlobals.getPackageManager();
13787            for (String pkg : extList) {
13788                try {
13789                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13790                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13791                        retList.add(info);
13792                    }
13793                } catch (RemoteException e) {
13794                }
13795            }
13796        }
13797        return retList;
13798    }
13799
13800    @Override
13801    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13802        enforceNotIsolatedCaller("getMyMemoryState");
13803        synchronized (this) {
13804            ProcessRecord proc;
13805            synchronized (mPidsSelfLocked) {
13806                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13807            }
13808            fillInProcMemInfo(proc, outInfo);
13809        }
13810    }
13811
13812    @Override
13813    public int getMemoryTrimLevel() {
13814        enforceNotIsolatedCaller("getMyMemoryState");
13815        synchronized (this) {
13816            return mLastMemoryLevel;
13817        }
13818    }
13819
13820    @Override
13821    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13822            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13823        (new ActivityManagerShellCommand(this, false)).exec(
13824                this, in, out, err, args, resultReceiver);
13825    }
13826
13827    @Override
13828    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13829        if (checkCallingPermission(android.Manifest.permission.DUMP)
13830                != PackageManager.PERMISSION_GRANTED) {
13831            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13832                    + Binder.getCallingPid()
13833                    + ", uid=" + Binder.getCallingUid()
13834                    + " without permission "
13835                    + android.Manifest.permission.DUMP);
13836            return;
13837        }
13838
13839        boolean dumpAll = false;
13840        boolean dumpClient = false;
13841        boolean dumpCheckin = false;
13842        boolean dumpCheckinFormat = false;
13843        String dumpPackage = null;
13844
13845        int opti = 0;
13846        while (opti < args.length) {
13847            String opt = args[opti];
13848            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13849                break;
13850            }
13851            opti++;
13852            if ("-a".equals(opt)) {
13853                dumpAll = true;
13854            } else if ("-c".equals(opt)) {
13855                dumpClient = true;
13856            } else if ("-p".equals(opt)) {
13857                if (opti < args.length) {
13858                    dumpPackage = args[opti];
13859                    opti++;
13860                } else {
13861                    pw.println("Error: -p option requires package argument");
13862                    return;
13863                }
13864                dumpClient = true;
13865            } else if ("--checkin".equals(opt)) {
13866                dumpCheckin = dumpCheckinFormat = true;
13867            } else if ("-C".equals(opt)) {
13868                dumpCheckinFormat = true;
13869            } else if ("-h".equals(opt)) {
13870                ActivityManagerShellCommand.dumpHelp(pw, true);
13871                return;
13872            } else {
13873                pw.println("Unknown argument: " + opt + "; use -h for help");
13874            }
13875        }
13876
13877        long origId = Binder.clearCallingIdentity();
13878        boolean more = false;
13879        // Is the caller requesting to dump a particular piece of data?
13880        if (opti < args.length) {
13881            String cmd = args[opti];
13882            opti++;
13883            if ("activities".equals(cmd) || "a".equals(cmd)) {
13884                synchronized (this) {
13885                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13886                }
13887            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13888                synchronized (this) {
13889                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13890                }
13891            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13892                String[] newArgs;
13893                String name;
13894                if (opti >= args.length) {
13895                    name = null;
13896                    newArgs = EMPTY_STRING_ARRAY;
13897                } else {
13898                    dumpPackage = args[opti];
13899                    opti++;
13900                    newArgs = new String[args.length - opti];
13901                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13902                            args.length - opti);
13903                }
13904                synchronized (this) {
13905                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13906                }
13907            } else if ("broadcast-stats".equals(cmd)) {
13908                String[] newArgs;
13909                String name;
13910                if (opti >= args.length) {
13911                    name = null;
13912                    newArgs = EMPTY_STRING_ARRAY;
13913                } else {
13914                    dumpPackage = args[opti];
13915                    opti++;
13916                    newArgs = new String[args.length - opti];
13917                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13918                            args.length - opti);
13919                }
13920                synchronized (this) {
13921                    if (dumpCheckinFormat) {
13922                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13923                                dumpPackage);
13924                    } else {
13925                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13926                    }
13927                }
13928            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13929                String[] newArgs;
13930                String name;
13931                if (opti >= args.length) {
13932                    name = null;
13933                    newArgs = EMPTY_STRING_ARRAY;
13934                } else {
13935                    dumpPackage = args[opti];
13936                    opti++;
13937                    newArgs = new String[args.length - opti];
13938                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13939                            args.length - opti);
13940                }
13941                synchronized (this) {
13942                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13943                }
13944            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13945                String[] newArgs;
13946                String name;
13947                if (opti >= args.length) {
13948                    name = null;
13949                    newArgs = EMPTY_STRING_ARRAY;
13950                } else {
13951                    dumpPackage = args[opti];
13952                    opti++;
13953                    newArgs = new String[args.length - opti];
13954                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13955                            args.length - opti);
13956                }
13957                synchronized (this) {
13958                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13959                }
13960            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13961                synchronized (this) {
13962                    dumpOomLocked(fd, pw, args, opti, true);
13963                }
13964            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13965                synchronized (this) {
13966                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13967                }
13968            } else if ("provider".equals(cmd)) {
13969                String[] newArgs;
13970                String name;
13971                if (opti >= args.length) {
13972                    name = null;
13973                    newArgs = EMPTY_STRING_ARRAY;
13974                } else {
13975                    name = args[opti];
13976                    opti++;
13977                    newArgs = new String[args.length - opti];
13978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13979                }
13980                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13981                    pw.println("No providers match: " + name);
13982                    pw.println("Use -h for help.");
13983                }
13984            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13985                synchronized (this) {
13986                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13987                }
13988            } else if ("service".equals(cmd)) {
13989                String[] newArgs;
13990                String name;
13991                if (opti >= args.length) {
13992                    name = null;
13993                    newArgs = EMPTY_STRING_ARRAY;
13994                } else {
13995                    name = args[opti];
13996                    opti++;
13997                    newArgs = new String[args.length - opti];
13998                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13999                            args.length - opti);
14000                }
14001                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14002                    pw.println("No services match: " + name);
14003                    pw.println("Use -h for help.");
14004                }
14005            } else if ("package".equals(cmd)) {
14006                String[] newArgs;
14007                if (opti >= args.length) {
14008                    pw.println("package: no package name specified");
14009                    pw.println("Use -h for help.");
14010                } else {
14011                    dumpPackage = args[opti];
14012                    opti++;
14013                    newArgs = new String[args.length - opti];
14014                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14015                            args.length - opti);
14016                    args = newArgs;
14017                    opti = 0;
14018                    more = true;
14019                }
14020            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14021                synchronized (this) {
14022                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14023                }
14024            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14025                if (dumpClient) {
14026                    ActiveServices.ServiceDumper dumper;
14027                    synchronized (this) {
14028                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14029                                dumpPackage);
14030                    }
14031                    dumper.dumpWithClient();
14032                } else {
14033                    synchronized (this) {
14034                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14035                                dumpPackage).dumpLocked();
14036                    }
14037                }
14038            } else if ("locks".equals(cmd)) {
14039                LockGuard.dump(fd, pw, args);
14040            } else {
14041                // Dumping a single activity?
14042                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14043                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14044                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14045                    if (res < 0) {
14046                        pw.println("Bad activity command, or no activities match: " + cmd);
14047                        pw.println("Use -h for help.");
14048                    }
14049                }
14050            }
14051            if (!more) {
14052                Binder.restoreCallingIdentity(origId);
14053                return;
14054            }
14055        }
14056
14057        // No piece of data specified, dump everything.
14058        if (dumpCheckinFormat) {
14059            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14060        } else if (dumpClient) {
14061            ActiveServices.ServiceDumper sdumper;
14062            synchronized (this) {
14063                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14064                pw.println();
14065                if (dumpAll) {
14066                    pw.println("-------------------------------------------------------------------------------");
14067                }
14068                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14069                pw.println();
14070                if (dumpAll) {
14071                    pw.println("-------------------------------------------------------------------------------");
14072                }
14073                if (dumpAll || dumpPackage != null) {
14074                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14075                    pw.println();
14076                    if (dumpAll) {
14077                        pw.println("-------------------------------------------------------------------------------");
14078                    }
14079                }
14080                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14081                pw.println();
14082                if (dumpAll) {
14083                    pw.println("-------------------------------------------------------------------------------");
14084                }
14085                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14086                pw.println();
14087                if (dumpAll) {
14088                    pw.println("-------------------------------------------------------------------------------");
14089                }
14090                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14091                        dumpPackage);
14092            }
14093            sdumper.dumpWithClient();
14094            pw.println();
14095            synchronized (this) {
14096                if (dumpAll) {
14097                    pw.println("-------------------------------------------------------------------------------");
14098                }
14099                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14100                pw.println();
14101                if (dumpAll) {
14102                    pw.println("-------------------------------------------------------------------------------");
14103                }
14104                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14105                if (mAssociations.size() > 0) {
14106                    pw.println();
14107                    if (dumpAll) {
14108                        pw.println("-------------------------------------------------------------------------------");
14109                    }
14110                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14111                }
14112                pw.println();
14113                if (dumpAll) {
14114                    pw.println("-------------------------------------------------------------------------------");
14115                }
14116                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14117            }
14118
14119        } else {
14120            synchronized (this) {
14121                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14122                pw.println();
14123                if (dumpAll) {
14124                    pw.println("-------------------------------------------------------------------------------");
14125                }
14126                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14127                pw.println();
14128                if (dumpAll) {
14129                    pw.println("-------------------------------------------------------------------------------");
14130                }
14131                if (dumpAll || dumpPackage != null) {
14132                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14133                    pw.println();
14134                    if (dumpAll) {
14135                        pw.println("-------------------------------------------------------------------------------");
14136                    }
14137                }
14138                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14139                pw.println();
14140                if (dumpAll) {
14141                    pw.println("-------------------------------------------------------------------------------");
14142                }
14143                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14144                pw.println();
14145                if (dumpAll) {
14146                    pw.println("-------------------------------------------------------------------------------");
14147                }
14148                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14149                        .dumpLocked();
14150                pw.println();
14151                if (dumpAll) {
14152                    pw.println("-------------------------------------------------------------------------------");
14153                }
14154                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14155                pw.println();
14156                if (dumpAll) {
14157                    pw.println("-------------------------------------------------------------------------------");
14158                }
14159                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14160                if (mAssociations.size() > 0) {
14161                    pw.println();
14162                    if (dumpAll) {
14163                        pw.println("-------------------------------------------------------------------------------");
14164                    }
14165                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14166                }
14167                pw.println();
14168                if (dumpAll) {
14169                    pw.println("-------------------------------------------------------------------------------");
14170                }
14171                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14172            }
14173        }
14174        Binder.restoreCallingIdentity(origId);
14175    }
14176
14177    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14178            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14179        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14180
14181        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14182                dumpPackage);
14183        boolean needSep = printedAnything;
14184
14185        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14186                dumpPackage, needSep, "  mFocusedActivity: ");
14187        if (printed) {
14188            printedAnything = true;
14189            needSep = false;
14190        }
14191
14192        if (dumpPackage == null) {
14193            if (needSep) {
14194                pw.println();
14195            }
14196            needSep = true;
14197            printedAnything = true;
14198            mStackSupervisor.dump(pw, "  ");
14199        }
14200
14201        if (!printedAnything) {
14202            pw.println("  (nothing)");
14203        }
14204    }
14205
14206    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14207            int opti, boolean dumpAll, String dumpPackage) {
14208        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14209
14210        boolean printedAnything = false;
14211
14212        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14213            boolean printedHeader = false;
14214
14215            final int N = mRecentTasks.size();
14216            for (int i=0; i<N; i++) {
14217                TaskRecord tr = mRecentTasks.get(i);
14218                if (dumpPackage != null) {
14219                    if (tr.realActivity == null ||
14220                            !dumpPackage.equals(tr.realActivity)) {
14221                        continue;
14222                    }
14223                }
14224                if (!printedHeader) {
14225                    pw.println("  Recent tasks:");
14226                    printedHeader = true;
14227                    printedAnything = true;
14228                }
14229                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14230                        pw.println(tr);
14231                if (dumpAll) {
14232                    mRecentTasks.get(i).dump(pw, "    ");
14233                }
14234            }
14235        }
14236
14237        if (!printedAnything) {
14238            pw.println("  (nothing)");
14239        }
14240    }
14241
14242    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14243            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14244        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14245
14246        int dumpUid = 0;
14247        if (dumpPackage != null) {
14248            IPackageManager pm = AppGlobals.getPackageManager();
14249            try {
14250                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14251            } catch (RemoteException e) {
14252            }
14253        }
14254
14255        boolean printedAnything = false;
14256
14257        final long now = SystemClock.uptimeMillis();
14258
14259        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14260            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14261                    = mAssociations.valueAt(i1);
14262            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14263                SparseArray<ArrayMap<String, Association>> sourceUids
14264                        = targetComponents.valueAt(i2);
14265                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14266                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14267                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14268                        Association ass = sourceProcesses.valueAt(i4);
14269                        if (dumpPackage != null) {
14270                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14271                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14272                                continue;
14273                            }
14274                        }
14275                        printedAnything = true;
14276                        pw.print("  ");
14277                        pw.print(ass.mTargetProcess);
14278                        pw.print("/");
14279                        UserHandle.formatUid(pw, ass.mTargetUid);
14280                        pw.print(" <- ");
14281                        pw.print(ass.mSourceProcess);
14282                        pw.print("/");
14283                        UserHandle.formatUid(pw, ass.mSourceUid);
14284                        pw.println();
14285                        pw.print("    via ");
14286                        pw.print(ass.mTargetComponent.flattenToShortString());
14287                        pw.println();
14288                        pw.print("    ");
14289                        long dur = ass.mTime;
14290                        if (ass.mNesting > 0) {
14291                            dur += now - ass.mStartTime;
14292                        }
14293                        TimeUtils.formatDuration(dur, pw);
14294                        pw.print(" (");
14295                        pw.print(ass.mCount);
14296                        pw.print(" times)");
14297                        pw.print("  ");
14298                        for (int i=0; i<ass.mStateTimes.length; i++) {
14299                            long amt = ass.mStateTimes[i];
14300                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14301                                amt += now - ass.mLastStateUptime;
14302                            }
14303                            if (amt != 0) {
14304                                pw.print(" ");
14305                                pw.print(ProcessList.makeProcStateString(
14306                                            i + ActivityManager.MIN_PROCESS_STATE));
14307                                pw.print("=");
14308                                TimeUtils.formatDuration(amt, pw);
14309                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14310                                    pw.print("*");
14311                                }
14312                            }
14313                        }
14314                        pw.println();
14315                        if (ass.mNesting > 0) {
14316                            pw.print("    Currently active: ");
14317                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14318                            pw.println();
14319                        }
14320                    }
14321                }
14322            }
14323
14324        }
14325
14326        if (!printedAnything) {
14327            pw.println("  (nothing)");
14328        }
14329    }
14330
14331    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14332            String header, boolean needSep) {
14333        boolean printed = false;
14334        int whichAppId = -1;
14335        if (dumpPackage != null) {
14336            try {
14337                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14338                        dumpPackage, 0);
14339                whichAppId = UserHandle.getAppId(info.uid);
14340            } catch (NameNotFoundException e) {
14341                e.printStackTrace();
14342            }
14343        }
14344        for (int i=0; i<uids.size(); i++) {
14345            UidRecord uidRec = uids.valueAt(i);
14346            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14347                continue;
14348            }
14349            if (!printed) {
14350                printed = true;
14351                if (needSep) {
14352                    pw.println();
14353                }
14354                pw.print("  ");
14355                pw.println(header);
14356                needSep = true;
14357            }
14358            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14359            pw.print(": "); pw.println(uidRec);
14360        }
14361        return printed;
14362    }
14363
14364    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14365            int opti, boolean dumpAll, String dumpPackage) {
14366        boolean needSep = false;
14367        boolean printedAnything = false;
14368        int numPers = 0;
14369
14370        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14371
14372        if (dumpAll) {
14373            final int NP = mProcessNames.getMap().size();
14374            for (int ip=0; ip<NP; ip++) {
14375                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14376                final int NA = procs.size();
14377                for (int ia=0; ia<NA; ia++) {
14378                    ProcessRecord r = procs.valueAt(ia);
14379                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14380                        continue;
14381                    }
14382                    if (!needSep) {
14383                        pw.println("  All known processes:");
14384                        needSep = true;
14385                        printedAnything = true;
14386                    }
14387                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14388                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14389                        pw.print(" "); pw.println(r);
14390                    r.dump(pw, "    ");
14391                    if (r.persistent) {
14392                        numPers++;
14393                    }
14394                }
14395            }
14396        }
14397
14398        if (mIsolatedProcesses.size() > 0) {
14399            boolean printed = false;
14400            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14401                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14402                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14403                    continue;
14404                }
14405                if (!printed) {
14406                    if (needSep) {
14407                        pw.println();
14408                    }
14409                    pw.println("  Isolated process list (sorted by uid):");
14410                    printedAnything = true;
14411                    printed = true;
14412                    needSep = true;
14413                }
14414                pw.println(String.format("%sIsolated #%2d: %s",
14415                        "    ", i, r.toString()));
14416            }
14417        }
14418
14419        if (mActiveUids.size() > 0) {
14420            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14421                printedAnything = needSep = true;
14422            }
14423        }
14424        if (mValidateUids.size() > 0) {
14425            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14426                printedAnything = needSep = true;
14427            }
14428        }
14429
14430        if (mLruProcesses.size() > 0) {
14431            if (needSep) {
14432                pw.println();
14433            }
14434            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14435                    pw.print(" total, non-act at ");
14436                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14437                    pw.print(", non-svc at ");
14438                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14439                    pw.println("):");
14440            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14441            needSep = true;
14442            printedAnything = true;
14443        }
14444
14445        if (dumpAll || dumpPackage != null) {
14446            synchronized (mPidsSelfLocked) {
14447                boolean printed = false;
14448                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14449                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14450                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14451                        continue;
14452                    }
14453                    if (!printed) {
14454                        if (needSep) pw.println();
14455                        needSep = true;
14456                        pw.println("  PID mappings:");
14457                        printed = true;
14458                        printedAnything = true;
14459                    }
14460                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14461                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14462                }
14463            }
14464        }
14465
14466        if (mForegroundProcesses.size() > 0) {
14467            synchronized (mPidsSelfLocked) {
14468                boolean printed = false;
14469                for (int i=0; i<mForegroundProcesses.size(); i++) {
14470                    ProcessRecord r = mPidsSelfLocked.get(
14471                            mForegroundProcesses.valueAt(i).pid);
14472                    if (dumpPackage != null && (r == null
14473                            || !r.pkgList.containsKey(dumpPackage))) {
14474                        continue;
14475                    }
14476                    if (!printed) {
14477                        if (needSep) pw.println();
14478                        needSep = true;
14479                        pw.println("  Foreground Processes:");
14480                        printed = true;
14481                        printedAnything = true;
14482                    }
14483                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14484                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14485                }
14486            }
14487        }
14488
14489        if (mPersistentStartingProcesses.size() > 0) {
14490            if (needSep) pw.println();
14491            needSep = true;
14492            printedAnything = true;
14493            pw.println("  Persisent processes that are starting:");
14494            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14495                    "Starting Norm", "Restarting PERS", dumpPackage);
14496        }
14497
14498        if (mRemovedProcesses.size() > 0) {
14499            if (needSep) pw.println();
14500            needSep = true;
14501            printedAnything = true;
14502            pw.println("  Processes that are being removed:");
14503            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14504                    "Removed Norm", "Removed PERS", dumpPackage);
14505        }
14506
14507        if (mProcessesOnHold.size() > 0) {
14508            if (needSep) pw.println();
14509            needSep = true;
14510            printedAnything = true;
14511            pw.println("  Processes that are on old until the system is ready:");
14512            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14513                    "OnHold Norm", "OnHold PERS", dumpPackage);
14514        }
14515
14516        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14517
14518        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14519        if (needSep) {
14520            printedAnything = true;
14521        }
14522
14523        if (dumpPackage == null) {
14524            pw.println();
14525            needSep = false;
14526            mUserController.dump(pw, dumpAll);
14527        }
14528        if (mHomeProcess != null && (dumpPackage == null
14529                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14530            if (needSep) {
14531                pw.println();
14532                needSep = false;
14533            }
14534            pw.println("  mHomeProcess: " + mHomeProcess);
14535        }
14536        if (mPreviousProcess != null && (dumpPackage == null
14537                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14538            if (needSep) {
14539                pw.println();
14540                needSep = false;
14541            }
14542            pw.println("  mPreviousProcess: " + mPreviousProcess);
14543        }
14544        if (dumpAll) {
14545            StringBuilder sb = new StringBuilder(128);
14546            sb.append("  mPreviousProcessVisibleTime: ");
14547            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14548            pw.println(sb);
14549        }
14550        if (mHeavyWeightProcess != null && (dumpPackage == null
14551                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14552            if (needSep) {
14553                pw.println();
14554                needSep = false;
14555            }
14556            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14557        }
14558        if (dumpPackage == null) {
14559            pw.println("  mConfiguration: " + mConfiguration);
14560        }
14561        if (dumpAll) {
14562            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14563            if (mCompatModePackages.getPackages().size() > 0) {
14564                boolean printed = false;
14565                for (Map.Entry<String, Integer> entry
14566                        : mCompatModePackages.getPackages().entrySet()) {
14567                    String pkg = entry.getKey();
14568                    int mode = entry.getValue();
14569                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14570                        continue;
14571                    }
14572                    if (!printed) {
14573                        pw.println("  mScreenCompatPackages:");
14574                        printed = true;
14575                    }
14576                    pw.print("    "); pw.print(pkg); pw.print(": ");
14577                            pw.print(mode); pw.println();
14578                }
14579            }
14580        }
14581        if (dumpPackage == null) {
14582            pw.println("  mWakefulness="
14583                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14584            pw.println("  mSleepTokens=" + mSleepTokens);
14585            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14586                    + lockScreenShownToString());
14587            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14588            if (mRunningVoice != null) {
14589                pw.println("  mRunningVoice=" + mRunningVoice);
14590                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14591            }
14592        }
14593        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14594                || mOrigWaitForDebugger) {
14595            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14596                    || dumpPackage.equals(mOrigDebugApp)) {
14597                if (needSep) {
14598                    pw.println();
14599                    needSep = false;
14600                }
14601                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14602                        + " mDebugTransient=" + mDebugTransient
14603                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14604            }
14605        }
14606        if (mCurAppTimeTracker != null) {
14607            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14608        }
14609        if (mMemWatchProcesses.getMap().size() > 0) {
14610            pw.println("  Mem watch processes:");
14611            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14612                    = mMemWatchProcesses.getMap();
14613            for (int i=0; i<procs.size(); i++) {
14614                final String proc = procs.keyAt(i);
14615                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14616                for (int j=0; j<uids.size(); j++) {
14617                    if (needSep) {
14618                        pw.println();
14619                        needSep = false;
14620                    }
14621                    StringBuilder sb = new StringBuilder();
14622                    sb.append("    ").append(proc).append('/');
14623                    UserHandle.formatUid(sb, uids.keyAt(j));
14624                    Pair<Long, String> val = uids.valueAt(j);
14625                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14626                    if (val.second != null) {
14627                        sb.append(", report to ").append(val.second);
14628                    }
14629                    pw.println(sb.toString());
14630                }
14631            }
14632            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14633            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14634            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14635                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14636        }
14637        if (mTrackAllocationApp != null) {
14638            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14639                if (needSep) {
14640                    pw.println();
14641                    needSep = false;
14642                }
14643                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14644            }
14645        }
14646        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14647                || mProfileFd != null) {
14648            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14649                if (needSep) {
14650                    pw.println();
14651                    needSep = false;
14652                }
14653                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14654                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14655                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14656                        + mAutoStopProfiler);
14657                pw.println("  mProfileType=" + mProfileType);
14658            }
14659        }
14660        if (mNativeDebuggingApp != null) {
14661            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14662                if (needSep) {
14663                    pw.println();
14664                    needSep = false;
14665                }
14666                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14667            }
14668        }
14669        if (dumpPackage == null) {
14670            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14671                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14672                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14673            }
14674            if (mController != null) {
14675                pw.println("  mController=" + mController
14676                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14677            }
14678            if (dumpAll) {
14679                pw.println("  Total persistent processes: " + numPers);
14680                pw.println("  mProcessesReady=" + mProcessesReady
14681                        + " mSystemReady=" + mSystemReady
14682                        + " mBooted=" + mBooted
14683                        + " mFactoryTest=" + mFactoryTest);
14684                pw.println("  mBooting=" + mBooting
14685                        + " mCallFinishBooting=" + mCallFinishBooting
14686                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14687                pw.print("  mLastPowerCheckRealtime=");
14688                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14689                        pw.println("");
14690                pw.print("  mLastPowerCheckUptime=");
14691                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14692                        pw.println("");
14693                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14694                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14695                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14696                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14697                        + " (" + mLruProcesses.size() + " total)"
14698                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14699                        + " mNumServiceProcs=" + mNumServiceProcs
14700                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14701                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14702                        + " mLastMemoryLevel=" + mLastMemoryLevel
14703                        + " mLastNumProcesses=" + mLastNumProcesses);
14704                long now = SystemClock.uptimeMillis();
14705                pw.print("  mLastIdleTime=");
14706                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14707                        pw.print(" mLowRamSinceLastIdle=");
14708                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14709                        pw.println();
14710            }
14711        }
14712
14713        if (!printedAnything) {
14714            pw.println("  (nothing)");
14715        }
14716    }
14717
14718    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14719            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14720        if (mProcessesToGc.size() > 0) {
14721            boolean printed = false;
14722            long now = SystemClock.uptimeMillis();
14723            for (int i=0; i<mProcessesToGc.size(); i++) {
14724                ProcessRecord proc = mProcessesToGc.get(i);
14725                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14726                    continue;
14727                }
14728                if (!printed) {
14729                    if (needSep) pw.println();
14730                    needSep = true;
14731                    pw.println("  Processes that are waiting to GC:");
14732                    printed = true;
14733                }
14734                pw.print("    Process "); pw.println(proc);
14735                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14736                        pw.print(", last gced=");
14737                        pw.print(now-proc.lastRequestedGc);
14738                        pw.print(" ms ago, last lowMem=");
14739                        pw.print(now-proc.lastLowMemory);
14740                        pw.println(" ms ago");
14741
14742            }
14743        }
14744        return needSep;
14745    }
14746
14747    void printOomLevel(PrintWriter pw, String name, int adj) {
14748        pw.print("    ");
14749        if (adj >= 0) {
14750            pw.print(' ');
14751            if (adj < 10) pw.print(' ');
14752        } else {
14753            if (adj > -10) pw.print(' ');
14754        }
14755        pw.print(adj);
14756        pw.print(": ");
14757        pw.print(name);
14758        pw.print(" (");
14759        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14760        pw.println(")");
14761    }
14762
14763    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14764            int opti, boolean dumpAll) {
14765        boolean needSep = false;
14766
14767        if (mLruProcesses.size() > 0) {
14768            if (needSep) pw.println();
14769            needSep = true;
14770            pw.println("  OOM levels:");
14771            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14772            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14773            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14774            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14775            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14776            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14777            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14778            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14779            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14780            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14781            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14782            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14783            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14784            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14785
14786            if (needSep) pw.println();
14787            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14788                    pw.print(" total, non-act at ");
14789                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14790                    pw.print(", non-svc at ");
14791                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14792                    pw.println("):");
14793            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14794            needSep = true;
14795        }
14796
14797        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14798
14799        pw.println();
14800        pw.println("  mHomeProcess: " + mHomeProcess);
14801        pw.println("  mPreviousProcess: " + mPreviousProcess);
14802        if (mHeavyWeightProcess != null) {
14803            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14804        }
14805
14806        return true;
14807    }
14808
14809    /**
14810     * There are three ways to call this:
14811     *  - no provider specified: dump all the providers
14812     *  - a flattened component name that matched an existing provider was specified as the
14813     *    first arg: dump that one provider
14814     *  - the first arg isn't the flattened component name of an existing provider:
14815     *    dump all providers whose component contains the first arg as a substring
14816     */
14817    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14818            int opti, boolean dumpAll) {
14819        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14820    }
14821
14822    static class ItemMatcher {
14823        ArrayList<ComponentName> components;
14824        ArrayList<String> strings;
14825        ArrayList<Integer> objects;
14826        boolean all;
14827
14828        ItemMatcher() {
14829            all = true;
14830        }
14831
14832        void build(String name) {
14833            ComponentName componentName = ComponentName.unflattenFromString(name);
14834            if (componentName != null) {
14835                if (components == null) {
14836                    components = new ArrayList<ComponentName>();
14837                }
14838                components.add(componentName);
14839                all = false;
14840            } else {
14841                int objectId = 0;
14842                // Not a '/' separated full component name; maybe an object ID?
14843                try {
14844                    objectId = Integer.parseInt(name, 16);
14845                    if (objects == null) {
14846                        objects = new ArrayList<Integer>();
14847                    }
14848                    objects.add(objectId);
14849                    all = false;
14850                } catch (RuntimeException e) {
14851                    // Not an integer; just do string match.
14852                    if (strings == null) {
14853                        strings = new ArrayList<String>();
14854                    }
14855                    strings.add(name);
14856                    all = false;
14857                }
14858            }
14859        }
14860
14861        int build(String[] args, int opti) {
14862            for (; opti<args.length; opti++) {
14863                String name = args[opti];
14864                if ("--".equals(name)) {
14865                    return opti+1;
14866                }
14867                build(name);
14868            }
14869            return opti;
14870        }
14871
14872        boolean match(Object object, ComponentName comp) {
14873            if (all) {
14874                return true;
14875            }
14876            if (components != null) {
14877                for (int i=0; i<components.size(); i++) {
14878                    if (components.get(i).equals(comp)) {
14879                        return true;
14880                    }
14881                }
14882            }
14883            if (objects != null) {
14884                for (int i=0; i<objects.size(); i++) {
14885                    if (System.identityHashCode(object) == objects.get(i)) {
14886                        return true;
14887                    }
14888                }
14889            }
14890            if (strings != null) {
14891                String flat = comp.flattenToString();
14892                for (int i=0; i<strings.size(); i++) {
14893                    if (flat.contains(strings.get(i))) {
14894                        return true;
14895                    }
14896                }
14897            }
14898            return false;
14899        }
14900    }
14901
14902    /**
14903     * There are three things that cmd can be:
14904     *  - a flattened component name that matches an existing activity
14905     *  - the cmd arg isn't the flattened component name of an existing activity:
14906     *    dump all activity whose component contains the cmd as a substring
14907     *  - A hex number of the ActivityRecord object instance.
14908     */
14909    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14910            int opti, boolean dumpAll) {
14911        ArrayList<ActivityRecord> activities;
14912
14913        synchronized (this) {
14914            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14915        }
14916
14917        if (activities.size() <= 0) {
14918            return false;
14919        }
14920
14921        String[] newArgs = new String[args.length - opti];
14922        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14923
14924        TaskRecord lastTask = null;
14925        boolean needSep = false;
14926        for (int i=activities.size()-1; i>=0; i--) {
14927            ActivityRecord r = activities.get(i);
14928            if (needSep) {
14929                pw.println();
14930            }
14931            needSep = true;
14932            synchronized (this) {
14933                if (lastTask != r.task) {
14934                    lastTask = r.task;
14935                    pw.print("TASK "); pw.print(lastTask.affinity);
14936                            pw.print(" id="); pw.println(lastTask.taskId);
14937                    if (dumpAll) {
14938                        lastTask.dump(pw, "  ");
14939                    }
14940                }
14941            }
14942            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14943        }
14944        return true;
14945    }
14946
14947    /**
14948     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14949     * there is a thread associated with the activity.
14950     */
14951    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14952            final ActivityRecord r, String[] args, boolean dumpAll) {
14953        String innerPrefix = prefix + "  ";
14954        synchronized (this) {
14955            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14956                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14957                    pw.print(" pid=");
14958                    if (r.app != null) pw.println(r.app.pid);
14959                    else pw.println("(not running)");
14960            if (dumpAll) {
14961                r.dump(pw, innerPrefix);
14962            }
14963        }
14964        if (r.app != null && r.app.thread != null) {
14965            // flush anything that is already in the PrintWriter since the thread is going
14966            // to write to the file descriptor directly
14967            pw.flush();
14968            try {
14969                TransferPipe tp = new TransferPipe();
14970                try {
14971                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14972                            r.appToken, innerPrefix, args);
14973                    tp.go(fd);
14974                } finally {
14975                    tp.kill();
14976                }
14977            } catch (IOException e) {
14978                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14979            } catch (RemoteException e) {
14980                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14981            }
14982        }
14983    }
14984
14985    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14986            int opti, boolean dumpAll, String dumpPackage) {
14987        boolean needSep = false;
14988        boolean onlyHistory = false;
14989        boolean printedAnything = false;
14990
14991        if ("history".equals(dumpPackage)) {
14992            if (opti < args.length && "-s".equals(args[opti])) {
14993                dumpAll = false;
14994            }
14995            onlyHistory = true;
14996            dumpPackage = null;
14997        }
14998
14999        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15000        if (!onlyHistory && dumpAll) {
15001            if (mRegisteredReceivers.size() > 0) {
15002                boolean printed = false;
15003                Iterator it = mRegisteredReceivers.values().iterator();
15004                while (it.hasNext()) {
15005                    ReceiverList r = (ReceiverList)it.next();
15006                    if (dumpPackage != null && (r.app == null ||
15007                            !dumpPackage.equals(r.app.info.packageName))) {
15008                        continue;
15009                    }
15010                    if (!printed) {
15011                        pw.println("  Registered Receivers:");
15012                        needSep = true;
15013                        printed = true;
15014                        printedAnything = true;
15015                    }
15016                    pw.print("  * "); pw.println(r);
15017                    r.dump(pw, "    ");
15018                }
15019            }
15020
15021            if (mReceiverResolver.dump(pw, needSep ?
15022                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15023                    "    ", dumpPackage, false, false)) {
15024                needSep = true;
15025                printedAnything = true;
15026            }
15027        }
15028
15029        for (BroadcastQueue q : mBroadcastQueues) {
15030            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15031            printedAnything |= needSep;
15032        }
15033
15034        needSep = true;
15035
15036        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15037            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15038                if (needSep) {
15039                    pw.println();
15040                }
15041                needSep = true;
15042                printedAnything = true;
15043                pw.print("  Sticky broadcasts for user ");
15044                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15045                StringBuilder sb = new StringBuilder(128);
15046                for (Map.Entry<String, ArrayList<Intent>> ent
15047                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15048                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15049                    if (dumpAll) {
15050                        pw.println(":");
15051                        ArrayList<Intent> intents = ent.getValue();
15052                        final int N = intents.size();
15053                        for (int i=0; i<N; i++) {
15054                            sb.setLength(0);
15055                            sb.append("    Intent: ");
15056                            intents.get(i).toShortString(sb, false, true, false, false);
15057                            pw.println(sb.toString());
15058                            Bundle bundle = intents.get(i).getExtras();
15059                            if (bundle != null) {
15060                                pw.print("      ");
15061                                pw.println(bundle.toString());
15062                            }
15063                        }
15064                    } else {
15065                        pw.println("");
15066                    }
15067                }
15068            }
15069        }
15070
15071        if (!onlyHistory && dumpAll) {
15072            pw.println();
15073            for (BroadcastQueue queue : mBroadcastQueues) {
15074                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15075                        + queue.mBroadcastsScheduled);
15076            }
15077            pw.println("  mHandler:");
15078            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15079            needSep = true;
15080            printedAnything = true;
15081        }
15082
15083        if (!printedAnything) {
15084            pw.println("  (nothing)");
15085        }
15086    }
15087
15088    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15089            int opti, boolean dumpAll, String dumpPackage) {
15090        if (mCurBroadcastStats == null) {
15091            return;
15092        }
15093
15094        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15095        final long now = SystemClock.elapsedRealtime();
15096        if (mLastBroadcastStats != null) {
15097            pw.print("  Last stats (from ");
15098            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15099            pw.print(" to ");
15100            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15101            pw.print(", ");
15102            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15103                    - mLastBroadcastStats.mStartUptime, pw);
15104            pw.println(" uptime):");
15105            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15106                pw.println("    (nothing)");
15107            }
15108            pw.println();
15109        }
15110        pw.print("  Current stats (from ");
15111        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15112        pw.print(" to now, ");
15113        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15114                - mCurBroadcastStats.mStartUptime, pw);
15115        pw.println(" uptime):");
15116        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15117            pw.println("    (nothing)");
15118        }
15119    }
15120
15121    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15122            int opti, boolean fullCheckin, String dumpPackage) {
15123        if (mCurBroadcastStats == null) {
15124            return;
15125        }
15126
15127        if (mLastBroadcastStats != null) {
15128            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15129            if (fullCheckin) {
15130                mLastBroadcastStats = null;
15131                return;
15132            }
15133        }
15134        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15135        if (fullCheckin) {
15136            mCurBroadcastStats = null;
15137        }
15138    }
15139
15140    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15141            int opti, boolean dumpAll, String dumpPackage) {
15142        boolean needSep;
15143        boolean printedAnything = false;
15144
15145        ItemMatcher matcher = new ItemMatcher();
15146        matcher.build(args, opti);
15147
15148        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15149
15150        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15151        printedAnything |= needSep;
15152
15153        if (mLaunchingProviders.size() > 0) {
15154            boolean printed = false;
15155            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15156                ContentProviderRecord r = mLaunchingProviders.get(i);
15157                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15158                    continue;
15159                }
15160                if (!printed) {
15161                    if (needSep) pw.println();
15162                    needSep = true;
15163                    pw.println("  Launching content providers:");
15164                    printed = true;
15165                    printedAnything = true;
15166                }
15167                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15168                        pw.println(r);
15169            }
15170        }
15171
15172        if (!printedAnything) {
15173            pw.println("  (nothing)");
15174        }
15175    }
15176
15177    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15178            int opti, boolean dumpAll, String dumpPackage) {
15179        boolean needSep = false;
15180        boolean printedAnything = false;
15181
15182        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15183
15184        if (mGrantedUriPermissions.size() > 0) {
15185            boolean printed = false;
15186            int dumpUid = -2;
15187            if (dumpPackage != null) {
15188                try {
15189                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15190                            MATCH_UNINSTALLED_PACKAGES, 0);
15191                } catch (NameNotFoundException e) {
15192                    dumpUid = -1;
15193                }
15194            }
15195            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15196                int uid = mGrantedUriPermissions.keyAt(i);
15197                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15198                    continue;
15199                }
15200                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15201                if (!printed) {
15202                    if (needSep) pw.println();
15203                    needSep = true;
15204                    pw.println("  Granted Uri Permissions:");
15205                    printed = true;
15206                    printedAnything = true;
15207                }
15208                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15209                for (UriPermission perm : perms.values()) {
15210                    pw.print("    "); pw.println(perm);
15211                    if (dumpAll) {
15212                        perm.dump(pw, "      ");
15213                    }
15214                }
15215            }
15216        }
15217
15218        if (!printedAnything) {
15219            pw.println("  (nothing)");
15220        }
15221    }
15222
15223    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15224            int opti, boolean dumpAll, String dumpPackage) {
15225        boolean printed = false;
15226
15227        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15228
15229        if (mIntentSenderRecords.size() > 0) {
15230            Iterator<WeakReference<PendingIntentRecord>> it
15231                    = mIntentSenderRecords.values().iterator();
15232            while (it.hasNext()) {
15233                WeakReference<PendingIntentRecord> ref = it.next();
15234                PendingIntentRecord rec = ref != null ? ref.get(): null;
15235                if (dumpPackage != null && (rec == null
15236                        || !dumpPackage.equals(rec.key.packageName))) {
15237                    continue;
15238                }
15239                printed = true;
15240                if (rec != null) {
15241                    pw.print("  * "); pw.println(rec);
15242                    if (dumpAll) {
15243                        rec.dump(pw, "    ");
15244                    }
15245                } else {
15246                    pw.print("  * "); pw.println(ref);
15247                }
15248            }
15249        }
15250
15251        if (!printed) {
15252            pw.println("  (nothing)");
15253        }
15254    }
15255
15256    private static final int dumpProcessList(PrintWriter pw,
15257            ActivityManagerService service, List list,
15258            String prefix, String normalLabel, String persistentLabel,
15259            String dumpPackage) {
15260        int numPers = 0;
15261        final int N = list.size()-1;
15262        for (int i=N; i>=0; i--) {
15263            ProcessRecord r = (ProcessRecord)list.get(i);
15264            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15265                continue;
15266            }
15267            pw.println(String.format("%s%s #%2d: %s",
15268                    prefix, (r.persistent ? persistentLabel : normalLabel),
15269                    i, r.toString()));
15270            if (r.persistent) {
15271                numPers++;
15272            }
15273        }
15274        return numPers;
15275    }
15276
15277    private static final boolean dumpProcessOomList(PrintWriter pw,
15278            ActivityManagerService service, List<ProcessRecord> origList,
15279            String prefix, String normalLabel, String persistentLabel,
15280            boolean inclDetails, String dumpPackage) {
15281
15282        ArrayList<Pair<ProcessRecord, Integer>> list
15283                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15284        for (int i=0; i<origList.size(); i++) {
15285            ProcessRecord r = origList.get(i);
15286            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15287                continue;
15288            }
15289            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15290        }
15291
15292        if (list.size() <= 0) {
15293            return false;
15294        }
15295
15296        Comparator<Pair<ProcessRecord, Integer>> comparator
15297                = new Comparator<Pair<ProcessRecord, Integer>>() {
15298            @Override
15299            public int compare(Pair<ProcessRecord, Integer> object1,
15300                    Pair<ProcessRecord, Integer> object2) {
15301                if (object1.first.setAdj != object2.first.setAdj) {
15302                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15303                }
15304                if (object1.first.setProcState != object2.first.setProcState) {
15305                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15306                }
15307                if (object1.second.intValue() != object2.second.intValue()) {
15308                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15309                }
15310                return 0;
15311            }
15312        };
15313
15314        Collections.sort(list, comparator);
15315
15316        final long curRealtime = SystemClock.elapsedRealtime();
15317        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15318        final long curUptime = SystemClock.uptimeMillis();
15319        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15320
15321        for (int i=list.size()-1; i>=0; i--) {
15322            ProcessRecord r = list.get(i).first;
15323            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15324            char schedGroup;
15325            switch (r.setSchedGroup) {
15326                case ProcessList.SCHED_GROUP_BACKGROUND:
15327                    schedGroup = 'B';
15328                    break;
15329                case ProcessList.SCHED_GROUP_DEFAULT:
15330                    schedGroup = 'F';
15331                    break;
15332                case ProcessList.SCHED_GROUP_TOP_APP:
15333                    schedGroup = 'T';
15334                    break;
15335                default:
15336                    schedGroup = '?';
15337                    break;
15338            }
15339            char foreground;
15340            if (r.foregroundActivities) {
15341                foreground = 'A';
15342            } else if (r.foregroundServices) {
15343                foreground = 'S';
15344            } else {
15345                foreground = ' ';
15346            }
15347            String procState = ProcessList.makeProcStateString(r.curProcState);
15348            pw.print(prefix);
15349            pw.print(r.persistent ? persistentLabel : normalLabel);
15350            pw.print(" #");
15351            int num = (origList.size()-1)-list.get(i).second;
15352            if (num < 10) pw.print(' ');
15353            pw.print(num);
15354            pw.print(": ");
15355            pw.print(oomAdj);
15356            pw.print(' ');
15357            pw.print(schedGroup);
15358            pw.print('/');
15359            pw.print(foreground);
15360            pw.print('/');
15361            pw.print(procState);
15362            pw.print(" trm:");
15363            if (r.trimMemoryLevel < 10) pw.print(' ');
15364            pw.print(r.trimMemoryLevel);
15365            pw.print(' ');
15366            pw.print(r.toShortString());
15367            pw.print(" (");
15368            pw.print(r.adjType);
15369            pw.println(')');
15370            if (r.adjSource != null || r.adjTarget != null) {
15371                pw.print(prefix);
15372                pw.print("    ");
15373                if (r.adjTarget instanceof ComponentName) {
15374                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15375                } else if (r.adjTarget != null) {
15376                    pw.print(r.adjTarget.toString());
15377                } else {
15378                    pw.print("{null}");
15379                }
15380                pw.print("<=");
15381                if (r.adjSource instanceof ProcessRecord) {
15382                    pw.print("Proc{");
15383                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15384                    pw.println("}");
15385                } else if (r.adjSource != null) {
15386                    pw.println(r.adjSource.toString());
15387                } else {
15388                    pw.println("{null}");
15389                }
15390            }
15391            if (inclDetails) {
15392                pw.print(prefix);
15393                pw.print("    ");
15394                pw.print("oom: max="); pw.print(r.maxAdj);
15395                pw.print(" curRaw="); pw.print(r.curRawAdj);
15396                pw.print(" setRaw="); pw.print(r.setRawAdj);
15397                pw.print(" cur="); pw.print(r.curAdj);
15398                pw.print(" set="); pw.println(r.setAdj);
15399                pw.print(prefix);
15400                pw.print("    ");
15401                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15402                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15403                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15404                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15405                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15406                pw.println();
15407                pw.print(prefix);
15408                pw.print("    ");
15409                pw.print("cached="); pw.print(r.cached);
15410                pw.print(" empty="); pw.print(r.empty);
15411                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15412
15413                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15414                    if (r.lastWakeTime != 0) {
15415                        long wtime;
15416                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15417                        synchronized (stats) {
15418                            wtime = stats.getProcessWakeTime(r.info.uid,
15419                                    r.pid, curRealtime);
15420                        }
15421                        long timeUsed = wtime - r.lastWakeTime;
15422                        pw.print(prefix);
15423                        pw.print("    ");
15424                        pw.print("keep awake over ");
15425                        TimeUtils.formatDuration(realtimeSince, pw);
15426                        pw.print(" used ");
15427                        TimeUtils.formatDuration(timeUsed, pw);
15428                        pw.print(" (");
15429                        pw.print((timeUsed*100)/realtimeSince);
15430                        pw.println("%)");
15431                    }
15432                    if (r.lastCpuTime != 0) {
15433                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15434                        pw.print(prefix);
15435                        pw.print("    ");
15436                        pw.print("run cpu over ");
15437                        TimeUtils.formatDuration(uptimeSince, pw);
15438                        pw.print(" used ");
15439                        TimeUtils.formatDuration(timeUsed, pw);
15440                        pw.print(" (");
15441                        pw.print((timeUsed*100)/uptimeSince);
15442                        pw.println("%)");
15443                    }
15444                }
15445            }
15446        }
15447        return true;
15448    }
15449
15450    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15451            String[] args) {
15452        ArrayList<ProcessRecord> procs;
15453        synchronized (this) {
15454            if (args != null && args.length > start
15455                    && args[start].charAt(0) != '-') {
15456                procs = new ArrayList<ProcessRecord>();
15457                int pid = -1;
15458                try {
15459                    pid = Integer.parseInt(args[start]);
15460                } catch (NumberFormatException e) {
15461                }
15462                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15463                    ProcessRecord proc = mLruProcesses.get(i);
15464                    if (proc.pid == pid) {
15465                        procs.add(proc);
15466                    } else if (allPkgs && proc.pkgList != null
15467                            && proc.pkgList.containsKey(args[start])) {
15468                        procs.add(proc);
15469                    } else if (proc.processName.equals(args[start])) {
15470                        procs.add(proc);
15471                    }
15472                }
15473                if (procs.size() <= 0) {
15474                    return null;
15475                }
15476            } else {
15477                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15478            }
15479        }
15480        return procs;
15481    }
15482
15483    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15484            PrintWriter pw, String[] args) {
15485        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15486        if (procs == null) {
15487            pw.println("No process found for: " + args[0]);
15488            return;
15489        }
15490
15491        long uptime = SystemClock.uptimeMillis();
15492        long realtime = SystemClock.elapsedRealtime();
15493        pw.println("Applications Graphics Acceleration Info:");
15494        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15495
15496        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15497            ProcessRecord r = procs.get(i);
15498            if (r.thread != null) {
15499                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15500                pw.flush();
15501                try {
15502                    TransferPipe tp = new TransferPipe();
15503                    try {
15504                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15505                        tp.go(fd);
15506                    } finally {
15507                        tp.kill();
15508                    }
15509                } catch (IOException e) {
15510                    pw.println("Failure while dumping the app: " + r);
15511                    pw.flush();
15512                } catch (RemoteException e) {
15513                    pw.println("Got a RemoteException while dumping the app " + r);
15514                    pw.flush();
15515                }
15516            }
15517        }
15518    }
15519
15520    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15521        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15522        if (procs == null) {
15523            pw.println("No process found for: " + args[0]);
15524            return;
15525        }
15526
15527        pw.println("Applications Database Info:");
15528
15529        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15530            ProcessRecord r = procs.get(i);
15531            if (r.thread != null) {
15532                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15533                pw.flush();
15534                try {
15535                    TransferPipe tp = new TransferPipe();
15536                    try {
15537                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15538                        tp.go(fd);
15539                    } finally {
15540                        tp.kill();
15541                    }
15542                } catch (IOException e) {
15543                    pw.println("Failure while dumping the app: " + r);
15544                    pw.flush();
15545                } catch (RemoteException e) {
15546                    pw.println("Got a RemoteException while dumping the app " + r);
15547                    pw.flush();
15548                }
15549            }
15550        }
15551    }
15552
15553    final static class MemItem {
15554        final boolean isProc;
15555        final String label;
15556        final String shortLabel;
15557        final long pss;
15558        final long swapPss;
15559        final int id;
15560        final boolean hasActivities;
15561        ArrayList<MemItem> subitems;
15562
15563        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15564                boolean _hasActivities) {
15565            isProc = true;
15566            label = _label;
15567            shortLabel = _shortLabel;
15568            pss = _pss;
15569            swapPss = _swapPss;
15570            id = _id;
15571            hasActivities = _hasActivities;
15572        }
15573
15574        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15575            isProc = false;
15576            label = _label;
15577            shortLabel = _shortLabel;
15578            pss = _pss;
15579            swapPss = _swapPss;
15580            id = _id;
15581            hasActivities = false;
15582        }
15583    }
15584
15585    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15586            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15587        if (sort && !isCompact) {
15588            Collections.sort(items, new Comparator<MemItem>() {
15589                @Override
15590                public int compare(MemItem lhs, MemItem rhs) {
15591                    if (lhs.pss < rhs.pss) {
15592                        return 1;
15593                    } else if (lhs.pss > rhs.pss) {
15594                        return -1;
15595                    }
15596                    return 0;
15597                }
15598            });
15599        }
15600
15601        for (int i=0; i<items.size(); i++) {
15602            MemItem mi = items.get(i);
15603            if (!isCompact) {
15604                if (dumpSwapPss) {
15605                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15606                            mi.label, stringifyKBSize(mi.swapPss));
15607                } else {
15608                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15609                }
15610            } else if (mi.isProc) {
15611                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15612                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15613                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15614                pw.println(mi.hasActivities ? ",a" : ",e");
15615            } else {
15616                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15617                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15618            }
15619            if (mi.subitems != null) {
15620                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15621                        true, isCompact, dumpSwapPss);
15622            }
15623        }
15624    }
15625
15626    // These are in KB.
15627    static final long[] DUMP_MEM_BUCKETS = new long[] {
15628        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15629        120*1024, 160*1024, 200*1024,
15630        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15631        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15632    };
15633
15634    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15635            boolean stackLike) {
15636        int start = label.lastIndexOf('.');
15637        if (start >= 0) start++;
15638        else start = 0;
15639        int end = label.length();
15640        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15641            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15642                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15643                out.append(bucket);
15644                out.append(stackLike ? "MB." : "MB ");
15645                out.append(label, start, end);
15646                return;
15647            }
15648        }
15649        out.append(memKB/1024);
15650        out.append(stackLike ? "MB." : "MB ");
15651        out.append(label, start, end);
15652    }
15653
15654    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15655            ProcessList.NATIVE_ADJ,
15656            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15657            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15658            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15659            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15660            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15661            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15662    };
15663    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15664            "Native",
15665            "System", "Persistent", "Persistent Service", "Foreground",
15666            "Visible", "Perceptible",
15667            "Heavy Weight", "Backup",
15668            "A Services", "Home",
15669            "Previous", "B Services", "Cached"
15670    };
15671    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15672            "native",
15673            "sys", "pers", "persvc", "fore",
15674            "vis", "percept",
15675            "heavy", "backup",
15676            "servicea", "home",
15677            "prev", "serviceb", "cached"
15678    };
15679
15680    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15681            long realtime, boolean isCheckinRequest, boolean isCompact) {
15682        if (isCompact) {
15683            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15684        }
15685        if (isCheckinRequest || isCompact) {
15686            // short checkin version
15687            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15688        } else {
15689            pw.println("Applications Memory Usage (in Kilobytes):");
15690            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15691        }
15692    }
15693
15694    private static final int KSM_SHARED = 0;
15695    private static final int KSM_SHARING = 1;
15696    private static final int KSM_UNSHARED = 2;
15697    private static final int KSM_VOLATILE = 3;
15698
15699    private final long[] getKsmInfo() {
15700        long[] longOut = new long[4];
15701        final int[] SINGLE_LONG_FORMAT = new int[] {
15702            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15703        };
15704        long[] longTmp = new long[1];
15705        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15706                SINGLE_LONG_FORMAT, null, longTmp, null);
15707        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15708        longTmp[0] = 0;
15709        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15710                SINGLE_LONG_FORMAT, null, longTmp, null);
15711        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15712        longTmp[0] = 0;
15713        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15714                SINGLE_LONG_FORMAT, null, longTmp, null);
15715        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15716        longTmp[0] = 0;
15717        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15718                SINGLE_LONG_FORMAT, null, longTmp, null);
15719        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15720        return longOut;
15721    }
15722
15723    private static String stringifySize(long size, int order) {
15724        Locale locale = Locale.US;
15725        switch (order) {
15726            case 1:
15727                return String.format(locale, "%,13d", size);
15728            case 1024:
15729                return String.format(locale, "%,9dK", size / 1024);
15730            case 1024 * 1024:
15731                return String.format(locale, "%,5dM", size / 1024 / 1024);
15732            case 1024 * 1024 * 1024:
15733                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15734            default:
15735                throw new IllegalArgumentException("Invalid size order");
15736        }
15737    }
15738
15739    private static String stringifyKBSize(long size) {
15740        return stringifySize(size * 1024, 1024);
15741    }
15742
15743    // Update this version number in case you change the 'compact' format
15744    private static final int MEMINFO_COMPACT_VERSION = 1;
15745
15746    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15747            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15748        boolean dumpDetails = false;
15749        boolean dumpFullDetails = false;
15750        boolean dumpDalvik = false;
15751        boolean dumpSummaryOnly = false;
15752        boolean dumpUnreachable = false;
15753        boolean oomOnly = false;
15754        boolean isCompact = false;
15755        boolean localOnly = false;
15756        boolean packages = false;
15757        boolean isCheckinRequest = false;
15758        boolean dumpSwapPss = false;
15759
15760        int opti = 0;
15761        while (opti < args.length) {
15762            String opt = args[opti];
15763            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15764                break;
15765            }
15766            opti++;
15767            if ("-a".equals(opt)) {
15768                dumpDetails = true;
15769                dumpFullDetails = true;
15770                dumpDalvik = true;
15771                dumpSwapPss = true;
15772            } else if ("-d".equals(opt)) {
15773                dumpDalvik = true;
15774            } else if ("-c".equals(opt)) {
15775                isCompact = true;
15776            } else if ("-s".equals(opt)) {
15777                dumpDetails = true;
15778                dumpSummaryOnly = true;
15779            } else if ("-S".equals(opt)) {
15780                dumpSwapPss = true;
15781            } else if ("--unreachable".equals(opt)) {
15782                dumpUnreachable = true;
15783            } else if ("--oom".equals(opt)) {
15784                oomOnly = true;
15785            } else if ("--local".equals(opt)) {
15786                localOnly = true;
15787            } else if ("--package".equals(opt)) {
15788                packages = true;
15789            } else if ("--checkin".equals(opt)) {
15790                isCheckinRequest = true;
15791
15792            } else if ("-h".equals(opt)) {
15793                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15794                pw.println("  -a: include all available information for each process.");
15795                pw.println("  -d: include dalvik details.");
15796                pw.println("  -c: dump in a compact machine-parseable representation.");
15797                pw.println("  -s: dump only summary of application memory usage.");
15798                pw.println("  -S: dump also SwapPss.");
15799                pw.println("  --oom: only show processes organized by oom adj.");
15800                pw.println("  --local: only collect details locally, don't call process.");
15801                pw.println("  --package: interpret process arg as package, dumping all");
15802                pw.println("             processes that have loaded that package.");
15803                pw.println("  --checkin: dump data for a checkin");
15804                pw.println("If [process] is specified it can be the name or ");
15805                pw.println("pid of a specific process to dump.");
15806                return;
15807            } else {
15808                pw.println("Unknown argument: " + opt + "; use -h for help");
15809            }
15810        }
15811
15812        long uptime = SystemClock.uptimeMillis();
15813        long realtime = SystemClock.elapsedRealtime();
15814        final long[] tmpLong = new long[1];
15815
15816        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15817        if (procs == null) {
15818            // No Java processes.  Maybe they want to print a native process.
15819            if (args != null && args.length > opti
15820                    && args[opti].charAt(0) != '-') {
15821                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15822                        = new ArrayList<ProcessCpuTracker.Stats>();
15823                updateCpuStatsNow();
15824                int findPid = -1;
15825                try {
15826                    findPid = Integer.parseInt(args[opti]);
15827                } catch (NumberFormatException e) {
15828                }
15829                synchronized (mProcessCpuTracker) {
15830                    final int N = mProcessCpuTracker.countStats();
15831                    for (int i=0; i<N; i++) {
15832                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15833                        if (st.pid == findPid || (st.baseName != null
15834                                && st.baseName.equals(args[opti]))) {
15835                            nativeProcs.add(st);
15836                        }
15837                    }
15838                }
15839                if (nativeProcs.size() > 0) {
15840                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15841                            isCompact);
15842                    Debug.MemoryInfo mi = null;
15843                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15844                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15845                        final int pid = r.pid;
15846                        if (!isCheckinRequest && dumpDetails) {
15847                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15848                        }
15849                        if (mi == null) {
15850                            mi = new Debug.MemoryInfo();
15851                        }
15852                        if (dumpDetails || (!brief && !oomOnly)) {
15853                            Debug.getMemoryInfo(pid, mi);
15854                        } else {
15855                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15856                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15857                        }
15858                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15859                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15860                        if (isCheckinRequest) {
15861                            pw.println();
15862                        }
15863                    }
15864                    return;
15865                }
15866            }
15867            pw.println("No process found for: " + args[opti]);
15868            return;
15869        }
15870
15871        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15872            dumpDetails = true;
15873        }
15874
15875        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15876
15877        String[] innerArgs = new String[args.length-opti];
15878        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15879
15880        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15881        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15882        long nativePss = 0;
15883        long nativeSwapPss = 0;
15884        long dalvikPss = 0;
15885        long dalvikSwapPss = 0;
15886        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15887                EmptyArray.LONG;
15888        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15889                EmptyArray.LONG;
15890        long otherPss = 0;
15891        long otherSwapPss = 0;
15892        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15893        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15894
15895        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15896        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15897        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15898                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15899
15900        long totalPss = 0;
15901        long totalSwapPss = 0;
15902        long cachedPss = 0;
15903        long cachedSwapPss = 0;
15904        boolean hasSwapPss = false;
15905
15906        Debug.MemoryInfo mi = null;
15907        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15908            final ProcessRecord r = procs.get(i);
15909            final IApplicationThread thread;
15910            final int pid;
15911            final int oomAdj;
15912            final boolean hasActivities;
15913            synchronized (this) {
15914                thread = r.thread;
15915                pid = r.pid;
15916                oomAdj = r.getSetAdjWithServices();
15917                hasActivities = r.activities.size() > 0;
15918            }
15919            if (thread != null) {
15920                if (!isCheckinRequest && dumpDetails) {
15921                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15922                }
15923                if (mi == null) {
15924                    mi = new Debug.MemoryInfo();
15925                }
15926                if (dumpDetails || (!brief && !oomOnly)) {
15927                    Debug.getMemoryInfo(pid, mi);
15928                    hasSwapPss = mi.hasSwappedOutPss;
15929                } else {
15930                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15931                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15932                }
15933                if (dumpDetails) {
15934                    if (localOnly) {
15935                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15936                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15937                        if (isCheckinRequest) {
15938                            pw.println();
15939                        }
15940                    } else {
15941                        try {
15942                            pw.flush();
15943                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15944                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15945                        } catch (RemoteException e) {
15946                            if (!isCheckinRequest) {
15947                                pw.println("Got RemoteException!");
15948                                pw.flush();
15949                            }
15950                        }
15951                    }
15952                }
15953
15954                final long myTotalPss = mi.getTotalPss();
15955                final long myTotalUss = mi.getTotalUss();
15956                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15957
15958                synchronized (this) {
15959                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15960                        // Record this for posterity if the process has been stable.
15961                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15962                    }
15963                }
15964
15965                if (!isCheckinRequest && mi != null) {
15966                    totalPss += myTotalPss;
15967                    totalSwapPss += myTotalSwapPss;
15968                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15969                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15970                            myTotalSwapPss, pid, hasActivities);
15971                    procMems.add(pssItem);
15972                    procMemsMap.put(pid, pssItem);
15973
15974                    nativePss += mi.nativePss;
15975                    nativeSwapPss += mi.nativeSwappedOutPss;
15976                    dalvikPss += mi.dalvikPss;
15977                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15978                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15979                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15980                        dalvikSubitemSwapPss[j] +=
15981                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15982                    }
15983                    otherPss += mi.otherPss;
15984                    otherSwapPss += mi.otherSwappedOutPss;
15985                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15986                        long mem = mi.getOtherPss(j);
15987                        miscPss[j] += mem;
15988                        otherPss -= mem;
15989                        mem = mi.getOtherSwappedOutPss(j);
15990                        miscSwapPss[j] += mem;
15991                        otherSwapPss -= mem;
15992                    }
15993
15994                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15995                        cachedPss += myTotalPss;
15996                        cachedSwapPss += myTotalSwapPss;
15997                    }
15998
15999                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16000                        if (oomIndex == (oomPss.length - 1)
16001                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16002                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16003                            oomPss[oomIndex] += myTotalPss;
16004                            oomSwapPss[oomIndex] += myTotalSwapPss;
16005                            if (oomProcs[oomIndex] == null) {
16006                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16007                            }
16008                            oomProcs[oomIndex].add(pssItem);
16009                            break;
16010                        }
16011                    }
16012                }
16013            }
16014        }
16015
16016        long nativeProcTotalPss = 0;
16017
16018        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16019            // If we are showing aggregations, also look for native processes to
16020            // include so that our aggregations are more accurate.
16021            updateCpuStatsNow();
16022            mi = null;
16023            synchronized (mProcessCpuTracker) {
16024                final int N = mProcessCpuTracker.countStats();
16025                for (int i=0; i<N; i++) {
16026                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16027                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16028                        if (mi == null) {
16029                            mi = new Debug.MemoryInfo();
16030                        }
16031                        if (!brief && !oomOnly) {
16032                            Debug.getMemoryInfo(st.pid, mi);
16033                        } else {
16034                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16035                            mi.nativePrivateDirty = (int)tmpLong[0];
16036                        }
16037
16038                        final long myTotalPss = mi.getTotalPss();
16039                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16040                        totalPss += myTotalPss;
16041                        nativeProcTotalPss += myTotalPss;
16042
16043                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16044                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16045                        procMems.add(pssItem);
16046
16047                        nativePss += mi.nativePss;
16048                        nativeSwapPss += mi.nativeSwappedOutPss;
16049                        dalvikPss += mi.dalvikPss;
16050                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16051                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16052                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16053                            dalvikSubitemSwapPss[j] +=
16054                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16055                        }
16056                        otherPss += mi.otherPss;
16057                        otherSwapPss += mi.otherSwappedOutPss;
16058                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16059                            long mem = mi.getOtherPss(j);
16060                            miscPss[j] += mem;
16061                            otherPss -= mem;
16062                            mem = mi.getOtherSwappedOutPss(j);
16063                            miscSwapPss[j] += mem;
16064                            otherSwapPss -= mem;
16065                        }
16066                        oomPss[0] += myTotalPss;
16067                        oomSwapPss[0] += myTotalSwapPss;
16068                        if (oomProcs[0] == null) {
16069                            oomProcs[0] = new ArrayList<MemItem>();
16070                        }
16071                        oomProcs[0].add(pssItem);
16072                    }
16073                }
16074            }
16075
16076            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16077
16078            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16079            final MemItem dalvikItem =
16080                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16081            if (dalvikSubitemPss.length > 0) {
16082                dalvikItem.subitems = new ArrayList<MemItem>();
16083                for (int j=0; j<dalvikSubitemPss.length; j++) {
16084                    final String name = Debug.MemoryInfo.getOtherLabel(
16085                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16086                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16087                                    dalvikSubitemSwapPss[j], j));
16088                }
16089            }
16090            catMems.add(dalvikItem);
16091            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16092            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16093                String label = Debug.MemoryInfo.getOtherLabel(j);
16094                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16095            }
16096
16097            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16098            for (int j=0; j<oomPss.length; j++) {
16099                if (oomPss[j] != 0) {
16100                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16101                            : DUMP_MEM_OOM_LABEL[j];
16102                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16103                            DUMP_MEM_OOM_ADJ[j]);
16104                    item.subitems = oomProcs[j];
16105                    oomMems.add(item);
16106                }
16107            }
16108
16109            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16110            if (!brief && !oomOnly && !isCompact) {
16111                pw.println();
16112                pw.println("Total PSS by process:");
16113                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16114                pw.println();
16115            }
16116            if (!isCompact) {
16117                pw.println("Total PSS by OOM adjustment:");
16118            }
16119            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16120            if (!brief && !oomOnly) {
16121                PrintWriter out = categoryPw != null ? categoryPw : pw;
16122                if (!isCompact) {
16123                    out.println();
16124                    out.println("Total PSS by category:");
16125                }
16126                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16127            }
16128            if (!isCompact) {
16129                pw.println();
16130            }
16131            MemInfoReader memInfo = new MemInfoReader();
16132            memInfo.readMemInfo();
16133            if (nativeProcTotalPss > 0) {
16134                synchronized (this) {
16135                    final long cachedKb = memInfo.getCachedSizeKb();
16136                    final long freeKb = memInfo.getFreeSizeKb();
16137                    final long zramKb = memInfo.getZramTotalSizeKb();
16138                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16139                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16140                            kernelKb*1024, nativeProcTotalPss*1024);
16141                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16142                            nativeProcTotalPss);
16143                }
16144            }
16145            if (!brief) {
16146                if (!isCompact) {
16147                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16148                    pw.print(" (status ");
16149                    switch (mLastMemoryLevel) {
16150                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16151                            pw.println("normal)");
16152                            break;
16153                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16154                            pw.println("moderate)");
16155                            break;
16156                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16157                            pw.println("low)");
16158                            break;
16159                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16160                            pw.println("critical)");
16161                            break;
16162                        default:
16163                            pw.print(mLastMemoryLevel);
16164                            pw.println(")");
16165                            break;
16166                    }
16167                    pw.print(" Free RAM: ");
16168                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16169                            + memInfo.getFreeSizeKb()));
16170                    pw.print(" (");
16171                    pw.print(stringifyKBSize(cachedPss));
16172                    pw.print(" cached pss + ");
16173                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16174                    pw.print(" cached kernel + ");
16175                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16176                    pw.println(" free)");
16177                } else {
16178                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16179                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16180                            + memInfo.getFreeSizeKb()); pw.print(",");
16181                    pw.println(totalPss - cachedPss);
16182                }
16183            }
16184            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16185                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16186                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16187            if (!isCompact) {
16188                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16189                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16190                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16191                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16192                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16193            } else {
16194                pw.print("lostram,"); pw.println(lostRAM);
16195            }
16196            if (!brief) {
16197                if (memInfo.getZramTotalSizeKb() != 0) {
16198                    if (!isCompact) {
16199                        pw.print("     ZRAM: ");
16200                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16201                                pw.print(" physical used for ");
16202                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16203                                        - memInfo.getSwapFreeSizeKb()));
16204                                pw.print(" in swap (");
16205                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16206                                pw.println(" total swap)");
16207                    } else {
16208                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16209                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16210                                pw.println(memInfo.getSwapFreeSizeKb());
16211                    }
16212                }
16213                final long[] ksm = getKsmInfo();
16214                if (!isCompact) {
16215                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16216                            || ksm[KSM_VOLATILE] != 0) {
16217                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16218                                pw.print(" saved from shared ");
16219                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16220                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16221                                pw.print(" unshared; ");
16222                                pw.print(stringifyKBSize(
16223                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16224                    }
16225                    pw.print("   Tuning: ");
16226                    pw.print(ActivityManager.staticGetMemoryClass());
16227                    pw.print(" (large ");
16228                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16229                    pw.print("), oom ");
16230                    pw.print(stringifySize(
16231                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16232                    pw.print(", restore limit ");
16233                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16234                    if (ActivityManager.isLowRamDeviceStatic()) {
16235                        pw.print(" (low-ram)");
16236                    }
16237                    if (ActivityManager.isHighEndGfx()) {
16238                        pw.print(" (high-end-gfx)");
16239                    }
16240                    pw.println();
16241                } else {
16242                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16243                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16244                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16245                    pw.print("tuning,");
16246                    pw.print(ActivityManager.staticGetMemoryClass());
16247                    pw.print(',');
16248                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16249                    pw.print(',');
16250                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16251                    if (ActivityManager.isLowRamDeviceStatic()) {
16252                        pw.print(",low-ram");
16253                    }
16254                    if (ActivityManager.isHighEndGfx()) {
16255                        pw.print(",high-end-gfx");
16256                    }
16257                    pw.println();
16258                }
16259            }
16260        }
16261    }
16262
16263    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16264            long memtrack, String name) {
16265        sb.append("  ");
16266        sb.append(ProcessList.makeOomAdjString(oomAdj));
16267        sb.append(' ');
16268        sb.append(ProcessList.makeProcStateString(procState));
16269        sb.append(' ');
16270        ProcessList.appendRamKb(sb, pss);
16271        sb.append(": ");
16272        sb.append(name);
16273        if (memtrack > 0) {
16274            sb.append(" (");
16275            sb.append(stringifyKBSize(memtrack));
16276            sb.append(" memtrack)");
16277        }
16278    }
16279
16280    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16281        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16282        sb.append(" (pid ");
16283        sb.append(mi.pid);
16284        sb.append(") ");
16285        sb.append(mi.adjType);
16286        sb.append('\n');
16287        if (mi.adjReason != null) {
16288            sb.append("                      ");
16289            sb.append(mi.adjReason);
16290            sb.append('\n');
16291        }
16292    }
16293
16294    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16295        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16296        for (int i=0, N=memInfos.size(); i<N; i++) {
16297            ProcessMemInfo mi = memInfos.get(i);
16298            infoMap.put(mi.pid, mi);
16299        }
16300        updateCpuStatsNow();
16301        long[] memtrackTmp = new long[1];
16302        synchronized (mProcessCpuTracker) {
16303            final int N = mProcessCpuTracker.countStats();
16304            for (int i=0; i<N; i++) {
16305                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16306                if (st.vsize > 0) {
16307                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16308                    if (pss > 0) {
16309                        if (infoMap.indexOfKey(st.pid) < 0) {
16310                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16311                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16312                            mi.pss = pss;
16313                            mi.memtrack = memtrackTmp[0];
16314                            memInfos.add(mi);
16315                        }
16316                    }
16317                }
16318            }
16319        }
16320
16321        long totalPss = 0;
16322        long totalMemtrack = 0;
16323        for (int i=0, N=memInfos.size(); i<N; i++) {
16324            ProcessMemInfo mi = memInfos.get(i);
16325            if (mi.pss == 0) {
16326                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16327                mi.memtrack = memtrackTmp[0];
16328            }
16329            totalPss += mi.pss;
16330            totalMemtrack += mi.memtrack;
16331        }
16332        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16333            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16334                if (lhs.oomAdj != rhs.oomAdj) {
16335                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16336                }
16337                if (lhs.pss != rhs.pss) {
16338                    return lhs.pss < rhs.pss ? 1 : -1;
16339                }
16340                return 0;
16341            }
16342        });
16343
16344        StringBuilder tag = new StringBuilder(128);
16345        StringBuilder stack = new StringBuilder(128);
16346        tag.append("Low on memory -- ");
16347        appendMemBucket(tag, totalPss, "total", false);
16348        appendMemBucket(stack, totalPss, "total", true);
16349
16350        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16351        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16352        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16353
16354        boolean firstLine = true;
16355        int lastOomAdj = Integer.MIN_VALUE;
16356        long extraNativeRam = 0;
16357        long extraNativeMemtrack = 0;
16358        long cachedPss = 0;
16359        for (int i=0, N=memInfos.size(); i<N; i++) {
16360            ProcessMemInfo mi = memInfos.get(i);
16361
16362            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16363                cachedPss += mi.pss;
16364            }
16365
16366            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16367                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16368                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16369                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16370                if (lastOomAdj != mi.oomAdj) {
16371                    lastOomAdj = mi.oomAdj;
16372                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16373                        tag.append(" / ");
16374                    }
16375                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16376                        if (firstLine) {
16377                            stack.append(":");
16378                            firstLine = false;
16379                        }
16380                        stack.append("\n\t at ");
16381                    } else {
16382                        stack.append("$");
16383                    }
16384                } else {
16385                    tag.append(" ");
16386                    stack.append("$");
16387                }
16388                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16389                    appendMemBucket(tag, mi.pss, mi.name, false);
16390                }
16391                appendMemBucket(stack, mi.pss, mi.name, true);
16392                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16393                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16394                    stack.append("(");
16395                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16396                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16397                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16398                            stack.append(":");
16399                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16400                        }
16401                    }
16402                    stack.append(")");
16403                }
16404            }
16405
16406            appendMemInfo(fullNativeBuilder, mi);
16407            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16408                // The short form only has native processes that are >= 512K.
16409                if (mi.pss >= 512) {
16410                    appendMemInfo(shortNativeBuilder, mi);
16411                } else {
16412                    extraNativeRam += mi.pss;
16413                    extraNativeMemtrack += mi.memtrack;
16414                }
16415            } else {
16416                // Short form has all other details, but if we have collected RAM
16417                // from smaller native processes let's dump a summary of that.
16418                if (extraNativeRam > 0) {
16419                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16420                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16421                    shortNativeBuilder.append('\n');
16422                    extraNativeRam = 0;
16423                }
16424                appendMemInfo(fullJavaBuilder, mi);
16425            }
16426        }
16427
16428        fullJavaBuilder.append("           ");
16429        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16430        fullJavaBuilder.append(": TOTAL");
16431        if (totalMemtrack > 0) {
16432            fullJavaBuilder.append(" (");
16433            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16434            fullJavaBuilder.append(" memtrack)");
16435        } else {
16436        }
16437        fullJavaBuilder.append("\n");
16438
16439        MemInfoReader memInfo = new MemInfoReader();
16440        memInfo.readMemInfo();
16441        final long[] infos = memInfo.getRawInfo();
16442
16443        StringBuilder memInfoBuilder = new StringBuilder(1024);
16444        Debug.getMemInfo(infos);
16445        memInfoBuilder.append("  MemInfo: ");
16446        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16447        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16448        memInfoBuilder.append(stringifyKBSize(
16449                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16450        memInfoBuilder.append(stringifyKBSize(
16451                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16452        memInfoBuilder.append(stringifyKBSize(
16453                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16454        memInfoBuilder.append("           ");
16455        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16456        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16457        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16458        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16459        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16460            memInfoBuilder.append("  ZRAM: ");
16461            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16462            memInfoBuilder.append(" RAM, ");
16463            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16464            memInfoBuilder.append(" swap total, ");
16465            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16466            memInfoBuilder.append(" swap free\n");
16467        }
16468        final long[] ksm = getKsmInfo();
16469        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16470                || ksm[KSM_VOLATILE] != 0) {
16471            memInfoBuilder.append("  KSM: ");
16472            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16473            memInfoBuilder.append(" saved from shared ");
16474            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16475            memInfoBuilder.append("\n       ");
16476            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16477            memInfoBuilder.append(" unshared; ");
16478            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16479            memInfoBuilder.append(" volatile\n");
16480        }
16481        memInfoBuilder.append("  Free RAM: ");
16482        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16483                + memInfo.getFreeSizeKb()));
16484        memInfoBuilder.append("\n");
16485        memInfoBuilder.append("  Used RAM: ");
16486        memInfoBuilder.append(stringifyKBSize(
16487                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16488        memInfoBuilder.append("\n");
16489        memInfoBuilder.append("  Lost RAM: ");
16490        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16491                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16492                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16493        memInfoBuilder.append("\n");
16494        Slog.i(TAG, "Low on memory:");
16495        Slog.i(TAG, shortNativeBuilder.toString());
16496        Slog.i(TAG, fullJavaBuilder.toString());
16497        Slog.i(TAG, memInfoBuilder.toString());
16498
16499        StringBuilder dropBuilder = new StringBuilder(1024);
16500        /*
16501        StringWriter oomSw = new StringWriter();
16502        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16503        StringWriter catSw = new StringWriter();
16504        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16505        String[] emptyArgs = new String[] { };
16506        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16507        oomPw.flush();
16508        String oomString = oomSw.toString();
16509        */
16510        dropBuilder.append("Low on memory:");
16511        dropBuilder.append(stack);
16512        dropBuilder.append('\n');
16513        dropBuilder.append(fullNativeBuilder);
16514        dropBuilder.append(fullJavaBuilder);
16515        dropBuilder.append('\n');
16516        dropBuilder.append(memInfoBuilder);
16517        dropBuilder.append('\n');
16518        /*
16519        dropBuilder.append(oomString);
16520        dropBuilder.append('\n');
16521        */
16522        StringWriter catSw = new StringWriter();
16523        synchronized (ActivityManagerService.this) {
16524            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16525            String[] emptyArgs = new String[] { };
16526            catPw.println();
16527            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16528            catPw.println();
16529            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16530                    false, null).dumpLocked();
16531            catPw.println();
16532            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16533            catPw.flush();
16534        }
16535        dropBuilder.append(catSw.toString());
16536        addErrorToDropBox("lowmem", null, "system_server", null,
16537                null, tag.toString(), dropBuilder.toString(), null, null);
16538        //Slog.i(TAG, "Sent to dropbox:");
16539        //Slog.i(TAG, dropBuilder.toString());
16540        synchronized (ActivityManagerService.this) {
16541            long now = SystemClock.uptimeMillis();
16542            if (mLastMemUsageReportTime < now) {
16543                mLastMemUsageReportTime = now;
16544            }
16545        }
16546    }
16547
16548    /**
16549     * Searches array of arguments for the specified string
16550     * @param args array of argument strings
16551     * @param value value to search for
16552     * @return true if the value is contained in the array
16553     */
16554    private static boolean scanArgs(String[] args, String value) {
16555        if (args != null) {
16556            for (String arg : args) {
16557                if (value.equals(arg)) {
16558                    return true;
16559                }
16560            }
16561        }
16562        return false;
16563    }
16564
16565    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16566            ContentProviderRecord cpr, boolean always) {
16567        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16568
16569        if (!inLaunching || always) {
16570            synchronized (cpr) {
16571                cpr.launchingApp = null;
16572                cpr.notifyAll();
16573            }
16574            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16575            String names[] = cpr.info.authority.split(";");
16576            for (int j = 0; j < names.length; j++) {
16577                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16578            }
16579        }
16580
16581        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16582            ContentProviderConnection conn = cpr.connections.get(i);
16583            if (conn.waiting) {
16584                // If this connection is waiting for the provider, then we don't
16585                // need to mess with its process unless we are always removing
16586                // or for some reason the provider is not currently launching.
16587                if (inLaunching && !always) {
16588                    continue;
16589                }
16590            }
16591            ProcessRecord capp = conn.client;
16592            conn.dead = true;
16593            if (conn.stableCount > 0) {
16594                if (!capp.persistent && capp.thread != null
16595                        && capp.pid != 0
16596                        && capp.pid != MY_PID) {
16597                    capp.kill("depends on provider "
16598                            + cpr.name.flattenToShortString()
16599                            + " in dying proc " + (proc != null ? proc.processName : "??")
16600                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16601                }
16602            } else if (capp.thread != null && conn.provider.provider != null) {
16603                try {
16604                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16605                } catch (RemoteException e) {
16606                }
16607                // In the protocol here, we don't expect the client to correctly
16608                // clean up this connection, we'll just remove it.
16609                cpr.connections.remove(i);
16610                if (conn.client.conProviders.remove(conn)) {
16611                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16612                }
16613            }
16614        }
16615
16616        if (inLaunching && always) {
16617            mLaunchingProviders.remove(cpr);
16618        }
16619        return inLaunching;
16620    }
16621
16622    /**
16623     * Main code for cleaning up a process when it has gone away.  This is
16624     * called both as a result of the process dying, or directly when stopping
16625     * a process when running in single process mode.
16626     *
16627     * @return Returns true if the given process has been restarted, so the
16628     * app that was passed in must remain on the process lists.
16629     */
16630    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16631            boolean restarting, boolean allowRestart, int index) {
16632        if (index >= 0) {
16633            removeLruProcessLocked(app);
16634            ProcessList.remove(app.pid);
16635        }
16636
16637        mProcessesToGc.remove(app);
16638        mPendingPssProcesses.remove(app);
16639
16640        // Dismiss any open dialogs.
16641        if (app.crashDialog != null && !app.forceCrashReport) {
16642            app.crashDialog.dismiss();
16643            app.crashDialog = null;
16644        }
16645        if (app.anrDialog != null) {
16646            app.anrDialog.dismiss();
16647            app.anrDialog = null;
16648        }
16649        if (app.waitDialog != null) {
16650            app.waitDialog.dismiss();
16651            app.waitDialog = null;
16652        }
16653
16654        app.crashing = false;
16655        app.notResponding = false;
16656
16657        app.resetPackageList(mProcessStats);
16658        app.unlinkDeathRecipient();
16659        app.makeInactive(mProcessStats);
16660        app.waitingToKill = null;
16661        app.forcingToForeground = null;
16662        updateProcessForegroundLocked(app, false, false);
16663        app.foregroundActivities = false;
16664        app.hasShownUi = false;
16665        app.treatLikeActivity = false;
16666        app.hasAboveClient = false;
16667        app.hasClientActivities = false;
16668
16669        mServices.killServicesLocked(app, allowRestart);
16670
16671        boolean restart = false;
16672
16673        // Remove published content providers.
16674        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16675            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16676            final boolean always = app.bad || !allowRestart;
16677            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16678            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16679                // We left the provider in the launching list, need to
16680                // restart it.
16681                restart = true;
16682            }
16683
16684            cpr.provider = null;
16685            cpr.proc = null;
16686        }
16687        app.pubProviders.clear();
16688
16689        // Take care of any launching providers waiting for this process.
16690        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16691            restart = true;
16692        }
16693
16694        // Unregister from connected content providers.
16695        if (!app.conProviders.isEmpty()) {
16696            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16697                ContentProviderConnection conn = app.conProviders.get(i);
16698                conn.provider.connections.remove(conn);
16699                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16700                        conn.provider.name);
16701            }
16702            app.conProviders.clear();
16703        }
16704
16705        // At this point there may be remaining entries in mLaunchingProviders
16706        // where we were the only one waiting, so they are no longer of use.
16707        // Look for these and clean up if found.
16708        // XXX Commented out for now.  Trying to figure out a way to reproduce
16709        // the actual situation to identify what is actually going on.
16710        if (false) {
16711            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16712                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16713                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16714                    synchronized (cpr) {
16715                        cpr.launchingApp = null;
16716                        cpr.notifyAll();
16717                    }
16718                }
16719            }
16720        }
16721
16722        skipCurrentReceiverLocked(app);
16723
16724        // Unregister any receivers.
16725        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16726            removeReceiverLocked(app.receivers.valueAt(i));
16727        }
16728        app.receivers.clear();
16729
16730        // If the app is undergoing backup, tell the backup manager about it
16731        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16732            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16733                    + mBackupTarget.appInfo + " died during backup");
16734            try {
16735                IBackupManager bm = IBackupManager.Stub.asInterface(
16736                        ServiceManager.getService(Context.BACKUP_SERVICE));
16737                bm.agentDisconnected(app.info.packageName);
16738            } catch (RemoteException e) {
16739                // can't happen; backup manager is local
16740            }
16741        }
16742
16743        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16744            ProcessChangeItem item = mPendingProcessChanges.get(i);
16745            if (item.pid == app.pid) {
16746                mPendingProcessChanges.remove(i);
16747                mAvailProcessChanges.add(item);
16748            }
16749        }
16750        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16751                null).sendToTarget();
16752
16753        // If the caller is restarting this app, then leave it in its
16754        // current lists and let the caller take care of it.
16755        if (restarting) {
16756            return false;
16757        }
16758
16759        if (!app.persistent || app.isolated) {
16760            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16761                    "Removing non-persistent process during cleanup: " + app);
16762            removeProcessNameLocked(app.processName, app.uid);
16763            if (mHeavyWeightProcess == app) {
16764                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16765                        mHeavyWeightProcess.userId, 0));
16766                mHeavyWeightProcess = null;
16767            }
16768        } else if (!app.removed) {
16769            // This app is persistent, so we need to keep its record around.
16770            // If it is not already on the pending app list, add it there
16771            // and start a new process for it.
16772            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16773                mPersistentStartingProcesses.add(app);
16774                restart = true;
16775            }
16776        }
16777        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16778                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16779        mProcessesOnHold.remove(app);
16780
16781        if (app == mHomeProcess) {
16782            mHomeProcess = null;
16783        }
16784        if (app == mPreviousProcess) {
16785            mPreviousProcess = null;
16786        }
16787
16788        if (restart && !app.isolated) {
16789            // We have components that still need to be running in the
16790            // process, so re-launch it.
16791            if (index < 0) {
16792                ProcessList.remove(app.pid);
16793            }
16794            addProcessNameLocked(app);
16795            startProcessLocked(app, "restart", app.processName);
16796            return true;
16797        } else if (app.pid > 0 && app.pid != MY_PID) {
16798            // Goodbye!
16799            boolean removed;
16800            synchronized (mPidsSelfLocked) {
16801                mPidsSelfLocked.remove(app.pid);
16802                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16803            }
16804            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16805            if (app.isolated) {
16806                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16807            }
16808            app.setPid(0);
16809        }
16810        return false;
16811    }
16812
16813    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16814        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16815            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16816            if (cpr.launchingApp == app) {
16817                return true;
16818            }
16819        }
16820        return false;
16821    }
16822
16823    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16824        // Look through the content providers we are waiting to have launched,
16825        // and if any run in this process then either schedule a restart of
16826        // the process or kill the client waiting for it if this process has
16827        // gone bad.
16828        boolean restart = false;
16829        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16830            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16831            if (cpr.launchingApp == app) {
16832                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16833                    restart = true;
16834                } else {
16835                    removeDyingProviderLocked(app, cpr, true);
16836                }
16837            }
16838        }
16839        return restart;
16840    }
16841
16842    // =========================================================
16843    // SERVICES
16844    // =========================================================
16845
16846    @Override
16847    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16848            int flags) {
16849        enforceNotIsolatedCaller("getServices");
16850        synchronized (this) {
16851            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16852        }
16853    }
16854
16855    @Override
16856    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16857        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16858        synchronized (this) {
16859            return mServices.getRunningServiceControlPanelLocked(name);
16860        }
16861    }
16862
16863    @Override
16864    public ComponentName startService(IApplicationThread caller, Intent service,
16865            String resolvedType, String callingPackage, int userId)
16866            throws TransactionTooLargeException {
16867        enforceNotIsolatedCaller("startService");
16868        // Refuse possible leaked file descriptors
16869        if (service != null && service.hasFileDescriptors() == true) {
16870            throw new IllegalArgumentException("File descriptors passed in Intent");
16871        }
16872
16873        if (callingPackage == null) {
16874            throw new IllegalArgumentException("callingPackage cannot be null");
16875        }
16876
16877        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16878                "startService: " + service + " type=" + resolvedType);
16879        synchronized(this) {
16880            final int callingPid = Binder.getCallingPid();
16881            final int callingUid = Binder.getCallingUid();
16882            final long origId = Binder.clearCallingIdentity();
16883            ComponentName res = mServices.startServiceLocked(caller, service,
16884                    resolvedType, callingPid, callingUid, callingPackage, userId);
16885            Binder.restoreCallingIdentity(origId);
16886            return res;
16887        }
16888    }
16889
16890    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16891            String callingPackage, int userId)
16892            throws TransactionTooLargeException {
16893        synchronized(this) {
16894            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16895                    "startServiceInPackage: " + service + " type=" + resolvedType);
16896            final long origId = Binder.clearCallingIdentity();
16897            ComponentName res = mServices.startServiceLocked(null, service,
16898                    resolvedType, -1, uid, callingPackage, userId);
16899            Binder.restoreCallingIdentity(origId);
16900            return res;
16901        }
16902    }
16903
16904    @Override
16905    public int stopService(IApplicationThread caller, Intent service,
16906            String resolvedType, int userId) {
16907        enforceNotIsolatedCaller("stopService");
16908        // Refuse possible leaked file descriptors
16909        if (service != null && service.hasFileDescriptors() == true) {
16910            throw new IllegalArgumentException("File descriptors passed in Intent");
16911        }
16912
16913        synchronized(this) {
16914            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16915        }
16916    }
16917
16918    @Override
16919    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16920        enforceNotIsolatedCaller("peekService");
16921        // Refuse possible leaked file descriptors
16922        if (service != null && service.hasFileDescriptors() == true) {
16923            throw new IllegalArgumentException("File descriptors passed in Intent");
16924        }
16925
16926        if (callingPackage == null) {
16927            throw new IllegalArgumentException("callingPackage cannot be null");
16928        }
16929
16930        synchronized(this) {
16931            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16932        }
16933    }
16934
16935    @Override
16936    public boolean stopServiceToken(ComponentName className, IBinder token,
16937            int startId) {
16938        synchronized(this) {
16939            return mServices.stopServiceTokenLocked(className, token, startId);
16940        }
16941    }
16942
16943    @Override
16944    public void setServiceForeground(ComponentName className, IBinder token,
16945            int id, Notification notification, int flags) {
16946        synchronized(this) {
16947            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16948        }
16949    }
16950
16951    @Override
16952    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16953            boolean requireFull, String name, String callerPackage) {
16954        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16955                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16956    }
16957
16958    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16959            String className, int flags) {
16960        boolean result = false;
16961        // For apps that don't have pre-defined UIDs, check for permission
16962        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16963            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16964                if (ActivityManager.checkUidPermission(
16965                        INTERACT_ACROSS_USERS,
16966                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16967                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16968                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16969                            + " requests FLAG_SINGLE_USER, but app does not hold "
16970                            + INTERACT_ACROSS_USERS;
16971                    Slog.w(TAG, msg);
16972                    throw new SecurityException(msg);
16973                }
16974                // Permission passed
16975                result = true;
16976            }
16977        } else if ("system".equals(componentProcessName)) {
16978            result = true;
16979        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16980            // Phone app and persistent apps are allowed to export singleuser providers.
16981            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16982                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16983        }
16984        if (DEBUG_MU) Slog.v(TAG_MU,
16985                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16986                + Integer.toHexString(flags) + ") = " + result);
16987        return result;
16988    }
16989
16990    /**
16991     * Checks to see if the caller is in the same app as the singleton
16992     * component, or the component is in a special app. It allows special apps
16993     * to export singleton components but prevents exporting singleton
16994     * components for regular apps.
16995     */
16996    boolean isValidSingletonCall(int callingUid, int componentUid) {
16997        int componentAppId = UserHandle.getAppId(componentUid);
16998        return UserHandle.isSameApp(callingUid, componentUid)
16999                || componentAppId == Process.SYSTEM_UID
17000                || componentAppId == Process.PHONE_UID
17001                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17002                        == PackageManager.PERMISSION_GRANTED;
17003    }
17004
17005    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17006            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17007            int userId) throws TransactionTooLargeException {
17008        enforceNotIsolatedCaller("bindService");
17009
17010        // Refuse possible leaked file descriptors
17011        if (service != null && service.hasFileDescriptors() == true) {
17012            throw new IllegalArgumentException("File descriptors passed in Intent");
17013        }
17014
17015        if (callingPackage == null) {
17016            throw new IllegalArgumentException("callingPackage cannot be null");
17017        }
17018
17019        synchronized(this) {
17020            return mServices.bindServiceLocked(caller, token, service,
17021                    resolvedType, connection, flags, callingPackage, userId);
17022        }
17023    }
17024
17025    public boolean unbindService(IServiceConnection connection) {
17026        synchronized (this) {
17027            return mServices.unbindServiceLocked(connection);
17028        }
17029    }
17030
17031    public void publishService(IBinder token, Intent intent, IBinder service) {
17032        // Refuse possible leaked file descriptors
17033        if (intent != null && intent.hasFileDescriptors() == true) {
17034            throw new IllegalArgumentException("File descriptors passed in Intent");
17035        }
17036
17037        synchronized(this) {
17038            if (!(token instanceof ServiceRecord)) {
17039                throw new IllegalArgumentException("Invalid service token");
17040            }
17041            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17042        }
17043    }
17044
17045    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17046        // Refuse possible leaked file descriptors
17047        if (intent != null && intent.hasFileDescriptors() == true) {
17048            throw new IllegalArgumentException("File descriptors passed in Intent");
17049        }
17050
17051        synchronized(this) {
17052            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17053        }
17054    }
17055
17056    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17057        synchronized(this) {
17058            if (!(token instanceof ServiceRecord)) {
17059                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17060                throw new IllegalArgumentException("Invalid service token");
17061            }
17062            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17063        }
17064    }
17065
17066    // =========================================================
17067    // BACKUP AND RESTORE
17068    // =========================================================
17069
17070    // Cause the target app to be launched if necessary and its backup agent
17071    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17072    // activity manager to announce its creation.
17073    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17074        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17075        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17076
17077        IPackageManager pm = AppGlobals.getPackageManager();
17078        ApplicationInfo app = null;
17079        try {
17080            app = pm.getApplicationInfo(packageName, 0, userId);
17081        } catch (RemoteException e) {
17082            // can't happen; package manager is process-local
17083        }
17084        if (app == null) {
17085            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17086            return false;
17087        }
17088
17089        synchronized(this) {
17090            // !!! TODO: currently no check here that we're already bound
17091            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17092            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17093            synchronized (stats) {
17094                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17095            }
17096
17097            // Backup agent is now in use, its package can't be stopped.
17098            try {
17099                AppGlobals.getPackageManager().setPackageStoppedState(
17100                        app.packageName, false, UserHandle.getUserId(app.uid));
17101            } catch (RemoteException e) {
17102            } catch (IllegalArgumentException e) {
17103                Slog.w(TAG, "Failed trying to unstop package "
17104                        + app.packageName + ": " + e);
17105            }
17106
17107            BackupRecord r = new BackupRecord(ss, app, backupMode);
17108            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17109                    ? new ComponentName(app.packageName, app.backupAgentName)
17110                    : new ComponentName("android", "FullBackupAgent");
17111            // startProcessLocked() returns existing proc's record if it's already running
17112            ProcessRecord proc = startProcessLocked(app.processName, app,
17113                    false, 0, "backup", hostingName, false, false, false);
17114            if (proc == null) {
17115                Slog.e(TAG, "Unable to start backup agent process " + r);
17116                return false;
17117            }
17118
17119            // If the app is a regular app (uid >= 10000) and not the system server or phone
17120            // process, etc, then mark it as being in full backup so that certain calls to the
17121            // process can be blocked. This is not reset to false anywhere because we kill the
17122            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17123            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17124                proc.inFullBackup = true;
17125            }
17126            r.app = proc;
17127            mBackupTarget = r;
17128            mBackupAppName = app.packageName;
17129
17130            // Try not to kill the process during backup
17131            updateOomAdjLocked(proc);
17132
17133            // If the process is already attached, schedule the creation of the backup agent now.
17134            // If it is not yet live, this will be done when it attaches to the framework.
17135            if (proc.thread != null) {
17136                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17137                try {
17138                    proc.thread.scheduleCreateBackupAgent(app,
17139                            compatibilityInfoForPackageLocked(app), backupMode);
17140                } catch (RemoteException e) {
17141                    // Will time out on the backup manager side
17142                }
17143            } else {
17144                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17145            }
17146            // Invariants: at this point, the target app process exists and the application
17147            // is either already running or in the process of coming up.  mBackupTarget and
17148            // mBackupAppName describe the app, so that when it binds back to the AM we
17149            // know that it's scheduled for a backup-agent operation.
17150        }
17151
17152        return true;
17153    }
17154
17155    @Override
17156    public void clearPendingBackup() {
17157        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17158        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17159
17160        synchronized (this) {
17161            mBackupTarget = null;
17162            mBackupAppName = null;
17163        }
17164    }
17165
17166    // A backup agent has just come up
17167    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17168        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17169                + " = " + agent);
17170
17171        synchronized(this) {
17172            if (!agentPackageName.equals(mBackupAppName)) {
17173                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17174                return;
17175            }
17176        }
17177
17178        long oldIdent = Binder.clearCallingIdentity();
17179        try {
17180            IBackupManager bm = IBackupManager.Stub.asInterface(
17181                    ServiceManager.getService(Context.BACKUP_SERVICE));
17182            bm.agentConnected(agentPackageName, agent);
17183        } catch (RemoteException e) {
17184            // can't happen; the backup manager service is local
17185        } catch (Exception e) {
17186            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17187            e.printStackTrace();
17188        } finally {
17189            Binder.restoreCallingIdentity(oldIdent);
17190        }
17191    }
17192
17193    // done with this agent
17194    public void unbindBackupAgent(ApplicationInfo appInfo) {
17195        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17196        if (appInfo == null) {
17197            Slog.w(TAG, "unbind backup agent for null app");
17198            return;
17199        }
17200
17201        synchronized(this) {
17202            try {
17203                if (mBackupAppName == null) {
17204                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17205                    return;
17206                }
17207
17208                if (!mBackupAppName.equals(appInfo.packageName)) {
17209                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17210                    return;
17211                }
17212
17213                // Not backing this app up any more; reset its OOM adjustment
17214                final ProcessRecord proc = mBackupTarget.app;
17215                updateOomAdjLocked(proc);
17216
17217                // If the app crashed during backup, 'thread' will be null here
17218                if (proc.thread != null) {
17219                    try {
17220                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17221                                compatibilityInfoForPackageLocked(appInfo));
17222                    } catch (Exception e) {
17223                        Slog.e(TAG, "Exception when unbinding backup agent:");
17224                        e.printStackTrace();
17225                    }
17226                }
17227            } finally {
17228                mBackupTarget = null;
17229                mBackupAppName = null;
17230            }
17231        }
17232    }
17233    // =========================================================
17234    // BROADCASTS
17235    // =========================================================
17236
17237    boolean isPendingBroadcastProcessLocked(int pid) {
17238        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17239                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17240    }
17241
17242    void skipPendingBroadcastLocked(int pid) {
17243            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17244            for (BroadcastQueue queue : mBroadcastQueues) {
17245                queue.skipPendingBroadcastLocked(pid);
17246            }
17247    }
17248
17249    // The app just attached; send any pending broadcasts that it should receive
17250    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17251        boolean didSomething = false;
17252        for (BroadcastQueue queue : mBroadcastQueues) {
17253            didSomething |= queue.sendPendingBroadcastsLocked(app);
17254        }
17255        return didSomething;
17256    }
17257
17258    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17259            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17260        enforceNotIsolatedCaller("registerReceiver");
17261        ArrayList<Intent> stickyIntents = null;
17262        ProcessRecord callerApp = null;
17263        int callingUid;
17264        int callingPid;
17265        synchronized(this) {
17266            if (caller != null) {
17267                callerApp = getRecordForAppLocked(caller);
17268                if (callerApp == null) {
17269                    throw new SecurityException(
17270                            "Unable to find app for caller " + caller
17271                            + " (pid=" + Binder.getCallingPid()
17272                            + ") when registering receiver " + receiver);
17273                }
17274                if (callerApp.info.uid != Process.SYSTEM_UID &&
17275                        !callerApp.pkgList.containsKey(callerPackage) &&
17276                        !"android".equals(callerPackage)) {
17277                    throw new SecurityException("Given caller package " + callerPackage
17278                            + " is not running in process " + callerApp);
17279                }
17280                callingUid = callerApp.info.uid;
17281                callingPid = callerApp.pid;
17282            } else {
17283                callerPackage = null;
17284                callingUid = Binder.getCallingUid();
17285                callingPid = Binder.getCallingPid();
17286            }
17287
17288            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17289                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17290
17291            Iterator<String> actions = filter.actionsIterator();
17292            if (actions == null) {
17293                ArrayList<String> noAction = new ArrayList<String>(1);
17294                noAction.add(null);
17295                actions = noAction.iterator();
17296            }
17297
17298            // Collect stickies of users
17299            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17300            while (actions.hasNext()) {
17301                String action = actions.next();
17302                for (int id : userIds) {
17303                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17304                    if (stickies != null) {
17305                        ArrayList<Intent> intents = stickies.get(action);
17306                        if (intents != null) {
17307                            if (stickyIntents == null) {
17308                                stickyIntents = new ArrayList<Intent>();
17309                            }
17310                            stickyIntents.addAll(intents);
17311                        }
17312                    }
17313                }
17314            }
17315        }
17316
17317        ArrayList<Intent> allSticky = null;
17318        if (stickyIntents != null) {
17319            final ContentResolver resolver = mContext.getContentResolver();
17320            // Look for any matching sticky broadcasts...
17321            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17322                Intent intent = stickyIntents.get(i);
17323                // If intent has scheme "content", it will need to acccess
17324                // provider that needs to lock mProviderMap in ActivityThread
17325                // and also it may need to wait application response, so we
17326                // cannot lock ActivityManagerService here.
17327                if (filter.match(resolver, intent, true, TAG) >= 0) {
17328                    if (allSticky == null) {
17329                        allSticky = new ArrayList<Intent>();
17330                    }
17331                    allSticky.add(intent);
17332                }
17333            }
17334        }
17335
17336        // The first sticky in the list is returned directly back to the client.
17337        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17338        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17339        if (receiver == null) {
17340            return sticky;
17341        }
17342
17343        synchronized (this) {
17344            if (callerApp != null && (callerApp.thread == null
17345                    || callerApp.thread.asBinder() != caller.asBinder())) {
17346                // Original caller already died
17347                return null;
17348            }
17349            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17350            if (rl == null) {
17351                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17352                        userId, receiver);
17353                if (rl.app != null) {
17354                    rl.app.receivers.add(rl);
17355                } else {
17356                    try {
17357                        receiver.asBinder().linkToDeath(rl, 0);
17358                    } catch (RemoteException e) {
17359                        return sticky;
17360                    }
17361                    rl.linkedToDeath = true;
17362                }
17363                mRegisteredReceivers.put(receiver.asBinder(), rl);
17364            } else if (rl.uid != callingUid) {
17365                throw new IllegalArgumentException(
17366                        "Receiver requested to register for uid " + callingUid
17367                        + " was previously registered for uid " + rl.uid);
17368            } else if (rl.pid != callingPid) {
17369                throw new IllegalArgumentException(
17370                        "Receiver requested to register for pid " + callingPid
17371                        + " was previously registered for pid " + rl.pid);
17372            } else if (rl.userId != userId) {
17373                throw new IllegalArgumentException(
17374                        "Receiver requested to register for user " + userId
17375                        + " was previously registered for user " + rl.userId);
17376            }
17377            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17378                    permission, callingUid, userId);
17379            rl.add(bf);
17380            if (!bf.debugCheck()) {
17381                Slog.w(TAG, "==> For Dynamic broadcast");
17382            }
17383            mReceiverResolver.addFilter(bf);
17384
17385            // Enqueue broadcasts for all existing stickies that match
17386            // this filter.
17387            if (allSticky != null) {
17388                ArrayList receivers = new ArrayList();
17389                receivers.add(bf);
17390
17391                final int stickyCount = allSticky.size();
17392                for (int i = 0; i < stickyCount; i++) {
17393                    Intent intent = allSticky.get(i);
17394                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17395                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17396                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17397                            null, 0, null, null, false, true, true, -1);
17398                    queue.enqueueParallelBroadcastLocked(r);
17399                    queue.scheduleBroadcastsLocked();
17400                }
17401            }
17402
17403            return sticky;
17404        }
17405    }
17406
17407    public void unregisterReceiver(IIntentReceiver receiver) {
17408        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17409
17410        final long origId = Binder.clearCallingIdentity();
17411        try {
17412            boolean doTrim = false;
17413
17414            synchronized(this) {
17415                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17416                if (rl != null) {
17417                    final BroadcastRecord r = rl.curBroadcast;
17418                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17419                        final boolean doNext = r.queue.finishReceiverLocked(
17420                                r, r.resultCode, r.resultData, r.resultExtras,
17421                                r.resultAbort, false);
17422                        if (doNext) {
17423                            doTrim = true;
17424                            r.queue.processNextBroadcast(false);
17425                        }
17426                    }
17427
17428                    if (rl.app != null) {
17429                        rl.app.receivers.remove(rl);
17430                    }
17431                    removeReceiverLocked(rl);
17432                    if (rl.linkedToDeath) {
17433                        rl.linkedToDeath = false;
17434                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17435                    }
17436                }
17437            }
17438
17439            // If we actually concluded any broadcasts, we might now be able
17440            // to trim the recipients' apps from our working set
17441            if (doTrim) {
17442                trimApplications();
17443                return;
17444            }
17445
17446        } finally {
17447            Binder.restoreCallingIdentity(origId);
17448        }
17449    }
17450
17451    void removeReceiverLocked(ReceiverList rl) {
17452        mRegisteredReceivers.remove(rl.receiver.asBinder());
17453        for (int i = rl.size() - 1; i >= 0; i--) {
17454            mReceiverResolver.removeFilter(rl.get(i));
17455        }
17456    }
17457
17458    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17459        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17460            ProcessRecord r = mLruProcesses.get(i);
17461            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17462                try {
17463                    r.thread.dispatchPackageBroadcast(cmd, packages);
17464                } catch (RemoteException ex) {
17465                }
17466            }
17467        }
17468    }
17469
17470    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17471            int callingUid, int[] users) {
17472        // TODO: come back and remove this assumption to triage all broadcasts
17473        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17474
17475        List<ResolveInfo> receivers = null;
17476        try {
17477            HashSet<ComponentName> singleUserReceivers = null;
17478            boolean scannedFirstReceivers = false;
17479            for (int user : users) {
17480                // Skip users that have Shell restrictions, with exception of always permitted
17481                // Shell broadcasts
17482                if (callingUid == Process.SHELL_UID
17483                        && mUserController.hasUserRestriction(
17484                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17485                        && !isPermittedShellBroadcast(intent)) {
17486                    continue;
17487                }
17488                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17489                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17490                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17491                    // If this is not the system user, we need to check for
17492                    // any receivers that should be filtered out.
17493                    for (int i=0; i<newReceivers.size(); i++) {
17494                        ResolveInfo ri = newReceivers.get(i);
17495                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17496                            newReceivers.remove(i);
17497                            i--;
17498                        }
17499                    }
17500                }
17501                if (newReceivers != null && newReceivers.size() == 0) {
17502                    newReceivers = null;
17503                }
17504                if (receivers == null) {
17505                    receivers = newReceivers;
17506                } else if (newReceivers != null) {
17507                    // We need to concatenate the additional receivers
17508                    // found with what we have do far.  This would be easy,
17509                    // but we also need to de-dup any receivers that are
17510                    // singleUser.
17511                    if (!scannedFirstReceivers) {
17512                        // Collect any single user receivers we had already retrieved.
17513                        scannedFirstReceivers = true;
17514                        for (int i=0; i<receivers.size(); i++) {
17515                            ResolveInfo ri = receivers.get(i);
17516                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17517                                ComponentName cn = new ComponentName(
17518                                        ri.activityInfo.packageName, ri.activityInfo.name);
17519                                if (singleUserReceivers == null) {
17520                                    singleUserReceivers = new HashSet<ComponentName>();
17521                                }
17522                                singleUserReceivers.add(cn);
17523                            }
17524                        }
17525                    }
17526                    // Add the new results to the existing results, tracking
17527                    // and de-dupping single user receivers.
17528                    for (int i=0; i<newReceivers.size(); i++) {
17529                        ResolveInfo ri = newReceivers.get(i);
17530                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17531                            ComponentName cn = new ComponentName(
17532                                    ri.activityInfo.packageName, ri.activityInfo.name);
17533                            if (singleUserReceivers == null) {
17534                                singleUserReceivers = new HashSet<ComponentName>();
17535                            }
17536                            if (!singleUserReceivers.contains(cn)) {
17537                                singleUserReceivers.add(cn);
17538                                receivers.add(ri);
17539                            }
17540                        } else {
17541                            receivers.add(ri);
17542                        }
17543                    }
17544                }
17545            }
17546        } catch (RemoteException ex) {
17547            // pm is in same process, this will never happen.
17548        }
17549        return receivers;
17550    }
17551
17552    private boolean isPermittedShellBroadcast(Intent intent) {
17553        // remote bugreport should always be allowed to be taken
17554        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17555    }
17556
17557    final int broadcastIntentLocked(ProcessRecord callerApp,
17558            String callerPackage, Intent intent, String resolvedType,
17559            IIntentReceiver resultTo, int resultCode, String resultData,
17560            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17561            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17562        intent = new Intent(intent);
17563
17564        // By default broadcasts do not go to stopped apps.
17565        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17566
17567        // If we have not finished booting, don't allow this to launch new processes.
17568        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17569            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17570        }
17571
17572        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17573                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17574                + " ordered=" + ordered + " userid=" + userId);
17575        if ((resultTo != null) && !ordered) {
17576            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17577        }
17578
17579        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17580                ALLOW_NON_FULL, "broadcast", callerPackage);
17581
17582        // Make sure that the user who is receiving this broadcast is running.
17583        // If not, we will just skip it. Make an exception for shutdown broadcasts
17584        // and upgrade steps.
17585
17586        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17587            if ((callingUid != Process.SYSTEM_UID
17588                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17589                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17590                Slog.w(TAG, "Skipping broadcast of " + intent
17591                        + ": user " + userId + " is stopped");
17592                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17593            }
17594        }
17595
17596        BroadcastOptions brOptions = null;
17597        if (bOptions != null) {
17598            brOptions = new BroadcastOptions(bOptions);
17599            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17600                // See if the caller is allowed to do this.  Note we are checking against
17601                // the actual real caller (not whoever provided the operation as say a
17602                // PendingIntent), because that who is actually supplied the arguments.
17603                if (checkComponentPermission(
17604                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17605                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17606                        != PackageManager.PERMISSION_GRANTED) {
17607                    String msg = "Permission Denial: " + intent.getAction()
17608                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17609                            + ", uid=" + callingUid + ")"
17610                            + " requires "
17611                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17612                    Slog.w(TAG, msg);
17613                    throw new SecurityException(msg);
17614                }
17615            }
17616        }
17617
17618        // Verify that protected broadcasts are only being sent by system code,
17619        // and that system code is only sending protected broadcasts.
17620        final String action = intent.getAction();
17621        final boolean isProtectedBroadcast;
17622        try {
17623            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17624        } catch (RemoteException e) {
17625            Slog.w(TAG, "Remote exception", e);
17626            return ActivityManager.BROADCAST_SUCCESS;
17627        }
17628
17629        final boolean isCallerSystem;
17630        switch (UserHandle.getAppId(callingUid)) {
17631            case Process.ROOT_UID:
17632            case Process.SYSTEM_UID:
17633            case Process.PHONE_UID:
17634            case Process.BLUETOOTH_UID:
17635            case Process.NFC_UID:
17636                isCallerSystem = true;
17637                break;
17638            default:
17639                isCallerSystem = (callerApp != null) && callerApp.persistent;
17640                break;
17641        }
17642
17643        if (isCallerSystem) {
17644            if (isProtectedBroadcast
17645                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17646                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17647                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17648                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17649                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17650                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17651                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17652                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17653                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17654                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17655                // Broadcast is either protected, or it's a public action that
17656                // we've relaxed, so it's fine for system internals to send.
17657            } else {
17658                // The vast majority of broadcasts sent from system internals
17659                // should be protected to avoid security holes, so yell loudly
17660                // to ensure we examine these cases.
17661                if (callerApp != null) {
17662                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17663                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17664                            new Throwable());
17665                } else {
17666                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17667                            + " from system uid " + UserHandle.formatUid(callingUid)
17668                            + " pkg " + callerPackage,
17669                            new Throwable());
17670                }
17671            }
17672
17673        } else {
17674            if (isProtectedBroadcast) {
17675                String msg = "Permission Denial: not allowed to send broadcast "
17676                        + action + " from pid="
17677                        + callingPid + ", uid=" + callingUid;
17678                Slog.w(TAG, msg);
17679                throw new SecurityException(msg);
17680
17681            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17682                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17683                // Special case for compatibility: we don't want apps to send this,
17684                // but historically it has not been protected and apps may be using it
17685                // to poke their own app widget.  So, instead of making it protected,
17686                // just limit it to the caller.
17687                if (callerPackage == null) {
17688                    String msg = "Permission Denial: not allowed to send broadcast "
17689                            + action + " from unknown caller.";
17690                    Slog.w(TAG, msg);
17691                    throw new SecurityException(msg);
17692                } else if (intent.getComponent() != null) {
17693                    // They are good enough to send to an explicit component...  verify
17694                    // it is being sent to the calling app.
17695                    if (!intent.getComponent().getPackageName().equals(
17696                            callerPackage)) {
17697                        String msg = "Permission Denial: not allowed to send broadcast "
17698                                + action + " to "
17699                                + intent.getComponent().getPackageName() + " from "
17700                                + callerPackage;
17701                        Slog.w(TAG, msg);
17702                        throw new SecurityException(msg);
17703                    }
17704                } else {
17705                    // Limit broadcast to their own package.
17706                    intent.setPackage(callerPackage);
17707                }
17708            }
17709        }
17710
17711        if (action != null) {
17712            switch (action) {
17713                case Intent.ACTION_UID_REMOVED:
17714                case Intent.ACTION_PACKAGE_REMOVED:
17715                case Intent.ACTION_PACKAGE_CHANGED:
17716                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17717                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17718                case Intent.ACTION_PACKAGES_SUSPENDED:
17719                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17720                    // Handle special intents: if this broadcast is from the package
17721                    // manager about a package being removed, we need to remove all of
17722                    // its activities from the history stack.
17723                    if (checkComponentPermission(
17724                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17725                            callingPid, callingUid, -1, true)
17726                            != PackageManager.PERMISSION_GRANTED) {
17727                        String msg = "Permission Denial: " + intent.getAction()
17728                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17729                                + ", uid=" + callingUid + ")"
17730                                + " requires "
17731                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17732                        Slog.w(TAG, msg);
17733                        throw new SecurityException(msg);
17734                    }
17735                    switch (action) {
17736                        case Intent.ACTION_UID_REMOVED:
17737                            final Bundle intentExtras = intent.getExtras();
17738                            final int uid = intentExtras != null
17739                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17740                            if (uid >= 0) {
17741                                mBatteryStatsService.removeUid(uid);
17742                                mAppOpsService.uidRemoved(uid);
17743                            }
17744                            break;
17745                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17746                            // If resources are unavailable just force stop all those packages
17747                            // and flush the attribute cache as well.
17748                            String list[] =
17749                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17750                            if (list != null && list.length > 0) {
17751                                for (int i = 0; i < list.length; i++) {
17752                                    forceStopPackageLocked(list[i], -1, false, true, true,
17753                                            false, false, userId, "storage unmount");
17754                                }
17755                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17756                                sendPackageBroadcastLocked(
17757                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17758                                        userId);
17759                            }
17760                            break;
17761                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17762                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17763                            break;
17764                        case Intent.ACTION_PACKAGE_REMOVED:
17765                        case Intent.ACTION_PACKAGE_CHANGED:
17766                            Uri data = intent.getData();
17767                            String ssp;
17768                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17769                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17770                                final boolean replacing =
17771                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17772                                final boolean killProcess =
17773                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17774                                final boolean fullUninstall = removed && !replacing;
17775                                if (removed) {
17776                                    if (killProcess) {
17777                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17778                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17779                                                false, true, true, false, fullUninstall, userId,
17780                                                removed ? "pkg removed" : "pkg changed");
17781                                    }
17782                                    final int cmd = killProcess
17783                                            ? IApplicationThread.PACKAGE_REMOVED
17784                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17785                                    sendPackageBroadcastLocked(cmd,
17786                                            new String[] {ssp}, userId);
17787                                    if (fullUninstall) {
17788                                        mAppOpsService.packageRemoved(
17789                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17790
17791                                        // Remove all permissions granted from/to this package
17792                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17793
17794                                        removeTasksByPackageNameLocked(ssp, userId);
17795
17796                                        // Hide the "unsupported display" dialog if necessary.
17797                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17798                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17799                                            mUnsupportedDisplaySizeDialog.dismiss();
17800                                            mUnsupportedDisplaySizeDialog = null;
17801                                        }
17802                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17803                                        mBatteryStatsService.notePackageUninstalled(ssp);
17804                                    }
17805                                } else {
17806                                    if (killProcess) {
17807                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17808                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17809                                                userId, ProcessList.INVALID_ADJ,
17810                                                false, true, true, false, "change " + ssp);
17811                                    }
17812                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17813                                            intent.getStringArrayExtra(
17814                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17815                                }
17816                            }
17817                            break;
17818                        case Intent.ACTION_PACKAGES_SUSPENDED:
17819                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17820                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17821                                    intent.getAction());
17822                            final String[] packageNames = intent.getStringArrayExtra(
17823                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17824                            final int userHandle = intent.getIntExtra(
17825                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17826
17827                            synchronized(ActivityManagerService.this) {
17828                                mRecentTasks.onPackagesSuspendedChanged(
17829                                        packageNames, suspended, userHandle);
17830                            }
17831                            break;
17832                    }
17833                    break;
17834                case Intent.ACTION_PACKAGE_REPLACED:
17835                {
17836                    final Uri data = intent.getData();
17837                    final String ssp;
17838                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17839                        final ApplicationInfo aInfo =
17840                                getPackageManagerInternalLocked().getApplicationInfo(
17841                                        ssp,
17842                                        userId);
17843                        if (aInfo == null) {
17844                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17845                                    + " ssp=" + ssp + " data=" + data);
17846                            return ActivityManager.BROADCAST_SUCCESS;
17847                        }
17848                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17849                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17850                                new String[] {ssp}, userId);
17851                    }
17852                    break;
17853                }
17854                case Intent.ACTION_PACKAGE_ADDED:
17855                {
17856                    // Special case for adding a package: by default turn on compatibility mode.
17857                    Uri data = intent.getData();
17858                    String ssp;
17859                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17860                        final boolean replacing =
17861                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17862                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17863
17864                        try {
17865                            ApplicationInfo ai = AppGlobals.getPackageManager().
17866                                    getApplicationInfo(ssp, 0, 0);
17867                            mBatteryStatsService.notePackageInstalled(ssp,
17868                                    ai != null ? ai.versionCode : 0);
17869                        } catch (RemoteException e) {
17870                        }
17871                    }
17872                    break;
17873                }
17874                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17875                {
17876                    Uri data = intent.getData();
17877                    String ssp;
17878                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17879                        // Hide the "unsupported display" dialog if necessary.
17880                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17881                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17882                            mUnsupportedDisplaySizeDialog.dismiss();
17883                            mUnsupportedDisplaySizeDialog = null;
17884                        }
17885                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17886                    }
17887                    break;
17888                }
17889                case Intent.ACTION_TIMEZONE_CHANGED:
17890                    // If this is the time zone changed action, queue up a message that will reset
17891                    // the timezone of all currently running processes. This message will get
17892                    // queued up before the broadcast happens.
17893                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17894                    break;
17895                case Intent.ACTION_TIME_CHANGED:
17896                    // If the user set the time, let all running processes know.
17897                    final int is24Hour =
17898                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17899                                    : 0;
17900                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17901                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17902                    synchronized (stats) {
17903                        stats.noteCurrentTimeChangedLocked();
17904                    }
17905                    break;
17906                case Intent.ACTION_CLEAR_DNS_CACHE:
17907                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17908                    break;
17909                case Proxy.PROXY_CHANGE_ACTION:
17910                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17911                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17912                    break;
17913                case android.hardware.Camera.ACTION_NEW_PICTURE:
17914                case android.hardware.Camera.ACTION_NEW_VIDEO:
17915                    // These broadcasts are no longer allowed by the system, since they can
17916                    // cause significant thrashing at a crictical point (using the camera).
17917                    // Apps should use JobScehduler to monitor for media provider changes.
17918                    Slog.w(TAG, action + " no longer allowed; dropping from "
17919                            + UserHandle.formatUid(callingUid));
17920                    if (resultTo != null) {
17921                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17922                        try {
17923                            queue.performReceiveLocked(callerApp, resultTo, intent,
17924                                    Activity.RESULT_CANCELED, null, null,
17925                                    false, false, userId);
17926                        } catch (RemoteException e) {
17927                            Slog.w(TAG, "Failure ["
17928                                    + queue.mQueueName + "] sending broadcast result of "
17929                                    + intent, e);
17930
17931                        }
17932                    }
17933                    // Lie; we don't want to crash the app.
17934                    return ActivityManager.BROADCAST_SUCCESS;
17935            }
17936        }
17937
17938        // Add to the sticky list if requested.
17939        if (sticky) {
17940            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17941                    callingPid, callingUid)
17942                    != PackageManager.PERMISSION_GRANTED) {
17943                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17944                        + callingPid + ", uid=" + callingUid
17945                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17946                Slog.w(TAG, msg);
17947                throw new SecurityException(msg);
17948            }
17949            if (requiredPermissions != null && requiredPermissions.length > 0) {
17950                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17951                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17952                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17953            }
17954            if (intent.getComponent() != null) {
17955                throw new SecurityException(
17956                        "Sticky broadcasts can't target a specific component");
17957            }
17958            // We use userId directly here, since the "all" target is maintained
17959            // as a separate set of sticky broadcasts.
17960            if (userId != UserHandle.USER_ALL) {
17961                // But first, if this is not a broadcast to all users, then
17962                // make sure it doesn't conflict with an existing broadcast to
17963                // all users.
17964                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17965                        UserHandle.USER_ALL);
17966                if (stickies != null) {
17967                    ArrayList<Intent> list = stickies.get(intent.getAction());
17968                    if (list != null) {
17969                        int N = list.size();
17970                        int i;
17971                        for (i=0; i<N; i++) {
17972                            if (intent.filterEquals(list.get(i))) {
17973                                throw new IllegalArgumentException(
17974                                        "Sticky broadcast " + intent + " for user "
17975                                        + userId + " conflicts with existing global broadcast");
17976                            }
17977                        }
17978                    }
17979                }
17980            }
17981            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17982            if (stickies == null) {
17983                stickies = new ArrayMap<>();
17984                mStickyBroadcasts.put(userId, stickies);
17985            }
17986            ArrayList<Intent> list = stickies.get(intent.getAction());
17987            if (list == null) {
17988                list = new ArrayList<>();
17989                stickies.put(intent.getAction(), list);
17990            }
17991            final int stickiesCount = list.size();
17992            int i;
17993            for (i = 0; i < stickiesCount; i++) {
17994                if (intent.filterEquals(list.get(i))) {
17995                    // This sticky already exists, replace it.
17996                    list.set(i, new Intent(intent));
17997                    break;
17998                }
17999            }
18000            if (i >= stickiesCount) {
18001                list.add(new Intent(intent));
18002            }
18003        }
18004
18005        int[] users;
18006        if (userId == UserHandle.USER_ALL) {
18007            // Caller wants broadcast to go to all started users.
18008            users = mUserController.getStartedUserArrayLocked();
18009        } else {
18010            // Caller wants broadcast to go to one specific user.
18011            users = new int[] {userId};
18012        }
18013
18014        // Figure out who all will receive this broadcast.
18015        List receivers = null;
18016        List<BroadcastFilter> registeredReceivers = null;
18017        // Need to resolve the intent to interested receivers...
18018        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18019                 == 0) {
18020            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18021        }
18022        if (intent.getComponent() == null) {
18023            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18024                // Query one target user at a time, excluding shell-restricted users
18025                for (int i = 0; i < users.length; i++) {
18026                    if (mUserController.hasUserRestriction(
18027                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18028                        continue;
18029                    }
18030                    List<BroadcastFilter> registeredReceiversForUser =
18031                            mReceiverResolver.queryIntent(intent,
18032                                    resolvedType, false, users[i]);
18033                    if (registeredReceivers == null) {
18034                        registeredReceivers = registeredReceiversForUser;
18035                    } else if (registeredReceiversForUser != null) {
18036                        registeredReceivers.addAll(registeredReceiversForUser);
18037                    }
18038                }
18039            } else {
18040                registeredReceivers = mReceiverResolver.queryIntent(intent,
18041                        resolvedType, false, userId);
18042            }
18043        }
18044
18045        final boolean replacePending =
18046                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18047
18048        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18049                + " replacePending=" + replacePending);
18050
18051        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18052        if (!ordered && NR > 0) {
18053            // If we are not serializing this broadcast, then send the
18054            // registered receivers separately so they don't wait for the
18055            // components to be launched.
18056            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18057            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18058                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18059                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18060                    resultExtras, ordered, sticky, false, userId);
18061            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18062            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18063            if (!replaced) {
18064                queue.enqueueParallelBroadcastLocked(r);
18065                queue.scheduleBroadcastsLocked();
18066            }
18067            registeredReceivers = null;
18068            NR = 0;
18069        }
18070
18071        // Merge into one list.
18072        int ir = 0;
18073        if (receivers != null) {
18074            // A special case for PACKAGE_ADDED: do not allow the package
18075            // being added to see this broadcast.  This prevents them from
18076            // using this as a back door to get run as soon as they are
18077            // installed.  Maybe in the future we want to have a special install
18078            // broadcast or such for apps, but we'd like to deliberately make
18079            // this decision.
18080            String skipPackages[] = null;
18081            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18082                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18083                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18084                Uri data = intent.getData();
18085                if (data != null) {
18086                    String pkgName = data.getSchemeSpecificPart();
18087                    if (pkgName != null) {
18088                        skipPackages = new String[] { pkgName };
18089                    }
18090                }
18091            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18092                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18093            }
18094            if (skipPackages != null && (skipPackages.length > 0)) {
18095                for (String skipPackage : skipPackages) {
18096                    if (skipPackage != null) {
18097                        int NT = receivers.size();
18098                        for (int it=0; it<NT; it++) {
18099                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18100                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18101                                receivers.remove(it);
18102                                it--;
18103                                NT--;
18104                            }
18105                        }
18106                    }
18107                }
18108            }
18109
18110            int NT = receivers != null ? receivers.size() : 0;
18111            int it = 0;
18112            ResolveInfo curt = null;
18113            BroadcastFilter curr = null;
18114            while (it < NT && ir < NR) {
18115                if (curt == null) {
18116                    curt = (ResolveInfo)receivers.get(it);
18117                }
18118                if (curr == null) {
18119                    curr = registeredReceivers.get(ir);
18120                }
18121                if (curr.getPriority() >= curt.priority) {
18122                    // Insert this broadcast record into the final list.
18123                    receivers.add(it, curr);
18124                    ir++;
18125                    curr = null;
18126                    it++;
18127                    NT++;
18128                } else {
18129                    // Skip to the next ResolveInfo in the final list.
18130                    it++;
18131                    curt = null;
18132                }
18133            }
18134        }
18135        while (ir < NR) {
18136            if (receivers == null) {
18137                receivers = new ArrayList();
18138            }
18139            receivers.add(registeredReceivers.get(ir));
18140            ir++;
18141        }
18142
18143        if ((receivers != null && receivers.size() > 0)
18144                || resultTo != null) {
18145            BroadcastQueue queue = broadcastQueueForIntent(intent);
18146            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18147                    callerPackage, callingPid, callingUid, resolvedType,
18148                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18149                    resultData, resultExtras, ordered, sticky, false, userId);
18150
18151            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18152                    + ": prev had " + queue.mOrderedBroadcasts.size());
18153            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18154                    "Enqueueing broadcast " + r.intent.getAction());
18155
18156            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18157            if (!replaced) {
18158                queue.enqueueOrderedBroadcastLocked(r);
18159                queue.scheduleBroadcastsLocked();
18160            }
18161        } else {
18162            // There was nobody interested in the broadcast, but we still want to record
18163            // that it happened.
18164            if (intent.getComponent() == null && intent.getPackage() == null
18165                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18166                // This was an implicit broadcast... let's record it for posterity.
18167                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18168            }
18169        }
18170
18171        return ActivityManager.BROADCAST_SUCCESS;
18172    }
18173
18174    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18175            int skipCount, long dispatchTime) {
18176        final long now = SystemClock.elapsedRealtime();
18177        if (mCurBroadcastStats == null ||
18178                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18179            mLastBroadcastStats = mCurBroadcastStats;
18180            if (mLastBroadcastStats != null) {
18181                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18182                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18183            }
18184            mCurBroadcastStats = new BroadcastStats();
18185        }
18186        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18187    }
18188
18189    final Intent verifyBroadcastLocked(Intent intent) {
18190        // Refuse possible leaked file descriptors
18191        if (intent != null && intent.hasFileDescriptors() == true) {
18192            throw new IllegalArgumentException("File descriptors passed in Intent");
18193        }
18194
18195        int flags = intent.getFlags();
18196
18197        if (!mProcessesReady) {
18198            // if the caller really truly claims to know what they're doing, go
18199            // ahead and allow the broadcast without launching any receivers
18200            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18201                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18202            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18203                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18204                        + " before boot completion");
18205                throw new IllegalStateException("Cannot broadcast before boot completed");
18206            }
18207        }
18208
18209        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18210            throw new IllegalArgumentException(
18211                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18212        }
18213
18214        return intent;
18215    }
18216
18217    public final int broadcastIntent(IApplicationThread caller,
18218            Intent intent, String resolvedType, IIntentReceiver resultTo,
18219            int resultCode, String resultData, Bundle resultExtras,
18220            String[] requiredPermissions, int appOp, Bundle bOptions,
18221            boolean serialized, boolean sticky, int userId) {
18222        enforceNotIsolatedCaller("broadcastIntent");
18223        synchronized(this) {
18224            intent = verifyBroadcastLocked(intent);
18225
18226            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18227            final int callingPid = Binder.getCallingPid();
18228            final int callingUid = Binder.getCallingUid();
18229            final long origId = Binder.clearCallingIdentity();
18230            int res = broadcastIntentLocked(callerApp,
18231                    callerApp != null ? callerApp.info.packageName : null,
18232                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18233                    requiredPermissions, appOp, bOptions, serialized, sticky,
18234                    callingPid, callingUid, userId);
18235            Binder.restoreCallingIdentity(origId);
18236            return res;
18237        }
18238    }
18239
18240
18241    int broadcastIntentInPackage(String packageName, int uid,
18242            Intent intent, String resolvedType, IIntentReceiver resultTo,
18243            int resultCode, String resultData, Bundle resultExtras,
18244            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18245            int userId) {
18246        synchronized(this) {
18247            intent = verifyBroadcastLocked(intent);
18248
18249            final long origId = Binder.clearCallingIdentity();
18250            String[] requiredPermissions = requiredPermission == null ? null
18251                    : new String[] {requiredPermission};
18252            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18253                    resultTo, resultCode, resultData, resultExtras,
18254                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18255                    sticky, -1, uid, userId);
18256            Binder.restoreCallingIdentity(origId);
18257            return res;
18258        }
18259    }
18260
18261    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18262        // Refuse possible leaked file descriptors
18263        if (intent != null && intent.hasFileDescriptors() == true) {
18264            throw new IllegalArgumentException("File descriptors passed in Intent");
18265        }
18266
18267        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18268                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18269
18270        synchronized(this) {
18271            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18272                    != PackageManager.PERMISSION_GRANTED) {
18273                String msg = "Permission Denial: unbroadcastIntent() from pid="
18274                        + Binder.getCallingPid()
18275                        + ", uid=" + Binder.getCallingUid()
18276                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18277                Slog.w(TAG, msg);
18278                throw new SecurityException(msg);
18279            }
18280            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18281            if (stickies != null) {
18282                ArrayList<Intent> list = stickies.get(intent.getAction());
18283                if (list != null) {
18284                    int N = list.size();
18285                    int i;
18286                    for (i=0; i<N; i++) {
18287                        if (intent.filterEquals(list.get(i))) {
18288                            list.remove(i);
18289                            break;
18290                        }
18291                    }
18292                    if (list.size() <= 0) {
18293                        stickies.remove(intent.getAction());
18294                    }
18295                }
18296                if (stickies.size() <= 0) {
18297                    mStickyBroadcasts.remove(userId);
18298                }
18299            }
18300        }
18301    }
18302
18303    void backgroundServicesFinishedLocked(int userId) {
18304        for (BroadcastQueue queue : mBroadcastQueues) {
18305            queue.backgroundServicesFinishedLocked(userId);
18306        }
18307    }
18308
18309    public void finishReceiver(IBinder who, int resultCode, String resultData,
18310            Bundle resultExtras, boolean resultAbort, int flags) {
18311        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18312
18313        // Refuse possible leaked file descriptors
18314        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18315            throw new IllegalArgumentException("File descriptors passed in Bundle");
18316        }
18317
18318        final long origId = Binder.clearCallingIdentity();
18319        try {
18320            boolean doNext = false;
18321            BroadcastRecord r;
18322
18323            synchronized(this) {
18324                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18325                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18326                r = queue.getMatchingOrderedReceiver(who);
18327                if (r != null) {
18328                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18329                        resultData, resultExtras, resultAbort, true);
18330                }
18331            }
18332
18333            if (doNext) {
18334                r.queue.processNextBroadcast(false);
18335            }
18336            trimApplications();
18337        } finally {
18338            Binder.restoreCallingIdentity(origId);
18339        }
18340    }
18341
18342    // =========================================================
18343    // INSTRUMENTATION
18344    // =========================================================
18345
18346    public boolean startInstrumentation(ComponentName className,
18347            String profileFile, int flags, Bundle arguments,
18348            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18349            int userId, String abiOverride) {
18350        enforceNotIsolatedCaller("startInstrumentation");
18351        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18352                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18353        // Refuse possible leaked file descriptors
18354        if (arguments != null && arguments.hasFileDescriptors()) {
18355            throw new IllegalArgumentException("File descriptors passed in Bundle");
18356        }
18357
18358        synchronized(this) {
18359            InstrumentationInfo ii = null;
18360            ApplicationInfo ai = null;
18361            try {
18362                ii = mContext.getPackageManager().getInstrumentationInfo(
18363                    className, STOCK_PM_FLAGS);
18364                ai = AppGlobals.getPackageManager().getApplicationInfo(
18365                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18366            } catch (PackageManager.NameNotFoundException e) {
18367            } catch (RemoteException e) {
18368            }
18369            if (ii == null) {
18370                reportStartInstrumentationFailureLocked(watcher, className,
18371                        "Unable to find instrumentation info for: " + className);
18372                return false;
18373            }
18374            if (ai == null) {
18375                reportStartInstrumentationFailureLocked(watcher, className,
18376                        "Unable to find instrumentation target package: " + ii.targetPackage);
18377                return false;
18378            }
18379            if (!ai.hasCode()) {
18380                reportStartInstrumentationFailureLocked(watcher, className,
18381                        "Instrumentation target has no code: " + ii.targetPackage);
18382                return false;
18383            }
18384
18385            int match = mContext.getPackageManager().checkSignatures(
18386                    ii.targetPackage, ii.packageName);
18387            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18388                String msg = "Permission Denial: starting instrumentation "
18389                        + className + " from pid="
18390                        + Binder.getCallingPid()
18391                        + ", uid=" + Binder.getCallingPid()
18392                        + " not allowed because package " + ii.packageName
18393                        + " does not have a signature matching the target "
18394                        + ii.targetPackage;
18395                reportStartInstrumentationFailureLocked(watcher, className, msg);
18396                throw new SecurityException(msg);
18397            }
18398
18399            final long origId = Binder.clearCallingIdentity();
18400            // Instrumentation can kill and relaunch even persistent processes
18401            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18402                    "start instr");
18403            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18404            app.instrumentationClass = className;
18405            app.instrumentationInfo = ai;
18406            app.instrumentationProfileFile = profileFile;
18407            app.instrumentationArguments = arguments;
18408            app.instrumentationWatcher = watcher;
18409            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18410            app.instrumentationResultClass = className;
18411            Binder.restoreCallingIdentity(origId);
18412        }
18413
18414        return true;
18415    }
18416
18417    /**
18418     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18419     * error to the logs, but if somebody is watching, send the report there too.  This enables
18420     * the "am" command to report errors with more information.
18421     *
18422     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18423     * @param cn The component name of the instrumentation.
18424     * @param report The error report.
18425     */
18426    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18427            ComponentName cn, String report) {
18428        Slog.w(TAG, report);
18429        if (watcher != null) {
18430            Bundle results = new Bundle();
18431            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18432            results.putString("Error", report);
18433            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18434        }
18435    }
18436
18437    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18438        if (app.instrumentationWatcher != null) {
18439            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18440                    app.instrumentationClass, resultCode, results);
18441        }
18442
18443        // Can't call out of the system process with a lock held, so post a message.
18444        if (app.instrumentationUiAutomationConnection != null) {
18445            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18446                    app.instrumentationUiAutomationConnection).sendToTarget();
18447        }
18448
18449        app.instrumentationWatcher = null;
18450        app.instrumentationUiAutomationConnection = null;
18451        app.instrumentationClass = null;
18452        app.instrumentationInfo = null;
18453        app.instrumentationProfileFile = null;
18454        app.instrumentationArguments = null;
18455
18456        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18457                "finished inst");
18458    }
18459
18460    public void finishInstrumentation(IApplicationThread target,
18461            int resultCode, Bundle results) {
18462        int userId = UserHandle.getCallingUserId();
18463        // Refuse possible leaked file descriptors
18464        if (results != null && results.hasFileDescriptors()) {
18465            throw new IllegalArgumentException("File descriptors passed in Intent");
18466        }
18467
18468        synchronized(this) {
18469            ProcessRecord app = getRecordForAppLocked(target);
18470            if (app == null) {
18471                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18472                return;
18473            }
18474            final long origId = Binder.clearCallingIdentity();
18475            finishInstrumentationLocked(app, resultCode, results);
18476            Binder.restoreCallingIdentity(origId);
18477        }
18478    }
18479
18480    // =========================================================
18481    // CONFIGURATION
18482    // =========================================================
18483
18484    public ConfigurationInfo getDeviceConfigurationInfo() {
18485        ConfigurationInfo config = new ConfigurationInfo();
18486        synchronized (this) {
18487            config.reqTouchScreen = mConfiguration.touchscreen;
18488            config.reqKeyboardType = mConfiguration.keyboard;
18489            config.reqNavigation = mConfiguration.navigation;
18490            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18491                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18492                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18493            }
18494            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18495                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18496                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18497            }
18498            config.reqGlEsVersion = GL_ES_VERSION;
18499        }
18500        return config;
18501    }
18502
18503    ActivityStack getFocusedStack() {
18504        return mStackSupervisor.getFocusedStack();
18505    }
18506
18507    @Override
18508    public int getFocusedStackId() throws RemoteException {
18509        ActivityStack focusedStack = getFocusedStack();
18510        if (focusedStack != null) {
18511            return focusedStack.getStackId();
18512        }
18513        return -1;
18514    }
18515
18516    public Configuration getConfiguration() {
18517        Configuration ci;
18518        synchronized(this) {
18519            ci = new Configuration(mConfiguration);
18520            ci.userSetLocale = false;
18521        }
18522        return ci;
18523    }
18524
18525    @Override
18526    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18527        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18528        synchronized (this) {
18529            mSuppressResizeConfigChanges = suppress;
18530        }
18531    }
18532
18533    @Override
18534    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18535        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18536        if (fromStackId == HOME_STACK_ID) {
18537            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18538        }
18539        synchronized (this) {
18540            final long origId = Binder.clearCallingIdentity();
18541            try {
18542                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18543            } finally {
18544                Binder.restoreCallingIdentity(origId);
18545            }
18546        }
18547    }
18548
18549    @Override
18550    public void updatePersistentConfiguration(Configuration values) {
18551        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18552                "updateConfiguration()");
18553        enforceWriteSettingsPermission("updateConfiguration()");
18554        if (values == null) {
18555            throw new NullPointerException("Configuration must not be null");
18556        }
18557
18558        int userId = UserHandle.getCallingUserId();
18559
18560        synchronized(this) {
18561            final long origId = Binder.clearCallingIdentity();
18562            updateConfigurationLocked(values, null, false, true, userId);
18563            Binder.restoreCallingIdentity(origId);
18564        }
18565    }
18566
18567    private void updateFontScaleIfNeeded() {
18568        final int currentUserId;
18569        synchronized(this) {
18570            currentUserId = mUserController.getCurrentUserIdLocked();
18571        }
18572        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18573                FONT_SCALE, 1.0f, currentUserId);
18574        if (mConfiguration.fontScale != scaleFactor) {
18575            final Configuration configuration = mWindowManager.computeNewConfiguration();
18576            configuration.fontScale = scaleFactor;
18577            updatePersistentConfiguration(configuration);
18578        }
18579    }
18580
18581    private void enforceWriteSettingsPermission(String func) {
18582        int uid = Binder.getCallingUid();
18583        if (uid == Process.ROOT_UID) {
18584            return;
18585        }
18586
18587        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18588                Settings.getPackageNameForUid(mContext, uid), false)) {
18589            return;
18590        }
18591
18592        String msg = "Permission Denial: " + func + " from pid="
18593                + Binder.getCallingPid()
18594                + ", uid=" + uid
18595                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18596        Slog.w(TAG, msg);
18597        throw new SecurityException(msg);
18598    }
18599
18600    public void updateConfiguration(Configuration values) {
18601        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18602                "updateConfiguration()");
18603
18604        synchronized(this) {
18605            if (values == null && mWindowManager != null) {
18606                // sentinel: fetch the current configuration from the window manager
18607                values = mWindowManager.computeNewConfiguration();
18608            }
18609
18610            if (mWindowManager != null) {
18611                mProcessList.applyDisplaySize(mWindowManager);
18612            }
18613
18614            final long origId = Binder.clearCallingIdentity();
18615            if (values != null) {
18616                Settings.System.clearConfiguration(values);
18617            }
18618            updateConfigurationLocked(values, null, false);
18619            Binder.restoreCallingIdentity(origId);
18620        }
18621    }
18622
18623    void updateUserConfigurationLocked() {
18624        Configuration configuration = new Configuration(mConfiguration);
18625        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18626                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18627        updateConfigurationLocked(configuration, null, false);
18628    }
18629
18630    boolean updateConfigurationLocked(Configuration values,
18631            ActivityRecord starting, boolean initLocale) {
18632        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18633        return updateConfigurationLocked(values, starting, initLocale, false,
18634                UserHandle.USER_NULL);
18635    }
18636
18637    // To cache the list of supported system locales
18638    private String[] mSupportedSystemLocales = null;
18639
18640    /**
18641     * Do either or both things: (1) change the current configuration, and (2)
18642     * make sure the given activity is running with the (now) current
18643     * configuration.  Returns true if the activity has been left running, or
18644     * false if <var>starting</var> is being destroyed to match the new
18645     * configuration.
18646     *
18647     * @param userId is only used when persistent parameter is set to true to persist configuration
18648     *               for that particular user
18649     */
18650    private boolean updateConfigurationLocked(Configuration values,
18651            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18652        int changes = 0;
18653
18654        if (mWindowManager != null) {
18655            mWindowManager.deferSurfaceLayout();
18656        }
18657        if (values != null) {
18658            Configuration newConfig = new Configuration(mConfiguration);
18659            changes = newConfig.updateFrom(values);
18660            if (changes != 0) {
18661                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18662                        "Updating configuration to: " + values);
18663
18664                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18665
18666                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18667                    final LocaleList locales = values.getLocales();
18668                    int bestLocaleIndex = 0;
18669                    if (locales.size() > 1) {
18670                        if (mSupportedSystemLocales == null) {
18671                            mSupportedSystemLocales =
18672                                    Resources.getSystem().getAssets().getLocales();
18673                        }
18674                        bestLocaleIndex = Math.max(0,
18675                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18676                    }
18677                    SystemProperties.set("persist.sys.locale",
18678                            locales.get(bestLocaleIndex).toLanguageTag());
18679                    LocaleList.setDefault(locales, bestLocaleIndex);
18680                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18681                            locales.get(bestLocaleIndex)));
18682                }
18683
18684                mConfigurationSeq++;
18685                if (mConfigurationSeq <= 0) {
18686                    mConfigurationSeq = 1;
18687                }
18688                newConfig.seq = mConfigurationSeq;
18689                mConfiguration = newConfig;
18690                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18691                mUsageStatsService.reportConfigurationChange(newConfig,
18692                        mUserController.getCurrentUserIdLocked());
18693                //mUsageStatsService.noteStartConfig(newConfig);
18694
18695                final Configuration configCopy = new Configuration(mConfiguration);
18696
18697                // TODO: If our config changes, should we auto dismiss any currently
18698                // showing dialogs?
18699                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18700
18701                AttributeCache ac = AttributeCache.instance();
18702                if (ac != null) {
18703                    ac.updateConfiguration(configCopy);
18704                }
18705
18706                // Make sure all resources in our process are updated
18707                // right now, so that anyone who is going to retrieve
18708                // resource values after we return will be sure to get
18709                // the new ones.  This is especially important during
18710                // boot, where the first config change needs to guarantee
18711                // all resources have that config before following boot
18712                // code is executed.
18713                mSystemThread.applyConfigurationToResources(configCopy);
18714
18715                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18716                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18717                    msg.obj = new Configuration(configCopy);
18718                    msg.arg1 = userId;
18719                    mHandler.sendMessage(msg);
18720                }
18721
18722                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18723                if (isDensityChange) {
18724                    // Reset the unsupported display size dialog.
18725                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18726
18727                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18728                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18729                }
18730
18731                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18732                    ProcessRecord app = mLruProcesses.get(i);
18733                    try {
18734                        if (app.thread != null) {
18735                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18736                                    + app.processName + " new config " + mConfiguration);
18737                            app.thread.scheduleConfigurationChanged(configCopy);
18738                        }
18739                    } catch (Exception e) {
18740                    }
18741                }
18742                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18743                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18744                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18745                        | Intent.FLAG_RECEIVER_FOREGROUND);
18746                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18747                        null, AppOpsManager.OP_NONE, null, false, false,
18748                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18749                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18750                    // Tell the shortcut manager that the system locale changed.  It needs to know
18751                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18752                    // we "push" from here, rather than having the service listen to the broadcast.
18753                    final ShortcutServiceInternal shortcutService =
18754                            LocalServices.getService(ShortcutServiceInternal.class);
18755                    if (shortcutService != null) {
18756                        shortcutService.onSystemLocaleChangedNoLock();
18757                    }
18758
18759                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18760                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18761                    if (!mProcessesReady) {
18762                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18763                    }
18764                    broadcastIntentLocked(null, null, intent,
18765                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18766                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18767                }
18768            }
18769            // Update the configuration with WM first and check if any of the stacks need to be
18770            // resized due to the configuration change. If so, resize the stacks now and do any
18771            // relaunches if necessary. This way we don't need to relaunch again below in
18772            // ensureActivityConfigurationLocked().
18773            if (mWindowManager != null) {
18774                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18775                if (resizedStacks != null) {
18776                    for (int stackId : resizedStacks) {
18777                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18778                        mStackSupervisor.resizeStackLocked(
18779                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18780                    }
18781                }
18782            }
18783        }
18784
18785        boolean kept = true;
18786        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18787        // mainStack is null during startup.
18788        if (mainStack != null) {
18789            if (changes != 0 && starting == null) {
18790                // If the configuration changed, and the caller is not already
18791                // in the process of starting an activity, then find the top
18792                // activity to check if its configuration needs to change.
18793                starting = mainStack.topRunningActivityLocked();
18794            }
18795
18796            if (starting != null && starting.state != ActivityState.STOPPED) {
18797                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18798                // And we need to make sure at this point that all other activities
18799                // are made visible with the correct configuration.
18800                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18801                        !PRESERVE_WINDOWS);
18802            }
18803        }
18804        if (mWindowManager != null) {
18805            mWindowManager.continueSurfaceLayout();
18806        }
18807        return kept;
18808    }
18809
18810    /**
18811     * Decide based on the configuration whether we should shouw the ANR,
18812     * crash, etc dialogs.  The idea is that if there is no affordnace to
18813     * press the on-screen buttons, we shouldn't show the dialog.
18814     *
18815     * A thought: SystemUI might also want to get told about this, the Power
18816     * dialog / global actions also might want different behaviors.
18817     */
18818    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18819        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18820                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18821                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18822        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18823                                    == Configuration.UI_MODE_TYPE_CAR);
18824        return inputMethodExists && uiIsNotCarType && !inVrMode;
18825    }
18826
18827    @Override
18828    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18829        synchronized (this) {
18830            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18831            if (srec != null) {
18832                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18833            }
18834        }
18835        return false;
18836    }
18837
18838    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18839            Intent resultData) {
18840
18841        synchronized (this) {
18842            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18843            if (r != null) {
18844                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18845            }
18846            return false;
18847        }
18848    }
18849
18850    public int getLaunchedFromUid(IBinder activityToken) {
18851        ActivityRecord srec;
18852        synchronized (this) {
18853            srec = ActivityRecord.forTokenLocked(activityToken);
18854        }
18855        if (srec == null) {
18856            return -1;
18857        }
18858        return srec.launchedFromUid;
18859    }
18860
18861    public String getLaunchedFromPackage(IBinder activityToken) {
18862        ActivityRecord srec;
18863        synchronized (this) {
18864            srec = ActivityRecord.forTokenLocked(activityToken);
18865        }
18866        if (srec == null) {
18867            return null;
18868        }
18869        return srec.launchedFromPackage;
18870    }
18871
18872    // =========================================================
18873    // LIFETIME MANAGEMENT
18874    // =========================================================
18875
18876    // Returns which broadcast queue the app is the current [or imminent] receiver
18877    // on, or 'null' if the app is not an active broadcast recipient.
18878    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18879        BroadcastRecord r = app.curReceiver;
18880        if (r != null) {
18881            return r.queue;
18882        }
18883
18884        // It's not the current receiver, but it might be starting up to become one
18885        synchronized (this) {
18886            for (BroadcastQueue queue : mBroadcastQueues) {
18887                r = queue.mPendingBroadcast;
18888                if (r != null && r.curApp == app) {
18889                    // found it; report which queue it's in
18890                    return queue;
18891                }
18892            }
18893        }
18894
18895        return null;
18896    }
18897
18898    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18899            int targetUid, ComponentName targetComponent, String targetProcess) {
18900        if (!mTrackingAssociations) {
18901            return null;
18902        }
18903        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18904                = mAssociations.get(targetUid);
18905        if (components == null) {
18906            components = new ArrayMap<>();
18907            mAssociations.put(targetUid, components);
18908        }
18909        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18910        if (sourceUids == null) {
18911            sourceUids = new SparseArray<>();
18912            components.put(targetComponent, sourceUids);
18913        }
18914        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18915        if (sourceProcesses == null) {
18916            sourceProcesses = new ArrayMap<>();
18917            sourceUids.put(sourceUid, sourceProcesses);
18918        }
18919        Association ass = sourceProcesses.get(sourceProcess);
18920        if (ass == null) {
18921            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18922                    targetProcess);
18923            sourceProcesses.put(sourceProcess, ass);
18924        }
18925        ass.mCount++;
18926        ass.mNesting++;
18927        if (ass.mNesting == 1) {
18928            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18929            ass.mLastState = sourceState;
18930        }
18931        return ass;
18932    }
18933
18934    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18935            ComponentName targetComponent) {
18936        if (!mTrackingAssociations) {
18937            return;
18938        }
18939        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18940                = mAssociations.get(targetUid);
18941        if (components == null) {
18942            return;
18943        }
18944        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18945        if (sourceUids == null) {
18946            return;
18947        }
18948        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18949        if (sourceProcesses == null) {
18950            return;
18951        }
18952        Association ass = sourceProcesses.get(sourceProcess);
18953        if (ass == null || ass.mNesting <= 0) {
18954            return;
18955        }
18956        ass.mNesting--;
18957        if (ass.mNesting == 0) {
18958            long uptime = SystemClock.uptimeMillis();
18959            ass.mTime += uptime - ass.mStartTime;
18960            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18961                    += uptime - ass.mLastStateUptime;
18962            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18963        }
18964    }
18965
18966    private void noteUidProcessState(final int uid, final int state) {
18967        mBatteryStatsService.noteUidProcessState(uid, state);
18968        if (mTrackingAssociations) {
18969            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18970                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18971                        = mAssociations.valueAt(i1);
18972                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18973                    SparseArray<ArrayMap<String, Association>> sourceUids
18974                            = targetComponents.valueAt(i2);
18975                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18976                    if (sourceProcesses != null) {
18977                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18978                            Association ass = sourceProcesses.valueAt(i4);
18979                            if (ass.mNesting >= 1) {
18980                                // currently associated
18981                                long uptime = SystemClock.uptimeMillis();
18982                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18983                                        += uptime - ass.mLastStateUptime;
18984                                ass.mLastState = state;
18985                                ass.mLastStateUptime = uptime;
18986                            }
18987                        }
18988                    }
18989                }
18990            }
18991        }
18992    }
18993
18994    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18995            boolean doingAll, long now) {
18996        if (mAdjSeq == app.adjSeq) {
18997            // This adjustment has already been computed.
18998            return app.curRawAdj;
18999        }
19000
19001        if (app.thread == null) {
19002            app.adjSeq = mAdjSeq;
19003            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19004            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19005            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19006        }
19007
19008        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19009        app.adjSource = null;
19010        app.adjTarget = null;
19011        app.empty = false;
19012        app.cached = false;
19013
19014        final int activitiesSize = app.activities.size();
19015
19016        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19017            // The max adjustment doesn't allow this app to be anything
19018            // below foreground, so it is not worth doing work for it.
19019            app.adjType = "fixed";
19020            app.adjSeq = mAdjSeq;
19021            app.curRawAdj = app.maxAdj;
19022            app.foregroundActivities = false;
19023            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19024            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19025            // System processes can do UI, and when they do we want to have
19026            // them trim their memory after the user leaves the UI.  To
19027            // facilitate this, here we need to determine whether or not it
19028            // is currently showing UI.
19029            app.systemNoUi = true;
19030            if (app == TOP_APP) {
19031                app.systemNoUi = false;
19032                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19033                app.adjType = "pers-top-activity";
19034            } else if (activitiesSize > 0) {
19035                for (int j = 0; j < activitiesSize; j++) {
19036                    final ActivityRecord r = app.activities.get(j);
19037                    if (r.visible) {
19038                        app.systemNoUi = false;
19039                    }
19040                }
19041            }
19042            if (!app.systemNoUi) {
19043                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19044            }
19045            return (app.curAdj=app.maxAdj);
19046        }
19047
19048        app.systemNoUi = false;
19049
19050        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19051
19052        // Determine the importance of the process, starting with most
19053        // important to least, and assign an appropriate OOM adjustment.
19054        int adj;
19055        int schedGroup;
19056        int procState;
19057        boolean foregroundActivities = false;
19058        BroadcastQueue queue;
19059        if (app == TOP_APP) {
19060            // The last app on the list is the foreground app.
19061            adj = ProcessList.FOREGROUND_APP_ADJ;
19062            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19063            app.adjType = "top-activity";
19064            foregroundActivities = true;
19065            procState = PROCESS_STATE_CUR_TOP;
19066        } else if (app.instrumentationClass != null) {
19067            // Don't want to kill running instrumentation.
19068            adj = ProcessList.FOREGROUND_APP_ADJ;
19069            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19070            app.adjType = "instrumentation";
19071            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19072        } else if ((queue = isReceivingBroadcast(app)) != null) {
19073            // An app that is currently receiving a broadcast also
19074            // counts as being in the foreground for OOM killer purposes.
19075            // It's placed in a sched group based on the nature of the
19076            // broadcast as reflected by which queue it's active in.
19077            adj = ProcessList.FOREGROUND_APP_ADJ;
19078            schedGroup = (queue == mFgBroadcastQueue)
19079                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19080            app.adjType = "broadcast";
19081            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19082        } else if (app.executingServices.size() > 0) {
19083            // An app that is currently executing a service callback also
19084            // counts as being in the foreground.
19085            adj = ProcessList.FOREGROUND_APP_ADJ;
19086            schedGroup = app.execServicesFg ?
19087                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19088            app.adjType = "exec-service";
19089            procState = ActivityManager.PROCESS_STATE_SERVICE;
19090            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19091        } else {
19092            // As far as we know the process is empty.  We may change our mind later.
19093            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19094            // At this point we don't actually know the adjustment.  Use the cached adj
19095            // value that the caller wants us to.
19096            adj = cachedAdj;
19097            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19098            app.cached = true;
19099            app.empty = true;
19100            app.adjType = "cch-empty";
19101        }
19102
19103        // Examine all activities if not already foreground.
19104        if (!foregroundActivities && activitiesSize > 0) {
19105            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19106            for (int j = 0; j < activitiesSize; j++) {
19107                final ActivityRecord r = app.activities.get(j);
19108                if (r.app != app) {
19109                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19110                            + " instead of expected " + app);
19111                    if (r.app == null || (r.app.uid == app.uid)) {
19112                        // Only fix things up when they look sane
19113                        r.app = app;
19114                    } else {
19115                        continue;
19116                    }
19117                }
19118                if (r.visible) {
19119                    // App has a visible activity; only upgrade adjustment.
19120                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19121                        adj = ProcessList.VISIBLE_APP_ADJ;
19122                        app.adjType = "visible";
19123                    }
19124                    if (procState > PROCESS_STATE_CUR_TOP) {
19125                        procState = PROCESS_STATE_CUR_TOP;
19126                    }
19127                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19128                    app.cached = false;
19129                    app.empty = false;
19130                    foregroundActivities = true;
19131                    if (r.task != null && minLayer > 0) {
19132                        final int layer = r.task.mLayerRank;
19133                        if (layer >= 0 && minLayer > layer) {
19134                            minLayer = layer;
19135                        }
19136                    }
19137                    break;
19138                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19139                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19140                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19141                        app.adjType = "pausing";
19142                    }
19143                    if (procState > PROCESS_STATE_CUR_TOP) {
19144                        procState = PROCESS_STATE_CUR_TOP;
19145                    }
19146                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19147                    app.cached = false;
19148                    app.empty = false;
19149                    foregroundActivities = true;
19150                } else if (r.state == ActivityState.STOPPING) {
19151                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19152                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19153                        app.adjType = "stopping";
19154                    }
19155                    // For the process state, we will at this point consider the
19156                    // process to be cached.  It will be cached either as an activity
19157                    // or empty depending on whether the activity is finishing.  We do
19158                    // this so that we can treat the process as cached for purposes of
19159                    // memory trimming (determing current memory level, trim command to
19160                    // send to process) since there can be an arbitrary number of stopping
19161                    // processes and they should soon all go into the cached state.
19162                    if (!r.finishing) {
19163                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19164                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19165                        }
19166                    }
19167                    app.cached = false;
19168                    app.empty = false;
19169                    foregroundActivities = true;
19170                } else {
19171                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19172                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19173                        app.adjType = "cch-act";
19174                    }
19175                }
19176            }
19177            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19178                adj += minLayer;
19179            }
19180        }
19181
19182        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19183                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19184            if (app.foregroundServices) {
19185                // The user is aware of this app, so make it visible.
19186                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19187                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19188                app.cached = false;
19189                app.adjType = "fg-service";
19190                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19191            } else if (app.forcingToForeground != null) {
19192                // The user is aware of this app, so make it visible.
19193                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19194                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19195                app.cached = false;
19196                app.adjType = "force-fg";
19197                app.adjSource = app.forcingToForeground;
19198                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19199            }
19200        }
19201
19202        if (app == mHeavyWeightProcess) {
19203            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19204                // We don't want to kill the current heavy-weight process.
19205                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19206                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19207                app.cached = false;
19208                app.adjType = "heavy";
19209            }
19210            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19211                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19212            }
19213        }
19214
19215        if (app == mHomeProcess) {
19216            if (adj > ProcessList.HOME_APP_ADJ) {
19217                // This process is hosting what we currently consider to be the
19218                // home app, so we don't want to let it go into the background.
19219                adj = ProcessList.HOME_APP_ADJ;
19220                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19221                app.cached = false;
19222                app.adjType = "home";
19223            }
19224            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19225                procState = ActivityManager.PROCESS_STATE_HOME;
19226            }
19227        }
19228
19229        if (app == mPreviousProcess && app.activities.size() > 0) {
19230            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19231                // This was the previous process that showed UI to the user.
19232                // We want to try to keep it around more aggressively, to give
19233                // a good experience around switching between two apps.
19234                adj = ProcessList.PREVIOUS_APP_ADJ;
19235                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19236                app.cached = false;
19237                app.adjType = "previous";
19238            }
19239            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19240                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19241            }
19242        }
19243
19244        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19245                + " reason=" + app.adjType);
19246
19247        // By default, we use the computed adjustment.  It may be changed if
19248        // there are applications dependent on our services or providers, but
19249        // this gives us a baseline and makes sure we don't get into an
19250        // infinite recursion.
19251        app.adjSeq = mAdjSeq;
19252        app.curRawAdj = adj;
19253        app.hasStartedServices = false;
19254
19255        if (mBackupTarget != null && app == mBackupTarget.app) {
19256            // If possible we want to avoid killing apps while they're being backed up
19257            if (adj > ProcessList.BACKUP_APP_ADJ) {
19258                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19259                adj = ProcessList.BACKUP_APP_ADJ;
19260                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19261                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19262                }
19263                app.adjType = "backup";
19264                app.cached = false;
19265            }
19266            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19267                procState = ActivityManager.PROCESS_STATE_BACKUP;
19268            }
19269        }
19270
19271        boolean mayBeTop = false;
19272
19273        for (int is = app.services.size()-1;
19274                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19275                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19276                        || procState > ActivityManager.PROCESS_STATE_TOP);
19277                is--) {
19278            ServiceRecord s = app.services.valueAt(is);
19279            if (s.startRequested) {
19280                app.hasStartedServices = true;
19281                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19282                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19283                }
19284                if (app.hasShownUi && app != mHomeProcess) {
19285                    // If this process has shown some UI, let it immediately
19286                    // go to the LRU list because it may be pretty heavy with
19287                    // UI stuff.  We'll tag it with a label just to help
19288                    // debug and understand what is going on.
19289                    if (adj > ProcessList.SERVICE_ADJ) {
19290                        app.adjType = "cch-started-ui-services";
19291                    }
19292                } else {
19293                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19294                        // This service has seen some activity within
19295                        // recent memory, so we will keep its process ahead
19296                        // of the background processes.
19297                        if (adj > ProcessList.SERVICE_ADJ) {
19298                            adj = ProcessList.SERVICE_ADJ;
19299                            app.adjType = "started-services";
19300                            app.cached = false;
19301                        }
19302                    }
19303                    // If we have let the service slide into the background
19304                    // state, still have some text describing what it is doing
19305                    // even though the service no longer has an impact.
19306                    if (adj > ProcessList.SERVICE_ADJ) {
19307                        app.adjType = "cch-started-services";
19308                    }
19309                }
19310            }
19311
19312            app.whitelistManager = false;
19313
19314            for (int conni = s.connections.size()-1;
19315                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19316                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19317                            || procState > ActivityManager.PROCESS_STATE_TOP);
19318                    conni--) {
19319                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19320                for (int i = 0;
19321                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19322                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19323                                || procState > ActivityManager.PROCESS_STATE_TOP);
19324                        i++) {
19325                    // XXX should compute this based on the max of
19326                    // all connected clients.
19327                    ConnectionRecord cr = clist.get(i);
19328                    if (cr.binding.client == app) {
19329                        // Binding to ourself is not interesting.
19330                        continue;
19331                    }
19332                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19333                        app.whitelistManager = true;
19334                    }
19335
19336                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19337                        ProcessRecord client = cr.binding.client;
19338                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19339                                TOP_APP, doingAll, now);
19340                        int clientProcState = client.curProcState;
19341                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19342                            // If the other app is cached for any reason, for purposes here
19343                            // we are going to consider it empty.  The specific cached state
19344                            // doesn't propagate except under certain conditions.
19345                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19346                        }
19347                        String adjType = null;
19348                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19349                            // Not doing bind OOM management, so treat
19350                            // this guy more like a started service.
19351                            if (app.hasShownUi && app != mHomeProcess) {
19352                                // If this process has shown some UI, let it immediately
19353                                // go to the LRU list because it may be pretty heavy with
19354                                // UI stuff.  We'll tag it with a label just to help
19355                                // debug and understand what is going on.
19356                                if (adj > clientAdj) {
19357                                    adjType = "cch-bound-ui-services";
19358                                }
19359                                app.cached = false;
19360                                clientAdj = adj;
19361                                clientProcState = procState;
19362                            } else {
19363                                if (now >= (s.lastActivity
19364                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19365                                    // This service has not seen activity within
19366                                    // recent memory, so allow it to drop to the
19367                                    // LRU list if there is no other reason to keep
19368                                    // it around.  We'll also tag it with a label just
19369                                    // to help debug and undertand what is going on.
19370                                    if (adj > clientAdj) {
19371                                        adjType = "cch-bound-services";
19372                                    }
19373                                    clientAdj = adj;
19374                                }
19375                            }
19376                        }
19377                        if (adj > clientAdj) {
19378                            // If this process has recently shown UI, and
19379                            // the process that is binding to it is less
19380                            // important than being visible, then we don't
19381                            // care about the binding as much as we care
19382                            // about letting this process get into the LRU
19383                            // list to be killed and restarted if needed for
19384                            // memory.
19385                            if (app.hasShownUi && app != mHomeProcess
19386                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19387                                adjType = "cch-bound-ui-services";
19388                            } else {
19389                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19390                                        |Context.BIND_IMPORTANT)) != 0) {
19391                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19392                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19393                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19394                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19395                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19396                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19397                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19398                                    adj = clientAdj;
19399                                } else {
19400                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19401                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19402                                    }
19403                                }
19404                                if (!client.cached) {
19405                                    app.cached = false;
19406                                }
19407                                adjType = "service";
19408                            }
19409                        }
19410                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19411                            // This will treat important bound services identically to
19412                            // the top app, which may behave differently than generic
19413                            // foreground work.
19414                            if (client.curSchedGroup > schedGroup) {
19415                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19416                                    schedGroup = client.curSchedGroup;
19417                                } else {
19418                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19419                                }
19420                            }
19421                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19422                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19423                                    // Special handling of clients who are in the top state.
19424                                    // We *may* want to consider this process to be in the
19425                                    // top state as well, but only if there is not another
19426                                    // reason for it to be running.  Being on the top is a
19427                                    // special state, meaning you are specifically running
19428                                    // for the current top app.  If the process is already
19429                                    // running in the background for some other reason, it
19430                                    // is more important to continue considering it to be
19431                                    // in the background state.
19432                                    mayBeTop = true;
19433                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19434                                } else {
19435                                    // Special handling for above-top states (persistent
19436                                    // processes).  These should not bring the current process
19437                                    // into the top state, since they are not on top.  Instead
19438                                    // give them the best state after that.
19439                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19440                                        clientProcState =
19441                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19442                                    } else if (mWakefulness
19443                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19444                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19445                                                    != 0) {
19446                                        clientProcState =
19447                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19448                                    } else {
19449                                        clientProcState =
19450                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19451                                    }
19452                                }
19453                            }
19454                        } else {
19455                            if (clientProcState <
19456                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19457                                clientProcState =
19458                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19459                            }
19460                        }
19461                        if (procState > clientProcState) {
19462                            procState = clientProcState;
19463                        }
19464                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19465                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19466                            app.pendingUiClean = true;
19467                        }
19468                        if (adjType != null) {
19469                            app.adjType = adjType;
19470                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19471                                    .REASON_SERVICE_IN_USE;
19472                            app.adjSource = cr.binding.client;
19473                            app.adjSourceProcState = clientProcState;
19474                            app.adjTarget = s.name;
19475                        }
19476                    }
19477                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19478                        app.treatLikeActivity = true;
19479                    }
19480                    final ActivityRecord a = cr.activity;
19481                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19482                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19483                            (a.visible || a.state == ActivityState.RESUMED ||
19484                             a.state == ActivityState.PAUSING)) {
19485                            adj = ProcessList.FOREGROUND_APP_ADJ;
19486                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19487                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19488                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19489                                } else {
19490                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19491                                }
19492                            }
19493                            app.cached = false;
19494                            app.adjType = "service";
19495                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19496                                    .REASON_SERVICE_IN_USE;
19497                            app.adjSource = a;
19498                            app.adjSourceProcState = procState;
19499                            app.adjTarget = s.name;
19500                        }
19501                    }
19502                }
19503            }
19504        }
19505
19506        for (int provi = app.pubProviders.size()-1;
19507                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19508                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19509                        || procState > ActivityManager.PROCESS_STATE_TOP);
19510                provi--) {
19511            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19512            for (int i = cpr.connections.size()-1;
19513                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19514                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19515                            || procState > ActivityManager.PROCESS_STATE_TOP);
19516                    i--) {
19517                ContentProviderConnection conn = cpr.connections.get(i);
19518                ProcessRecord client = conn.client;
19519                if (client == app) {
19520                    // Being our own client is not interesting.
19521                    continue;
19522                }
19523                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19524                int clientProcState = client.curProcState;
19525                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19526                    // If the other app is cached for any reason, for purposes here
19527                    // we are going to consider it empty.
19528                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19529                }
19530                if (adj > clientAdj) {
19531                    if (app.hasShownUi && app != mHomeProcess
19532                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19533                        app.adjType = "cch-ui-provider";
19534                    } else {
19535                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19536                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19537                        app.adjType = "provider";
19538                    }
19539                    app.cached &= client.cached;
19540                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19541                            .REASON_PROVIDER_IN_USE;
19542                    app.adjSource = client;
19543                    app.adjSourceProcState = clientProcState;
19544                    app.adjTarget = cpr.name;
19545                }
19546                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19547                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19548                        // Special handling of clients who are in the top state.
19549                        // We *may* want to consider this process to be in the
19550                        // top state as well, but only if there is not another
19551                        // reason for it to be running.  Being on the top is a
19552                        // special state, meaning you are specifically running
19553                        // for the current top app.  If the process is already
19554                        // running in the background for some other reason, it
19555                        // is more important to continue considering it to be
19556                        // in the background state.
19557                        mayBeTop = true;
19558                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19559                    } else {
19560                        // Special handling for above-top states (persistent
19561                        // processes).  These should not bring the current process
19562                        // into the top state, since they are not on top.  Instead
19563                        // give them the best state after that.
19564                        clientProcState =
19565                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19566                    }
19567                }
19568                if (procState > clientProcState) {
19569                    procState = clientProcState;
19570                }
19571                if (client.curSchedGroup > schedGroup) {
19572                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19573                }
19574            }
19575            // If the provider has external (non-framework) process
19576            // dependencies, ensure that its adjustment is at least
19577            // FOREGROUND_APP_ADJ.
19578            if (cpr.hasExternalProcessHandles()) {
19579                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19580                    adj = ProcessList.FOREGROUND_APP_ADJ;
19581                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19582                    app.cached = false;
19583                    app.adjType = "provider";
19584                    app.adjTarget = cpr.name;
19585                }
19586                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19587                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19588                }
19589            }
19590        }
19591
19592        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19593            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19594                adj = ProcessList.PREVIOUS_APP_ADJ;
19595                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19596                app.cached = false;
19597                app.adjType = "provider";
19598            }
19599            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19600                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19601            }
19602        }
19603
19604        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19605            // A client of one of our services or providers is in the top state.  We
19606            // *may* want to be in the top state, but not if we are already running in
19607            // the background for some other reason.  For the decision here, we are going
19608            // to pick out a few specific states that we want to remain in when a client
19609            // is top (states that tend to be longer-term) and otherwise allow it to go
19610            // to the top state.
19611            switch (procState) {
19612                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19613                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19614                case ActivityManager.PROCESS_STATE_SERVICE:
19615                    // These all are longer-term states, so pull them up to the top
19616                    // of the background states, but not all the way to the top state.
19617                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19618                    break;
19619                default:
19620                    // Otherwise, top is a better choice, so take it.
19621                    procState = ActivityManager.PROCESS_STATE_TOP;
19622                    break;
19623            }
19624        }
19625
19626        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19627            if (app.hasClientActivities) {
19628                // This is a cached process, but with client activities.  Mark it so.
19629                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19630                app.adjType = "cch-client-act";
19631            } else if (app.treatLikeActivity) {
19632                // This is a cached process, but somebody wants us to treat it like it has
19633                // an activity, okay!
19634                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19635                app.adjType = "cch-as-act";
19636            }
19637        }
19638
19639        if (adj == ProcessList.SERVICE_ADJ) {
19640            if (doingAll) {
19641                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19642                mNewNumServiceProcs++;
19643                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19644                if (!app.serviceb) {
19645                    // This service isn't far enough down on the LRU list to
19646                    // normally be a B service, but if we are low on RAM and it
19647                    // is large we want to force it down since we would prefer to
19648                    // keep launcher over it.
19649                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19650                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19651                        app.serviceHighRam = true;
19652                        app.serviceb = true;
19653                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19654                    } else {
19655                        mNewNumAServiceProcs++;
19656                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19657                    }
19658                } else {
19659                    app.serviceHighRam = false;
19660                }
19661            }
19662            if (app.serviceb) {
19663                adj = ProcessList.SERVICE_B_ADJ;
19664            }
19665        }
19666
19667        app.curRawAdj = adj;
19668
19669        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19670        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19671        if (adj > app.maxAdj) {
19672            adj = app.maxAdj;
19673            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19674                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19675            }
19676        }
19677
19678        // Do final modification to adj.  Everything we do between here and applying
19679        // the final setAdj must be done in this function, because we will also use
19680        // it when computing the final cached adj later.  Note that we don't need to
19681        // worry about this for max adj above, since max adj will always be used to
19682        // keep it out of the cached vaues.
19683        app.curAdj = app.modifyRawOomAdj(adj);
19684        app.curSchedGroup = schedGroup;
19685        app.curProcState = procState;
19686        app.foregroundActivities = foregroundActivities;
19687
19688        return app.curRawAdj;
19689    }
19690
19691    /**
19692     * Record new PSS sample for a process.
19693     */
19694    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19695            long now) {
19696        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19697                swapPss * 1024);
19698        proc.lastPssTime = now;
19699        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19700        if (DEBUG_PSS) Slog.d(TAG_PSS,
19701                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19702                + " state=" + ProcessList.makeProcStateString(procState));
19703        if (proc.initialIdlePss == 0) {
19704            proc.initialIdlePss = pss;
19705        }
19706        proc.lastPss = pss;
19707        proc.lastSwapPss = swapPss;
19708        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19709            proc.lastCachedPss = pss;
19710            proc.lastCachedSwapPss = swapPss;
19711        }
19712
19713        final SparseArray<Pair<Long, String>> watchUids
19714                = mMemWatchProcesses.getMap().get(proc.processName);
19715        Long check = null;
19716        if (watchUids != null) {
19717            Pair<Long, String> val = watchUids.get(proc.uid);
19718            if (val == null) {
19719                val = watchUids.get(0);
19720            }
19721            if (val != null) {
19722                check = val.first;
19723            }
19724        }
19725        if (check != null) {
19726            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19727                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19728                if (!isDebuggable) {
19729                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19730                        isDebuggable = true;
19731                    }
19732                }
19733                if (isDebuggable) {
19734                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19735                    final ProcessRecord myProc = proc;
19736                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19737                    mMemWatchDumpProcName = proc.processName;
19738                    mMemWatchDumpFile = heapdumpFile.toString();
19739                    mMemWatchDumpPid = proc.pid;
19740                    mMemWatchDumpUid = proc.uid;
19741                    BackgroundThread.getHandler().post(new Runnable() {
19742                        @Override
19743                        public void run() {
19744                            revokeUriPermission(ActivityThread.currentActivityThread()
19745                                            .getApplicationThread(),
19746                                    DumpHeapActivity.JAVA_URI,
19747                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19748                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19749                                    UserHandle.myUserId());
19750                            ParcelFileDescriptor fd = null;
19751                            try {
19752                                heapdumpFile.delete();
19753                                fd = ParcelFileDescriptor.open(heapdumpFile,
19754                                        ParcelFileDescriptor.MODE_CREATE |
19755                                                ParcelFileDescriptor.MODE_TRUNCATE |
19756                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19757                                                ParcelFileDescriptor.MODE_APPEND);
19758                                IApplicationThread thread = myProc.thread;
19759                                if (thread != null) {
19760                                    try {
19761                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19762                                                "Requesting dump heap from "
19763                                                + myProc + " to " + heapdumpFile);
19764                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19765                                    } catch (RemoteException e) {
19766                                    }
19767                                }
19768                            } catch (FileNotFoundException e) {
19769                                e.printStackTrace();
19770                            } finally {
19771                                if (fd != null) {
19772                                    try {
19773                                        fd.close();
19774                                    } catch (IOException e) {
19775                                    }
19776                                }
19777                            }
19778                        }
19779                    });
19780                } else {
19781                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19782                            + ", but debugging not enabled");
19783                }
19784            }
19785        }
19786    }
19787
19788    /**
19789     * Schedule PSS collection of a process.
19790     */
19791    void requestPssLocked(ProcessRecord proc, int procState) {
19792        if (mPendingPssProcesses.contains(proc)) {
19793            return;
19794        }
19795        if (mPendingPssProcesses.size() == 0) {
19796            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19797        }
19798        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19799        proc.pssProcState = procState;
19800        mPendingPssProcesses.add(proc);
19801    }
19802
19803    /**
19804     * Schedule PSS collection of all processes.
19805     */
19806    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19807        if (!always) {
19808            if (now < (mLastFullPssTime +
19809                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19810                return;
19811            }
19812        }
19813        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19814        mLastFullPssTime = now;
19815        mFullPssPending = true;
19816        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19817        mPendingPssProcesses.clear();
19818        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19819            ProcessRecord app = mLruProcesses.get(i);
19820            if (app.thread == null
19821                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19822                continue;
19823            }
19824            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19825                app.pssProcState = app.setProcState;
19826                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19827                        mTestPssMode, isSleepingLocked(), now);
19828                mPendingPssProcesses.add(app);
19829            }
19830        }
19831        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19832    }
19833
19834    public void setTestPssMode(boolean enabled) {
19835        synchronized (this) {
19836            mTestPssMode = enabled;
19837            if (enabled) {
19838                // Whenever we enable the mode, we want to take a snapshot all of current
19839                // process mem use.
19840                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19841            }
19842        }
19843    }
19844
19845    /**
19846     * Ask a given process to GC right now.
19847     */
19848    final void performAppGcLocked(ProcessRecord app) {
19849        try {
19850            app.lastRequestedGc = SystemClock.uptimeMillis();
19851            if (app.thread != null) {
19852                if (app.reportLowMemory) {
19853                    app.reportLowMemory = false;
19854                    app.thread.scheduleLowMemory();
19855                } else {
19856                    app.thread.processInBackground();
19857                }
19858            }
19859        } catch (Exception e) {
19860            // whatever.
19861        }
19862    }
19863
19864    /**
19865     * Returns true if things are idle enough to perform GCs.
19866     */
19867    private final boolean canGcNowLocked() {
19868        boolean processingBroadcasts = false;
19869        for (BroadcastQueue q : mBroadcastQueues) {
19870            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19871                processingBroadcasts = true;
19872            }
19873        }
19874        return !processingBroadcasts
19875                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19876    }
19877
19878    /**
19879     * Perform GCs on all processes that are waiting for it, but only
19880     * if things are idle.
19881     */
19882    final void performAppGcsLocked() {
19883        final int N = mProcessesToGc.size();
19884        if (N <= 0) {
19885            return;
19886        }
19887        if (canGcNowLocked()) {
19888            while (mProcessesToGc.size() > 0) {
19889                ProcessRecord proc = mProcessesToGc.remove(0);
19890                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19891                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19892                            <= SystemClock.uptimeMillis()) {
19893                        // To avoid spamming the system, we will GC processes one
19894                        // at a time, waiting a few seconds between each.
19895                        performAppGcLocked(proc);
19896                        scheduleAppGcsLocked();
19897                        return;
19898                    } else {
19899                        // It hasn't been long enough since we last GCed this
19900                        // process...  put it in the list to wait for its time.
19901                        addProcessToGcListLocked(proc);
19902                        break;
19903                    }
19904                }
19905            }
19906
19907            scheduleAppGcsLocked();
19908        }
19909    }
19910
19911    /**
19912     * If all looks good, perform GCs on all processes waiting for them.
19913     */
19914    final void performAppGcsIfAppropriateLocked() {
19915        if (canGcNowLocked()) {
19916            performAppGcsLocked();
19917            return;
19918        }
19919        // Still not idle, wait some more.
19920        scheduleAppGcsLocked();
19921    }
19922
19923    /**
19924     * Schedule the execution of all pending app GCs.
19925     */
19926    final void scheduleAppGcsLocked() {
19927        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19928
19929        if (mProcessesToGc.size() > 0) {
19930            // Schedule a GC for the time to the next process.
19931            ProcessRecord proc = mProcessesToGc.get(0);
19932            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19933
19934            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19935            long now = SystemClock.uptimeMillis();
19936            if (when < (now+GC_TIMEOUT)) {
19937                when = now + GC_TIMEOUT;
19938            }
19939            mHandler.sendMessageAtTime(msg, when);
19940        }
19941    }
19942
19943    /**
19944     * Add a process to the array of processes waiting to be GCed.  Keeps the
19945     * list in sorted order by the last GC time.  The process can't already be
19946     * on the list.
19947     */
19948    final void addProcessToGcListLocked(ProcessRecord proc) {
19949        boolean added = false;
19950        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19951            if (mProcessesToGc.get(i).lastRequestedGc <
19952                    proc.lastRequestedGc) {
19953                added = true;
19954                mProcessesToGc.add(i+1, proc);
19955                break;
19956            }
19957        }
19958        if (!added) {
19959            mProcessesToGc.add(0, proc);
19960        }
19961    }
19962
19963    /**
19964     * Set up to ask a process to GC itself.  This will either do it
19965     * immediately, or put it on the list of processes to gc the next
19966     * time things are idle.
19967     */
19968    final void scheduleAppGcLocked(ProcessRecord app) {
19969        long now = SystemClock.uptimeMillis();
19970        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19971            return;
19972        }
19973        if (!mProcessesToGc.contains(app)) {
19974            addProcessToGcListLocked(app);
19975            scheduleAppGcsLocked();
19976        }
19977    }
19978
19979    final void checkExcessivePowerUsageLocked(boolean doKills) {
19980        updateCpuStatsNow();
19981
19982        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19983        boolean doWakeKills = doKills;
19984        boolean doCpuKills = doKills;
19985        if (mLastPowerCheckRealtime == 0) {
19986            doWakeKills = false;
19987        }
19988        if (mLastPowerCheckUptime == 0) {
19989            doCpuKills = false;
19990        }
19991        if (stats.isScreenOn()) {
19992            doWakeKills = false;
19993        }
19994        final long curRealtime = SystemClock.elapsedRealtime();
19995        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19996        final long curUptime = SystemClock.uptimeMillis();
19997        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19998        mLastPowerCheckRealtime = curRealtime;
19999        mLastPowerCheckUptime = curUptime;
20000        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20001            doWakeKills = false;
20002        }
20003        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20004            doCpuKills = false;
20005        }
20006        int i = mLruProcesses.size();
20007        while (i > 0) {
20008            i--;
20009            ProcessRecord app = mLruProcesses.get(i);
20010            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20011                long wtime;
20012                synchronized (stats) {
20013                    wtime = stats.getProcessWakeTime(app.info.uid,
20014                            app.pid, curRealtime);
20015                }
20016                long wtimeUsed = wtime - app.lastWakeTime;
20017                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20018                if (DEBUG_POWER) {
20019                    StringBuilder sb = new StringBuilder(128);
20020                    sb.append("Wake for ");
20021                    app.toShortString(sb);
20022                    sb.append(": over ");
20023                    TimeUtils.formatDuration(realtimeSince, sb);
20024                    sb.append(" used ");
20025                    TimeUtils.formatDuration(wtimeUsed, sb);
20026                    sb.append(" (");
20027                    sb.append((wtimeUsed*100)/realtimeSince);
20028                    sb.append("%)");
20029                    Slog.i(TAG_POWER, sb.toString());
20030                    sb.setLength(0);
20031                    sb.append("CPU for ");
20032                    app.toShortString(sb);
20033                    sb.append(": over ");
20034                    TimeUtils.formatDuration(uptimeSince, sb);
20035                    sb.append(" used ");
20036                    TimeUtils.formatDuration(cputimeUsed, sb);
20037                    sb.append(" (");
20038                    sb.append((cputimeUsed*100)/uptimeSince);
20039                    sb.append("%)");
20040                    Slog.i(TAG_POWER, sb.toString());
20041                }
20042                // If a process has held a wake lock for more
20043                // than 50% of the time during this period,
20044                // that sounds bad.  Kill!
20045                if (doWakeKills && realtimeSince > 0
20046                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20047                    synchronized (stats) {
20048                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20049                                realtimeSince, wtimeUsed);
20050                    }
20051                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20052                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20053                } else if (doCpuKills && uptimeSince > 0
20054                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20055                    synchronized (stats) {
20056                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20057                                uptimeSince, cputimeUsed);
20058                    }
20059                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20060                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20061                } else {
20062                    app.lastWakeTime = wtime;
20063                    app.lastCpuTime = app.curCpuTime;
20064                }
20065            }
20066        }
20067    }
20068
20069    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20070            long nowElapsed) {
20071        boolean success = true;
20072
20073        if (app.curRawAdj != app.setRawAdj) {
20074            app.setRawAdj = app.curRawAdj;
20075        }
20076
20077        int changes = 0;
20078
20079        if (app.curAdj != app.setAdj) {
20080            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20081            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20082                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20083                    + app.adjType);
20084            app.setAdj = app.curAdj;
20085        }
20086
20087        if (app.setSchedGroup != app.curSchedGroup) {
20088            app.setSchedGroup = app.curSchedGroup;
20089            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20090                    "Setting sched group of " + app.processName
20091                    + " to " + app.curSchedGroup);
20092            if (app.waitingToKill != null && app.curReceiver == null
20093                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20094                app.kill(app.waitingToKill, true);
20095                success = false;
20096            } else {
20097                int processGroup;
20098                switch (app.curSchedGroup) {
20099                    case ProcessList.SCHED_GROUP_BACKGROUND:
20100                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20101                        break;
20102                    case ProcessList.SCHED_GROUP_TOP_APP:
20103                        processGroup = Process.THREAD_GROUP_TOP_APP;
20104                        break;
20105                    default:
20106                        processGroup = Process.THREAD_GROUP_DEFAULT;
20107                        break;
20108                }
20109                if (true) {
20110                    long oldId = Binder.clearCallingIdentity();
20111                    try {
20112                        Process.setProcessGroup(app.pid, processGroup);
20113                    } catch (Exception e) {
20114                        Slog.w(TAG, "Failed setting process group of " + app.pid
20115                                + " to " + app.curSchedGroup);
20116                        e.printStackTrace();
20117                    } finally {
20118                        Binder.restoreCallingIdentity(oldId);
20119                    }
20120                } else {
20121                    if (app.thread != null) {
20122                        try {
20123                            app.thread.setSchedulingGroup(processGroup);
20124                        } catch (RemoteException e) {
20125                        }
20126                    }
20127                }
20128            }
20129        }
20130        if (app.repForegroundActivities != app.foregroundActivities) {
20131            app.repForegroundActivities = app.foregroundActivities;
20132            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20133        }
20134        if (app.repProcState != app.curProcState) {
20135            app.repProcState = app.curProcState;
20136            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20137            if (app.thread != null) {
20138                try {
20139                    if (false) {
20140                        //RuntimeException h = new RuntimeException("here");
20141                        Slog.i(TAG, "Sending new process state " + app.repProcState
20142                                + " to " + app /*, h*/);
20143                    }
20144                    app.thread.setProcessState(app.repProcState);
20145                } catch (RemoteException e) {
20146                }
20147            }
20148        }
20149        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20150                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20151            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20152                // Experimental code to more aggressively collect pss while
20153                // running test...  the problem is that this tends to collect
20154                // the data right when a process is transitioning between process
20155                // states, which well tend to give noisy data.
20156                long start = SystemClock.uptimeMillis();
20157                long pss = Debug.getPss(app.pid, mTmpLong, null);
20158                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20159                mPendingPssProcesses.remove(app);
20160                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20161                        + " to " + app.curProcState + ": "
20162                        + (SystemClock.uptimeMillis()-start) + "ms");
20163            }
20164            app.lastStateTime = now;
20165            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20166                    mTestPssMode, isSleepingLocked(), now);
20167            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20168                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20169                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20170                    + (app.nextPssTime-now) + ": " + app);
20171        } else {
20172            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20173                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20174                    mTestPssMode)))) {
20175                requestPssLocked(app, app.setProcState);
20176                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20177                        mTestPssMode, isSleepingLocked(), now);
20178            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20179                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20180        }
20181        if (app.setProcState != app.curProcState) {
20182            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20183                    "Proc state change of " + app.processName
20184                            + " to " + app.curProcState);
20185            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20186            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20187            if (setImportant && !curImportant) {
20188                // This app is no longer something we consider important enough to allow to
20189                // use arbitrary amounts of battery power.  Note
20190                // its current wake lock time to later know to kill it if
20191                // it is not behaving well.
20192                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20193                synchronized (stats) {
20194                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20195                            app.pid, nowElapsed);
20196                }
20197                app.lastCpuTime = app.curCpuTime;
20198
20199            }
20200            // Inform UsageStats of important process state change
20201            // Must be called before updating setProcState
20202            maybeUpdateUsageStatsLocked(app, nowElapsed);
20203
20204            app.setProcState = app.curProcState;
20205            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20206                app.notCachedSinceIdle = false;
20207            }
20208            if (!doingAll) {
20209                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20210            } else {
20211                app.procStateChanged = true;
20212            }
20213        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20214                > USAGE_STATS_INTERACTION_INTERVAL) {
20215            // For apps that sit around for a long time in the interactive state, we need
20216            // to report this at least once a day so they don't go idle.
20217            maybeUpdateUsageStatsLocked(app, nowElapsed);
20218        }
20219
20220        if (changes != 0) {
20221            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20222                    "Changes in " + app + ": " + changes);
20223            int i = mPendingProcessChanges.size()-1;
20224            ProcessChangeItem item = null;
20225            while (i >= 0) {
20226                item = mPendingProcessChanges.get(i);
20227                if (item.pid == app.pid) {
20228                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20229                            "Re-using existing item: " + item);
20230                    break;
20231                }
20232                i--;
20233            }
20234            if (i < 0) {
20235                // No existing item in pending changes; need a new one.
20236                final int NA = mAvailProcessChanges.size();
20237                if (NA > 0) {
20238                    item = mAvailProcessChanges.remove(NA-1);
20239                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20240                            "Retrieving available item: " + item);
20241                } else {
20242                    item = new ProcessChangeItem();
20243                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20244                            "Allocating new item: " + item);
20245                }
20246                item.changes = 0;
20247                item.pid = app.pid;
20248                item.uid = app.info.uid;
20249                if (mPendingProcessChanges.size() == 0) {
20250                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20251                            "*** Enqueueing dispatch processes changed!");
20252                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20253                }
20254                mPendingProcessChanges.add(item);
20255            }
20256            item.changes |= changes;
20257            item.processState = app.repProcState;
20258            item.foregroundActivities = app.repForegroundActivities;
20259            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20260                    "Item " + Integer.toHexString(System.identityHashCode(item))
20261                    + " " + app.toShortString() + ": changes=" + item.changes
20262                    + " procState=" + item.processState
20263                    + " foreground=" + item.foregroundActivities
20264                    + " type=" + app.adjType + " source=" + app.adjSource
20265                    + " target=" + app.adjTarget);
20266        }
20267
20268        return success;
20269    }
20270
20271    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20272        final UidRecord.ChangeItem pendingChange;
20273        if (uidRec == null || uidRec.pendingChange == null) {
20274            if (mPendingUidChanges.size() == 0) {
20275                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20276                        "*** Enqueueing dispatch uid changed!");
20277                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20278            }
20279            final int NA = mAvailUidChanges.size();
20280            if (NA > 0) {
20281                pendingChange = mAvailUidChanges.remove(NA-1);
20282                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20283                        "Retrieving available item: " + pendingChange);
20284            } else {
20285                pendingChange = new UidRecord.ChangeItem();
20286                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20287                        "Allocating new item: " + pendingChange);
20288            }
20289            if (uidRec != null) {
20290                uidRec.pendingChange = pendingChange;
20291                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20292                    // If this uid is going away, and we haven't yet reported it is gone,
20293                    // then do so now.
20294                    change = UidRecord.CHANGE_GONE_IDLE;
20295                }
20296            } else if (uid < 0) {
20297                throw new IllegalArgumentException("No UidRecord or uid");
20298            }
20299            pendingChange.uidRecord = uidRec;
20300            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20301            mPendingUidChanges.add(pendingChange);
20302        } else {
20303            pendingChange = uidRec.pendingChange;
20304            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20305                change = UidRecord.CHANGE_GONE_IDLE;
20306            }
20307        }
20308        pendingChange.change = change;
20309        pendingChange.processState = uidRec != null
20310                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20311    }
20312
20313    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20314            String authority) {
20315        if (app == null) return;
20316        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20317            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20318            if (userState == null) return;
20319            final long now = SystemClock.elapsedRealtime();
20320            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20321            if (lastReported == null || lastReported < now - 60 * 1000L) {
20322                mUsageStatsService.reportContentProviderUsage(
20323                        authority, providerPkgName, app.userId);
20324                userState.mProviderLastReportedFg.put(authority, now);
20325            }
20326        }
20327    }
20328
20329    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20330        if (DEBUG_USAGE_STATS) {
20331            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20332                    + "] state changes: old = " + app.setProcState + ", new = "
20333                    + app.curProcState);
20334        }
20335        if (mUsageStatsService == null) {
20336            return;
20337        }
20338        boolean isInteraction;
20339        // To avoid some abuse patterns, we are going to be careful about what we consider
20340        // to be an app interaction.  Being the top activity doesn't count while the display
20341        // is sleeping, nor do short foreground services.
20342        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20343            isInteraction = true;
20344            app.fgInteractionTime = 0;
20345        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20346            if (app.fgInteractionTime == 0) {
20347                app.fgInteractionTime = nowElapsed;
20348                isInteraction = false;
20349            } else {
20350                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20351            }
20352        } else {
20353            isInteraction = app.curProcState
20354                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20355            app.fgInteractionTime = 0;
20356        }
20357        if (isInteraction && (!app.reportedInteraction
20358                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20359            app.interactionEventTime = nowElapsed;
20360            String[] packages = app.getPackageList();
20361            if (packages != null) {
20362                for (int i = 0; i < packages.length; i++) {
20363                    mUsageStatsService.reportEvent(packages[i], app.userId,
20364                            UsageEvents.Event.SYSTEM_INTERACTION);
20365                }
20366            }
20367        }
20368        app.reportedInteraction = isInteraction;
20369        if (!isInteraction) {
20370            app.interactionEventTime = 0;
20371        }
20372    }
20373
20374    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20375        if (proc.thread != null) {
20376            if (proc.baseProcessTracker != null) {
20377                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20378            }
20379        }
20380    }
20381
20382    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20383            ProcessRecord TOP_APP, boolean doingAll, long now) {
20384        if (app.thread == null) {
20385            return false;
20386        }
20387
20388        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20389
20390        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20391    }
20392
20393    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20394            boolean oomAdj) {
20395        if (isForeground != proc.foregroundServices) {
20396            proc.foregroundServices = isForeground;
20397            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20398                    proc.info.uid);
20399            if (isForeground) {
20400                if (curProcs == null) {
20401                    curProcs = new ArrayList<ProcessRecord>();
20402                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20403                }
20404                if (!curProcs.contains(proc)) {
20405                    curProcs.add(proc);
20406                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20407                            proc.info.packageName, proc.info.uid);
20408                }
20409            } else {
20410                if (curProcs != null) {
20411                    if (curProcs.remove(proc)) {
20412                        mBatteryStatsService.noteEvent(
20413                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20414                                proc.info.packageName, proc.info.uid);
20415                        if (curProcs.size() <= 0) {
20416                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20417                        }
20418                    }
20419                }
20420            }
20421            if (oomAdj) {
20422                updateOomAdjLocked();
20423            }
20424        }
20425    }
20426
20427    private final ActivityRecord resumedAppLocked() {
20428        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20429        String pkg;
20430        int uid;
20431        if (act != null) {
20432            pkg = act.packageName;
20433            uid = act.info.applicationInfo.uid;
20434        } else {
20435            pkg = null;
20436            uid = -1;
20437        }
20438        // Has the UID or resumed package name changed?
20439        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20440                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20441            if (mCurResumedPackage != null) {
20442                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20443                        mCurResumedPackage, mCurResumedUid);
20444            }
20445            mCurResumedPackage = pkg;
20446            mCurResumedUid = uid;
20447            if (mCurResumedPackage != null) {
20448                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20449                        mCurResumedPackage, mCurResumedUid);
20450            }
20451        }
20452        return act;
20453    }
20454
20455    final boolean updateOomAdjLocked(ProcessRecord app) {
20456        final ActivityRecord TOP_ACT = resumedAppLocked();
20457        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20458        final boolean wasCached = app.cached;
20459
20460        mAdjSeq++;
20461
20462        // This is the desired cached adjusment we want to tell it to use.
20463        // If our app is currently cached, we know it, and that is it.  Otherwise,
20464        // we don't know it yet, and it needs to now be cached we will then
20465        // need to do a complete oom adj.
20466        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20467                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20468        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20469                SystemClock.uptimeMillis());
20470        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20471            // Changed to/from cached state, so apps after it in the LRU
20472            // list may also be changed.
20473            updateOomAdjLocked();
20474        }
20475        return success;
20476    }
20477
20478    final void updateOomAdjLocked() {
20479        final ActivityRecord TOP_ACT = resumedAppLocked();
20480        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20481        final long now = SystemClock.uptimeMillis();
20482        final long nowElapsed = SystemClock.elapsedRealtime();
20483        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20484        final int N = mLruProcesses.size();
20485
20486        if (false) {
20487            RuntimeException e = new RuntimeException();
20488            e.fillInStackTrace();
20489            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20490        }
20491
20492        // Reset state in all uid records.
20493        for (int i=mActiveUids.size()-1; i>=0; i--) {
20494            final UidRecord uidRec = mActiveUids.valueAt(i);
20495            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20496                    "Starting update of " + uidRec);
20497            uidRec.reset();
20498        }
20499
20500        mStackSupervisor.rankTaskLayersIfNeeded();
20501
20502        mAdjSeq++;
20503        mNewNumServiceProcs = 0;
20504        mNewNumAServiceProcs = 0;
20505
20506        final int emptyProcessLimit;
20507        final int cachedProcessLimit;
20508        if (mProcessLimit <= 0) {
20509            emptyProcessLimit = cachedProcessLimit = 0;
20510        } else if (mProcessLimit == 1) {
20511            emptyProcessLimit = 1;
20512            cachedProcessLimit = 0;
20513        } else {
20514            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20515            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20516        }
20517
20518        // Let's determine how many processes we have running vs.
20519        // how many slots we have for background processes; we may want
20520        // to put multiple processes in a slot of there are enough of
20521        // them.
20522        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20523                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20524        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20525        if (numEmptyProcs > cachedProcessLimit) {
20526            // If there are more empty processes than our limit on cached
20527            // processes, then use the cached process limit for the factor.
20528            // This ensures that the really old empty processes get pushed
20529            // down to the bottom, so if we are running low on memory we will
20530            // have a better chance at keeping around more cached processes
20531            // instead of a gazillion empty processes.
20532            numEmptyProcs = cachedProcessLimit;
20533        }
20534        int emptyFactor = numEmptyProcs/numSlots;
20535        if (emptyFactor < 1) emptyFactor = 1;
20536        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20537        if (cachedFactor < 1) cachedFactor = 1;
20538        int stepCached = 0;
20539        int stepEmpty = 0;
20540        int numCached = 0;
20541        int numEmpty = 0;
20542        int numTrimming = 0;
20543
20544        mNumNonCachedProcs = 0;
20545        mNumCachedHiddenProcs = 0;
20546
20547        // First update the OOM adjustment for each of the
20548        // application processes based on their current state.
20549        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20550        int nextCachedAdj = curCachedAdj+1;
20551        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20552        int nextEmptyAdj = curEmptyAdj+2;
20553        for (int i=N-1; i>=0; i--) {
20554            ProcessRecord app = mLruProcesses.get(i);
20555            if (!app.killedByAm && app.thread != null) {
20556                app.procStateChanged = false;
20557                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20558
20559                // If we haven't yet assigned the final cached adj
20560                // to the process, do that now.
20561                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20562                    switch (app.curProcState) {
20563                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20564                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20565                            // This process is a cached process holding activities...
20566                            // assign it the next cached value for that type, and then
20567                            // step that cached level.
20568                            app.curRawAdj = curCachedAdj;
20569                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20570                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20571                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20572                                    + ")");
20573                            if (curCachedAdj != nextCachedAdj) {
20574                                stepCached++;
20575                                if (stepCached >= cachedFactor) {
20576                                    stepCached = 0;
20577                                    curCachedAdj = nextCachedAdj;
20578                                    nextCachedAdj += 2;
20579                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20580                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20581                                    }
20582                                }
20583                            }
20584                            break;
20585                        default:
20586                            // For everything else, assign next empty cached process
20587                            // level and bump that up.  Note that this means that
20588                            // long-running services that have dropped down to the
20589                            // cached level will be treated as empty (since their process
20590                            // state is still as a service), which is what we want.
20591                            app.curRawAdj = curEmptyAdj;
20592                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20593                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20594                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20595                                    + ")");
20596                            if (curEmptyAdj != nextEmptyAdj) {
20597                                stepEmpty++;
20598                                if (stepEmpty >= emptyFactor) {
20599                                    stepEmpty = 0;
20600                                    curEmptyAdj = nextEmptyAdj;
20601                                    nextEmptyAdj += 2;
20602                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20603                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20604                                    }
20605                                }
20606                            }
20607                            break;
20608                    }
20609                }
20610
20611                applyOomAdjLocked(app, true, now, nowElapsed);
20612
20613                // Count the number of process types.
20614                switch (app.curProcState) {
20615                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20616                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20617                        mNumCachedHiddenProcs++;
20618                        numCached++;
20619                        if (numCached > cachedProcessLimit) {
20620                            app.kill("cached #" + numCached, true);
20621                        }
20622                        break;
20623                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20624                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20625                                && app.lastActivityTime < oldTime) {
20626                            app.kill("empty for "
20627                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20628                                    / 1000) + "s", true);
20629                        } else {
20630                            numEmpty++;
20631                            if (numEmpty > emptyProcessLimit) {
20632                                app.kill("empty #" + numEmpty, true);
20633                            }
20634                        }
20635                        break;
20636                    default:
20637                        mNumNonCachedProcs++;
20638                        break;
20639                }
20640
20641                if (app.isolated && app.services.size() <= 0) {
20642                    // If this is an isolated process, and there are no
20643                    // services running in it, then the process is no longer
20644                    // needed.  We agressively kill these because we can by
20645                    // definition not re-use the same process again, and it is
20646                    // good to avoid having whatever code was running in them
20647                    // left sitting around after no longer needed.
20648                    app.kill("isolated not needed", true);
20649                } else {
20650                    // Keeping this process, update its uid.
20651                    final UidRecord uidRec = app.uidRecord;
20652                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20653                        uidRec.curProcState = app.curProcState;
20654                    }
20655                }
20656
20657                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20658                        && !app.killedByAm) {
20659                    numTrimming++;
20660                }
20661            }
20662        }
20663
20664        mNumServiceProcs = mNewNumServiceProcs;
20665
20666        // Now determine the memory trimming level of background processes.
20667        // Unfortunately we need to start at the back of the list to do this
20668        // properly.  We only do this if the number of background apps we
20669        // are managing to keep around is less than half the maximum we desire;
20670        // if we are keeping a good number around, we'll let them use whatever
20671        // memory they want.
20672        final int numCachedAndEmpty = numCached + numEmpty;
20673        int memFactor;
20674        if (numCached <= ProcessList.TRIM_CACHED_APPS
20675                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20676            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20677                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20678            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20679                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20680            } else {
20681                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20682            }
20683        } else {
20684            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20685        }
20686        // We always allow the memory level to go up (better).  We only allow it to go
20687        // down if we are in a state where that is allowed, *and* the total number of processes
20688        // has gone down since last time.
20689        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20690                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20691                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20692        if (memFactor > mLastMemoryLevel) {
20693            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20694                memFactor = mLastMemoryLevel;
20695                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20696            }
20697        }
20698        if (memFactor != mLastMemoryLevel) {
20699            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20700        }
20701        mLastMemoryLevel = memFactor;
20702        mLastNumProcesses = mLruProcesses.size();
20703        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20704        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20705        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20706            if (mLowRamStartTime == 0) {
20707                mLowRamStartTime = now;
20708            }
20709            int step = 0;
20710            int fgTrimLevel;
20711            switch (memFactor) {
20712                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20713                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20714                    break;
20715                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20716                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20717                    break;
20718                default:
20719                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20720                    break;
20721            }
20722            int factor = numTrimming/3;
20723            int minFactor = 2;
20724            if (mHomeProcess != null) minFactor++;
20725            if (mPreviousProcess != null) minFactor++;
20726            if (factor < minFactor) factor = minFactor;
20727            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20728            for (int i=N-1; i>=0; i--) {
20729                ProcessRecord app = mLruProcesses.get(i);
20730                if (allChanged || app.procStateChanged) {
20731                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20732                    app.procStateChanged = false;
20733                }
20734                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20735                        && !app.killedByAm) {
20736                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20737                        try {
20738                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20739                                    "Trimming memory of " + app.processName + " to " + curLevel);
20740                            app.thread.scheduleTrimMemory(curLevel);
20741                        } catch (RemoteException e) {
20742                        }
20743                        if (false) {
20744                            // For now we won't do this; our memory trimming seems
20745                            // to be good enough at this point that destroying
20746                            // activities causes more harm than good.
20747                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20748                                    && app != mHomeProcess && app != mPreviousProcess) {
20749                                // Need to do this on its own message because the stack may not
20750                                // be in a consistent state at this point.
20751                                // For these apps we will also finish their activities
20752                                // to help them free memory.
20753                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20754                            }
20755                        }
20756                    }
20757                    app.trimMemoryLevel = curLevel;
20758                    step++;
20759                    if (step >= factor) {
20760                        step = 0;
20761                        switch (curLevel) {
20762                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20763                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20764                                break;
20765                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20766                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20767                                break;
20768                        }
20769                    }
20770                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20771                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20772                            && app.thread != null) {
20773                        try {
20774                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20775                                    "Trimming memory of heavy-weight " + app.processName
20776                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20777                            app.thread.scheduleTrimMemory(
20778                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20779                        } catch (RemoteException e) {
20780                        }
20781                    }
20782                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20783                } else {
20784                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20785                            || app.systemNoUi) && app.pendingUiClean) {
20786                        // If this application is now in the background and it
20787                        // had done UI, then give it the special trim level to
20788                        // have it free UI resources.
20789                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20790                        if (app.trimMemoryLevel < level && app.thread != null) {
20791                            try {
20792                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20793                                        "Trimming memory of bg-ui " + app.processName
20794                                        + " to " + level);
20795                                app.thread.scheduleTrimMemory(level);
20796                            } catch (RemoteException e) {
20797                            }
20798                        }
20799                        app.pendingUiClean = false;
20800                    }
20801                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20802                        try {
20803                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20804                                    "Trimming memory of fg " + app.processName
20805                                    + " to " + fgTrimLevel);
20806                            app.thread.scheduleTrimMemory(fgTrimLevel);
20807                        } catch (RemoteException e) {
20808                        }
20809                    }
20810                    app.trimMemoryLevel = fgTrimLevel;
20811                }
20812            }
20813        } else {
20814            if (mLowRamStartTime != 0) {
20815                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20816                mLowRamStartTime = 0;
20817            }
20818            for (int i=N-1; i>=0; i--) {
20819                ProcessRecord app = mLruProcesses.get(i);
20820                if (allChanged || app.procStateChanged) {
20821                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20822                    app.procStateChanged = false;
20823                }
20824                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20825                        || app.systemNoUi) && app.pendingUiClean) {
20826                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20827                            && app.thread != null) {
20828                        try {
20829                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20830                                    "Trimming memory of ui hidden " + app.processName
20831                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20832                            app.thread.scheduleTrimMemory(
20833                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20834                        } catch (RemoteException e) {
20835                        }
20836                    }
20837                    app.pendingUiClean = false;
20838                }
20839                app.trimMemoryLevel = 0;
20840            }
20841        }
20842
20843        if (mAlwaysFinishActivities) {
20844            // Need to do this on its own message because the stack may not
20845            // be in a consistent state at this point.
20846            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20847        }
20848
20849        if (allChanged) {
20850            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20851        }
20852
20853        // Update from any uid changes.
20854        for (int i=mActiveUids.size()-1; i>=0; i--) {
20855            final UidRecord uidRec = mActiveUids.valueAt(i);
20856            int uidChange = UidRecord.CHANGE_PROCSTATE;
20857            if (uidRec.setProcState != uidRec.curProcState) {
20858                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20859                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20860                        + " to " + uidRec.curProcState);
20861                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20862                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20863                        uidRec.lastBackgroundTime = nowElapsed;
20864                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20865                            // Note: the background settle time is in elapsed realtime, while
20866                            // the handler time base is uptime.  All this means is that we may
20867                            // stop background uids later than we had intended, but that only
20868                            // happens because the device was sleeping so we are okay anyway.
20869                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20870                        }
20871                    }
20872                } else {
20873                    if (uidRec.idle) {
20874                        uidChange = UidRecord.CHANGE_ACTIVE;
20875                        uidRec.idle = false;
20876                    }
20877                    uidRec.lastBackgroundTime = 0;
20878                }
20879                uidRec.setProcState = uidRec.curProcState;
20880                enqueueUidChangeLocked(uidRec, -1, uidChange);
20881                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20882            }
20883        }
20884
20885        if (mProcessStats.shouldWriteNowLocked(now)) {
20886            mHandler.post(new Runnable() {
20887                @Override public void run() {
20888                    synchronized (ActivityManagerService.this) {
20889                        mProcessStats.writeStateAsyncLocked();
20890                    }
20891                }
20892            });
20893        }
20894
20895        if (DEBUG_OOM_ADJ) {
20896            final long duration = SystemClock.uptimeMillis() - now;
20897            if (false) {
20898                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20899                        new RuntimeException("here").fillInStackTrace());
20900            } else {
20901                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20902            }
20903        }
20904    }
20905
20906    final void idleUids() {
20907        synchronized (this) {
20908            final long nowElapsed = SystemClock.elapsedRealtime();
20909            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20910            long nextTime = 0;
20911            for (int i=mActiveUids.size()-1; i>=0; i--) {
20912                final UidRecord uidRec = mActiveUids.valueAt(i);
20913                final long bgTime = uidRec.lastBackgroundTime;
20914                if (bgTime > 0 && !uidRec.idle) {
20915                    if (bgTime <= maxBgTime) {
20916                        uidRec.idle = true;
20917                        doStopUidLocked(uidRec.uid, uidRec);
20918                    } else {
20919                        if (nextTime == 0 || nextTime > bgTime) {
20920                            nextTime = bgTime;
20921                        }
20922                    }
20923                }
20924            }
20925            if (nextTime > 0) {
20926                mHandler.removeMessages(IDLE_UIDS_MSG);
20927                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20928                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20929            }
20930        }
20931    }
20932
20933    final void runInBackgroundDisabled(int uid) {
20934        synchronized (this) {
20935            UidRecord uidRec = mActiveUids.get(uid);
20936            if (uidRec != null) {
20937                // This uid is actually running...  should it be considered background now?
20938                if (uidRec.idle) {
20939                    doStopUidLocked(uidRec.uid, uidRec);
20940                }
20941            } else {
20942                // This uid isn't actually running...  still send a report about it being "stopped".
20943                doStopUidLocked(uid, null);
20944            }
20945        }
20946    }
20947
20948    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20949        mServices.stopInBackgroundLocked(uid);
20950        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20951    }
20952
20953    final void trimApplications() {
20954        synchronized (this) {
20955            int i;
20956
20957            // First remove any unused application processes whose package
20958            // has been removed.
20959            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20960                final ProcessRecord app = mRemovedProcesses.get(i);
20961                if (app.activities.size() == 0
20962                        && app.curReceiver == null && app.services.size() == 0) {
20963                    Slog.i(
20964                        TAG, "Exiting empty application process "
20965                        + app.toShortString() + " ("
20966                        + (app.thread != null ? app.thread.asBinder() : null)
20967                        + ")\n");
20968                    if (app.pid > 0 && app.pid != MY_PID) {
20969                        app.kill("empty", false);
20970                    } else {
20971                        try {
20972                            app.thread.scheduleExit();
20973                        } catch (Exception e) {
20974                            // Ignore exceptions.
20975                        }
20976                    }
20977                    cleanUpApplicationRecordLocked(app, false, true, -1);
20978                    mRemovedProcesses.remove(i);
20979
20980                    if (app.persistent) {
20981                        addAppLocked(app.info, false, null /* ABI override */);
20982                    }
20983                }
20984            }
20985
20986            // Now update the oom adj for all processes.
20987            updateOomAdjLocked();
20988        }
20989    }
20990
20991    /** This method sends the specified signal to each of the persistent apps */
20992    public void signalPersistentProcesses(int sig) throws RemoteException {
20993        if (sig != Process.SIGNAL_USR1) {
20994            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20995        }
20996
20997        synchronized (this) {
20998            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20999                    != PackageManager.PERMISSION_GRANTED) {
21000                throw new SecurityException("Requires permission "
21001                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21002            }
21003
21004            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21005                ProcessRecord r = mLruProcesses.get(i);
21006                if (r.thread != null && r.persistent) {
21007                    Process.sendSignal(r.pid, sig);
21008                }
21009            }
21010        }
21011    }
21012
21013    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21014        if (proc == null || proc == mProfileProc) {
21015            proc = mProfileProc;
21016            profileType = mProfileType;
21017            clearProfilerLocked();
21018        }
21019        if (proc == null) {
21020            return;
21021        }
21022        try {
21023            proc.thread.profilerControl(false, null, profileType);
21024        } catch (RemoteException e) {
21025            throw new IllegalStateException("Process disappeared");
21026        }
21027    }
21028
21029    private void clearProfilerLocked() {
21030        if (mProfileFd != null) {
21031            try {
21032                mProfileFd.close();
21033            } catch (IOException e) {
21034            }
21035        }
21036        mProfileApp = null;
21037        mProfileProc = null;
21038        mProfileFile = null;
21039        mProfileType = 0;
21040        mAutoStopProfiler = false;
21041        mSamplingInterval = 0;
21042    }
21043
21044    public boolean profileControl(String process, int userId, boolean start,
21045            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21046
21047        try {
21048            synchronized (this) {
21049                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21050                // its own permission.
21051                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21052                        != PackageManager.PERMISSION_GRANTED) {
21053                    throw new SecurityException("Requires permission "
21054                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21055                }
21056
21057                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21058                    throw new IllegalArgumentException("null profile info or fd");
21059                }
21060
21061                ProcessRecord proc = null;
21062                if (process != null) {
21063                    proc = findProcessLocked(process, userId, "profileControl");
21064                }
21065
21066                if (start && (proc == null || proc.thread == null)) {
21067                    throw new IllegalArgumentException("Unknown process: " + process);
21068                }
21069
21070                if (start) {
21071                    stopProfilerLocked(null, 0);
21072                    setProfileApp(proc.info, proc.processName, profilerInfo);
21073                    mProfileProc = proc;
21074                    mProfileType = profileType;
21075                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21076                    try {
21077                        fd = fd.dup();
21078                    } catch (IOException e) {
21079                        fd = null;
21080                    }
21081                    profilerInfo.profileFd = fd;
21082                    proc.thread.profilerControl(start, profilerInfo, profileType);
21083                    fd = null;
21084                    mProfileFd = null;
21085                } else {
21086                    stopProfilerLocked(proc, profileType);
21087                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21088                        try {
21089                            profilerInfo.profileFd.close();
21090                        } catch (IOException e) {
21091                        }
21092                    }
21093                }
21094
21095                return true;
21096            }
21097        } catch (RemoteException e) {
21098            throw new IllegalStateException("Process disappeared");
21099        } finally {
21100            if (profilerInfo != null && profilerInfo.profileFd != null) {
21101                try {
21102                    profilerInfo.profileFd.close();
21103                } catch (IOException e) {
21104                }
21105            }
21106        }
21107    }
21108
21109    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21110        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21111                userId, true, ALLOW_FULL_ONLY, callName, null);
21112        ProcessRecord proc = null;
21113        try {
21114            int pid = Integer.parseInt(process);
21115            synchronized (mPidsSelfLocked) {
21116                proc = mPidsSelfLocked.get(pid);
21117            }
21118        } catch (NumberFormatException e) {
21119        }
21120
21121        if (proc == null) {
21122            ArrayMap<String, SparseArray<ProcessRecord>> all
21123                    = mProcessNames.getMap();
21124            SparseArray<ProcessRecord> procs = all.get(process);
21125            if (procs != null && procs.size() > 0) {
21126                proc = procs.valueAt(0);
21127                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21128                    for (int i=1; i<procs.size(); i++) {
21129                        ProcessRecord thisProc = procs.valueAt(i);
21130                        if (thisProc.userId == userId) {
21131                            proc = thisProc;
21132                            break;
21133                        }
21134                    }
21135                }
21136            }
21137        }
21138
21139        return proc;
21140    }
21141
21142    public boolean dumpHeap(String process, int userId, boolean managed,
21143            String path, ParcelFileDescriptor fd) throws RemoteException {
21144
21145        try {
21146            synchronized (this) {
21147                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21148                // its own permission (same as profileControl).
21149                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21150                        != PackageManager.PERMISSION_GRANTED) {
21151                    throw new SecurityException("Requires permission "
21152                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21153                }
21154
21155                if (fd == null) {
21156                    throw new IllegalArgumentException("null fd");
21157                }
21158
21159                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21160                if (proc == null || proc.thread == null) {
21161                    throw new IllegalArgumentException("Unknown process: " + process);
21162                }
21163
21164                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21165                if (!isDebuggable) {
21166                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21167                        throw new SecurityException("Process not debuggable: " + proc);
21168                    }
21169                }
21170
21171                proc.thread.dumpHeap(managed, path, fd);
21172                fd = null;
21173                return true;
21174            }
21175        } catch (RemoteException e) {
21176            throw new IllegalStateException("Process disappeared");
21177        } finally {
21178            if (fd != null) {
21179                try {
21180                    fd.close();
21181                } catch (IOException e) {
21182                }
21183            }
21184        }
21185    }
21186
21187    @Override
21188    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21189            String reportPackage) {
21190        if (processName != null) {
21191            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21192                    "setDumpHeapDebugLimit()");
21193        } else {
21194            synchronized (mPidsSelfLocked) {
21195                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21196                if (proc == null) {
21197                    throw new SecurityException("No process found for calling pid "
21198                            + Binder.getCallingPid());
21199                }
21200                if (!Build.IS_DEBUGGABLE
21201                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21202                    throw new SecurityException("Not running a debuggable build");
21203                }
21204                processName = proc.processName;
21205                uid = proc.uid;
21206                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21207                    throw new SecurityException("Package " + reportPackage + " is not running in "
21208                            + proc);
21209                }
21210            }
21211        }
21212        synchronized (this) {
21213            if (maxMemSize > 0) {
21214                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21215            } else {
21216                if (uid != 0) {
21217                    mMemWatchProcesses.remove(processName, uid);
21218                } else {
21219                    mMemWatchProcesses.getMap().remove(processName);
21220                }
21221            }
21222        }
21223    }
21224
21225    @Override
21226    public void dumpHeapFinished(String path) {
21227        synchronized (this) {
21228            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21229                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21230                        + " does not match last pid " + mMemWatchDumpPid);
21231                return;
21232            }
21233            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21234                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21235                        + " does not match last path " + mMemWatchDumpFile);
21236                return;
21237            }
21238            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21239            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21240        }
21241    }
21242
21243    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21244    public void monitor() {
21245        synchronized (this) { }
21246    }
21247
21248    void onCoreSettingsChange(Bundle settings) {
21249        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21250            ProcessRecord processRecord = mLruProcesses.get(i);
21251            try {
21252                if (processRecord.thread != null) {
21253                    processRecord.thread.setCoreSettings(settings);
21254                }
21255            } catch (RemoteException re) {
21256                /* ignore */
21257            }
21258        }
21259    }
21260
21261    // Multi-user methods
21262
21263    /**
21264     * Start user, if its not already running, but don't bring it to foreground.
21265     */
21266    @Override
21267    public boolean startUserInBackground(final int userId) {
21268        return mUserController.startUser(userId, /* foreground */ false);
21269    }
21270
21271    @Override
21272    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21273        return mUserController.unlockUser(userId, token, secret, listener);
21274    }
21275
21276    @Override
21277    public boolean switchUser(final int targetUserId) {
21278        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21279        UserInfo currentUserInfo;
21280        UserInfo targetUserInfo;
21281        synchronized (this) {
21282            int currentUserId = mUserController.getCurrentUserIdLocked();
21283            currentUserInfo = mUserController.getUserInfo(currentUserId);
21284            targetUserInfo = mUserController.getUserInfo(targetUserId);
21285            if (targetUserInfo == null) {
21286                Slog.w(TAG, "No user info for user #" + targetUserId);
21287                return false;
21288            }
21289            if (!targetUserInfo.supportsSwitchTo()) {
21290                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21291                return false;
21292            }
21293            if (targetUserInfo.isManagedProfile()) {
21294                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21295                return false;
21296            }
21297            mUserController.setTargetUserIdLocked(targetUserId);
21298        }
21299        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21300        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21301        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21302        return true;
21303    }
21304
21305    void scheduleStartProfilesLocked() {
21306        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21307            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21308                    DateUtils.SECOND_IN_MILLIS);
21309        }
21310    }
21311
21312    @Override
21313    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21314        return mUserController.stopUser(userId, force, callback);
21315    }
21316
21317    @Override
21318    public UserInfo getCurrentUser() {
21319        return mUserController.getCurrentUser();
21320    }
21321
21322    @Override
21323    public boolean isUserRunning(int userId, int flags) {
21324        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21325                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21326            String msg = "Permission Denial: isUserRunning() from pid="
21327                    + Binder.getCallingPid()
21328                    + ", uid=" + Binder.getCallingUid()
21329                    + " requires " + INTERACT_ACROSS_USERS;
21330            Slog.w(TAG, msg);
21331            throw new SecurityException(msg);
21332        }
21333        synchronized (this) {
21334            return mUserController.isUserRunningLocked(userId, flags);
21335        }
21336    }
21337
21338    @Override
21339    public int[] getRunningUserIds() {
21340        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21341                != PackageManager.PERMISSION_GRANTED) {
21342            String msg = "Permission Denial: isUserRunning() from pid="
21343                    + Binder.getCallingPid()
21344                    + ", uid=" + Binder.getCallingUid()
21345                    + " requires " + INTERACT_ACROSS_USERS;
21346            Slog.w(TAG, msg);
21347            throw new SecurityException(msg);
21348        }
21349        synchronized (this) {
21350            return mUserController.getStartedUserArrayLocked();
21351        }
21352    }
21353
21354    @Override
21355    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21356        mUserController.registerUserSwitchObserver(observer);
21357    }
21358
21359    @Override
21360    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21361        mUserController.unregisterUserSwitchObserver(observer);
21362    }
21363
21364    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21365        if (info == null) return null;
21366        ApplicationInfo newInfo = new ApplicationInfo(info);
21367        newInfo.initForUser(userId);
21368        return newInfo;
21369    }
21370
21371    public boolean isUserStopped(int userId) {
21372        synchronized (this) {
21373            return mUserController.getStartedUserStateLocked(userId) == null;
21374        }
21375    }
21376
21377    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21378        if (aInfo == null
21379                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21380            return aInfo;
21381        }
21382
21383        ActivityInfo info = new ActivityInfo(aInfo);
21384        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21385        return info;
21386    }
21387
21388    private boolean processSanityChecksLocked(ProcessRecord process) {
21389        if (process == null || process.thread == null) {
21390            return false;
21391        }
21392
21393        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21394        if (!isDebuggable) {
21395            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21396                return false;
21397            }
21398        }
21399
21400        return true;
21401    }
21402
21403    public boolean startBinderTracking() throws RemoteException {
21404        synchronized (this) {
21405            mBinderTransactionTrackingEnabled = true;
21406            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21407            // permission (same as profileControl).
21408            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21409                    != PackageManager.PERMISSION_GRANTED) {
21410                throw new SecurityException("Requires permission "
21411                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21412            }
21413
21414            for (int i = 0; i < mLruProcesses.size(); i++) {
21415                ProcessRecord process = mLruProcesses.get(i);
21416                if (!processSanityChecksLocked(process)) {
21417                    continue;
21418                }
21419                try {
21420                    process.thread.startBinderTracking();
21421                } catch (RemoteException e) {
21422                    Log.v(TAG, "Process disappared");
21423                }
21424            }
21425            return true;
21426        }
21427    }
21428
21429    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21430        try {
21431            synchronized (this) {
21432                mBinderTransactionTrackingEnabled = false;
21433                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21434                // permission (same as profileControl).
21435                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21436                        != PackageManager.PERMISSION_GRANTED) {
21437                    throw new SecurityException("Requires permission "
21438                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21439                }
21440
21441                if (fd == null) {
21442                    throw new IllegalArgumentException("null fd");
21443                }
21444
21445                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21446                pw.println("Binder transaction traces for all processes.\n");
21447                for (ProcessRecord process : mLruProcesses) {
21448                    if (!processSanityChecksLocked(process)) {
21449                        continue;
21450                    }
21451
21452                    pw.println("Traces for process: " + process.processName);
21453                    pw.flush();
21454                    try {
21455                        TransferPipe tp = new TransferPipe();
21456                        try {
21457                            process.thread.stopBinderTrackingAndDump(
21458                                    tp.getWriteFd().getFileDescriptor());
21459                            tp.go(fd.getFileDescriptor());
21460                        } finally {
21461                            tp.kill();
21462                        }
21463                    } catch (IOException e) {
21464                        pw.println("Failure while dumping IPC traces from " + process +
21465                                ".  Exception: " + e);
21466                        pw.flush();
21467                    } catch (RemoteException e) {
21468                        pw.println("Got a RemoteException while dumping IPC traces from " +
21469                                process + ".  Exception: " + e);
21470                        pw.flush();
21471                    }
21472                }
21473                fd = null;
21474                return true;
21475            }
21476        } finally {
21477            if (fd != null) {
21478                try {
21479                    fd.close();
21480                } catch (IOException e) {
21481                }
21482            }
21483        }
21484    }
21485
21486    private final class LocalService extends ActivityManagerInternal {
21487        @Override
21488        public void onWakefulnessChanged(int wakefulness) {
21489            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21490        }
21491
21492        @Override
21493        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21494                String processName, String abiOverride, int uid, Runnable crashHandler) {
21495            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21496                    processName, abiOverride, uid, crashHandler);
21497        }
21498
21499        @Override
21500        public SleepToken acquireSleepToken(String tag) {
21501            Preconditions.checkNotNull(tag);
21502
21503            ComponentName requestedVrService = null;
21504            ComponentName callingVrActivity = null;
21505            int userId = -1;
21506            synchronized (ActivityManagerService.this) {
21507                if (mFocusedActivity != null) {
21508                    requestedVrService = mFocusedActivity.requestedVrComponent;
21509                    callingVrActivity = mFocusedActivity.info.getComponentName();
21510                    userId = mFocusedActivity.userId;
21511                }
21512            }
21513
21514            if (requestedVrService != null) {
21515                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21516            }
21517
21518            synchronized (ActivityManagerService.this) {
21519                SleepTokenImpl token = new SleepTokenImpl(tag);
21520                mSleepTokens.add(token);
21521                updateSleepIfNeededLocked();
21522                return token;
21523            }
21524        }
21525
21526        @Override
21527        public ComponentName getHomeActivityForUser(int userId) {
21528            synchronized (ActivityManagerService.this) {
21529                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21530                return homeActivity == null ? null : homeActivity.realActivity;
21531            }
21532        }
21533
21534        @Override
21535        public void onUserRemoved(int userId) {
21536            synchronized (ActivityManagerService.this) {
21537                ActivityManagerService.this.onUserStoppedLocked(userId);
21538            }
21539        }
21540
21541        @Override
21542        public void onLocalVoiceInteractionStarted(IBinder activity,
21543                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21544            synchronized (ActivityManagerService.this) {
21545                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21546                        voiceSession, voiceInteractor);
21547            }
21548        }
21549
21550        @Override
21551        public void notifyStartingWindowDrawn() {
21552            synchronized (ActivityManagerService.this) {
21553                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21554            }
21555        }
21556
21557        @Override
21558        public void notifyAppTransitionStarting(int reason) {
21559            synchronized (ActivityManagerService.this) {
21560                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21561            }
21562        }
21563
21564        @Override
21565        public void notifyAppTransitionFinished() {
21566            synchronized (ActivityManagerService.this) {
21567                mStackSupervisor.notifyAppTransitionDone();
21568            }
21569        }
21570
21571        @Override
21572        public void notifyAppTransitionCancelled() {
21573            synchronized (ActivityManagerService.this) {
21574                mStackSupervisor.notifyAppTransitionDone();
21575            }
21576        }
21577
21578        @Override
21579        public List<IBinder> getTopVisibleActivities() {
21580            synchronized (ActivityManagerService.this) {
21581                return mStackSupervisor.getTopVisibleActivities();
21582            }
21583        }
21584
21585        @Override
21586        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21587            synchronized (ActivityManagerService.this) {
21588                mStackSupervisor.setDockedStackMinimized(minimized);
21589            }
21590        }
21591
21592        @Override
21593        public void killForegroundAppsForUser(int userHandle) {
21594            synchronized (ActivityManagerService.this) {
21595                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21596                final int NP = mProcessNames.getMap().size();
21597                for (int ip = 0; ip < NP; ip++) {
21598                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21599                    final int NA = apps.size();
21600                    for (int ia = 0; ia < NA; ia++) {
21601                        final ProcessRecord app = apps.valueAt(ia);
21602                        if (app.persistent) {
21603                            // We don't kill persistent processes.
21604                            continue;
21605                        }
21606                        if (app.removed) {
21607                            procs.add(app);
21608                        } else if (app.userId == userHandle && app.foregroundActivities) {
21609                            app.removed = true;
21610                            procs.add(app);
21611                        }
21612                    }
21613                }
21614
21615                final int N = procs.size();
21616                for (int i = 0; i < N; i++) {
21617                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21618                }
21619            }
21620        }
21621
21622        @Override
21623        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21624            if (!(target instanceof PendingIntentRecord)) {
21625                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21626                return;
21627            }
21628            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21629        }
21630    }
21631
21632    private final class SleepTokenImpl extends SleepToken {
21633        private final String mTag;
21634        private final long mAcquireTime;
21635
21636        public SleepTokenImpl(String tag) {
21637            mTag = tag;
21638            mAcquireTime = SystemClock.uptimeMillis();
21639        }
21640
21641        @Override
21642        public void release() {
21643            synchronized (ActivityManagerService.this) {
21644                if (mSleepTokens.remove(this)) {
21645                    updateSleepIfNeededLocked();
21646                }
21647            }
21648        }
21649
21650        @Override
21651        public String toString() {
21652            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21653        }
21654    }
21655
21656    /**
21657     * An implementation of IAppTask, that allows an app to manage its own tasks via
21658     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21659     * only the process that calls getAppTasks() can call the AppTask methods.
21660     */
21661    class AppTaskImpl extends IAppTask.Stub {
21662        private int mTaskId;
21663        private int mCallingUid;
21664
21665        public AppTaskImpl(int taskId, int callingUid) {
21666            mTaskId = taskId;
21667            mCallingUid = callingUid;
21668        }
21669
21670        private void checkCaller() {
21671            if (mCallingUid != Binder.getCallingUid()) {
21672                throw new SecurityException("Caller " + mCallingUid
21673                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21674            }
21675        }
21676
21677        @Override
21678        public void finishAndRemoveTask() {
21679            checkCaller();
21680
21681            synchronized (ActivityManagerService.this) {
21682                long origId = Binder.clearCallingIdentity();
21683                try {
21684                    // We remove the task from recents to preserve backwards
21685                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21686                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21687                    }
21688                } finally {
21689                    Binder.restoreCallingIdentity(origId);
21690                }
21691            }
21692        }
21693
21694        @Override
21695        public ActivityManager.RecentTaskInfo getTaskInfo() {
21696            checkCaller();
21697
21698            synchronized (ActivityManagerService.this) {
21699                long origId = Binder.clearCallingIdentity();
21700                try {
21701                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21702                    if (tr == null) {
21703                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21704                    }
21705                    return createRecentTaskInfoFromTaskRecord(tr);
21706                } finally {
21707                    Binder.restoreCallingIdentity(origId);
21708                }
21709            }
21710        }
21711
21712        @Override
21713        public void moveToFront() {
21714            checkCaller();
21715            // Will bring task to front if it already has a root activity.
21716            final long origId = Binder.clearCallingIdentity();
21717            try {
21718                synchronized (this) {
21719                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21720                }
21721            } finally {
21722                Binder.restoreCallingIdentity(origId);
21723            }
21724        }
21725
21726        @Override
21727        public int startActivity(IBinder whoThread, String callingPackage,
21728                Intent intent, String resolvedType, Bundle bOptions) {
21729            checkCaller();
21730
21731            int callingUser = UserHandle.getCallingUserId();
21732            TaskRecord tr;
21733            IApplicationThread appThread;
21734            synchronized (ActivityManagerService.this) {
21735                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21736                if (tr == null) {
21737                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21738                }
21739                appThread = ApplicationThreadNative.asInterface(whoThread);
21740                if (appThread == null) {
21741                    throw new IllegalArgumentException("Bad app thread " + appThread);
21742                }
21743            }
21744            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21745                    resolvedType, null, null, null, null, 0, 0, null, null,
21746                    null, bOptions, false, callingUser, null, tr);
21747        }
21748
21749        @Override
21750        public void setExcludeFromRecents(boolean exclude) {
21751            checkCaller();
21752
21753            synchronized (ActivityManagerService.this) {
21754                long origId = Binder.clearCallingIdentity();
21755                try {
21756                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21757                    if (tr == null) {
21758                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21759                    }
21760                    Intent intent = tr.getBaseIntent();
21761                    if (exclude) {
21762                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21763                    } else {
21764                        intent.setFlags(intent.getFlags()
21765                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21766                    }
21767                } finally {
21768                    Binder.restoreCallingIdentity(origId);
21769                }
21770            }
21771        }
21772    }
21773
21774    /**
21775     * Kill processes for the user with id userId and that depend on the package named packageName
21776     */
21777    @Override
21778    public void killPackageDependents(String packageName, int userId) {
21779        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21780        if (packageName == null) {
21781            throw new NullPointerException(
21782                    "Cannot kill the dependents of a package without its name.");
21783        }
21784
21785        long callingId = Binder.clearCallingIdentity();
21786        IPackageManager pm = AppGlobals.getPackageManager();
21787        int pkgUid = -1;
21788        try {
21789            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21790        } catch (RemoteException e) {
21791        }
21792        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21793            throw new IllegalArgumentException(
21794                    "Cannot kill dependents of non-existing package " + packageName);
21795        }
21796        try {
21797            synchronized(this) {
21798                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21799                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21800                        "dep: " + packageName);
21801            }
21802        } finally {
21803            Binder.restoreCallingIdentity(callingId);
21804        }
21805    }
21806}
21807