ActivityManagerService.java revision 60920d5aa11bbb0e82a7f101cee825586e87aff0
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                    // Lie; we don't want to crash the app.
17921                    return ActivityManager.BROADCAST_SUCCESS;
17922            }
17923        }
17924
17925        // Add to the sticky list if requested.
17926        if (sticky) {
17927            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17928                    callingPid, callingUid)
17929                    != PackageManager.PERMISSION_GRANTED) {
17930                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17931                        + callingPid + ", uid=" + callingUid
17932                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17933                Slog.w(TAG, msg);
17934                throw new SecurityException(msg);
17935            }
17936            if (requiredPermissions != null && requiredPermissions.length > 0) {
17937                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17938                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17939                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17940            }
17941            if (intent.getComponent() != null) {
17942                throw new SecurityException(
17943                        "Sticky broadcasts can't target a specific component");
17944            }
17945            // We use userId directly here, since the "all" target is maintained
17946            // as a separate set of sticky broadcasts.
17947            if (userId != UserHandle.USER_ALL) {
17948                // But first, if this is not a broadcast to all users, then
17949                // make sure it doesn't conflict with an existing broadcast to
17950                // all users.
17951                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17952                        UserHandle.USER_ALL);
17953                if (stickies != null) {
17954                    ArrayList<Intent> list = stickies.get(intent.getAction());
17955                    if (list != null) {
17956                        int N = list.size();
17957                        int i;
17958                        for (i=0; i<N; i++) {
17959                            if (intent.filterEquals(list.get(i))) {
17960                                throw new IllegalArgumentException(
17961                                        "Sticky broadcast " + intent + " for user "
17962                                        + userId + " conflicts with existing global broadcast");
17963                            }
17964                        }
17965                    }
17966                }
17967            }
17968            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17969            if (stickies == null) {
17970                stickies = new ArrayMap<>();
17971                mStickyBroadcasts.put(userId, stickies);
17972            }
17973            ArrayList<Intent> list = stickies.get(intent.getAction());
17974            if (list == null) {
17975                list = new ArrayList<>();
17976                stickies.put(intent.getAction(), list);
17977            }
17978            final int stickiesCount = list.size();
17979            int i;
17980            for (i = 0; i < stickiesCount; i++) {
17981                if (intent.filterEquals(list.get(i))) {
17982                    // This sticky already exists, replace it.
17983                    list.set(i, new Intent(intent));
17984                    break;
17985                }
17986            }
17987            if (i >= stickiesCount) {
17988                list.add(new Intent(intent));
17989            }
17990        }
17991
17992        int[] users;
17993        if (userId == UserHandle.USER_ALL) {
17994            // Caller wants broadcast to go to all started users.
17995            users = mUserController.getStartedUserArrayLocked();
17996        } else {
17997            // Caller wants broadcast to go to one specific user.
17998            users = new int[] {userId};
17999        }
18000
18001        // Figure out who all will receive this broadcast.
18002        List receivers = null;
18003        List<BroadcastFilter> registeredReceivers = null;
18004        // Need to resolve the intent to interested receivers...
18005        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18006                 == 0) {
18007            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18008        }
18009        if (intent.getComponent() == null) {
18010            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18011                // Query one target user at a time, excluding shell-restricted users
18012                for (int i = 0; i < users.length; i++) {
18013                    if (mUserController.hasUserRestriction(
18014                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18015                        continue;
18016                    }
18017                    List<BroadcastFilter> registeredReceiversForUser =
18018                            mReceiverResolver.queryIntent(intent,
18019                                    resolvedType, false, users[i]);
18020                    if (registeredReceivers == null) {
18021                        registeredReceivers = registeredReceiversForUser;
18022                    } else if (registeredReceiversForUser != null) {
18023                        registeredReceivers.addAll(registeredReceiversForUser);
18024                    }
18025                }
18026            } else {
18027                registeredReceivers = mReceiverResolver.queryIntent(intent,
18028                        resolvedType, false, userId);
18029            }
18030        }
18031
18032        final boolean replacePending =
18033                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18034
18035        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18036                + " replacePending=" + replacePending);
18037
18038        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18039        if (!ordered && NR > 0) {
18040            // If we are not serializing this broadcast, then send the
18041            // registered receivers separately so they don't wait for the
18042            // components to be launched.
18043            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18044            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18045                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18046                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18047                    resultExtras, ordered, sticky, false, userId);
18048            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18049            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18050            if (!replaced) {
18051                queue.enqueueParallelBroadcastLocked(r);
18052                queue.scheduleBroadcastsLocked();
18053            }
18054            registeredReceivers = null;
18055            NR = 0;
18056        }
18057
18058        // Merge into one list.
18059        int ir = 0;
18060        if (receivers != null) {
18061            // A special case for PACKAGE_ADDED: do not allow the package
18062            // being added to see this broadcast.  This prevents them from
18063            // using this as a back door to get run as soon as they are
18064            // installed.  Maybe in the future we want to have a special install
18065            // broadcast or such for apps, but we'd like to deliberately make
18066            // this decision.
18067            String skipPackages[] = null;
18068            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18069                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18070                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18071                Uri data = intent.getData();
18072                if (data != null) {
18073                    String pkgName = data.getSchemeSpecificPart();
18074                    if (pkgName != null) {
18075                        skipPackages = new String[] { pkgName };
18076                    }
18077                }
18078            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18079                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18080            }
18081            if (skipPackages != null && (skipPackages.length > 0)) {
18082                for (String skipPackage : skipPackages) {
18083                    if (skipPackage != null) {
18084                        int NT = receivers.size();
18085                        for (int it=0; it<NT; it++) {
18086                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18087                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18088                                receivers.remove(it);
18089                                it--;
18090                                NT--;
18091                            }
18092                        }
18093                    }
18094                }
18095            }
18096
18097            int NT = receivers != null ? receivers.size() : 0;
18098            int it = 0;
18099            ResolveInfo curt = null;
18100            BroadcastFilter curr = null;
18101            while (it < NT && ir < NR) {
18102                if (curt == null) {
18103                    curt = (ResolveInfo)receivers.get(it);
18104                }
18105                if (curr == null) {
18106                    curr = registeredReceivers.get(ir);
18107                }
18108                if (curr.getPriority() >= curt.priority) {
18109                    // Insert this broadcast record into the final list.
18110                    receivers.add(it, curr);
18111                    ir++;
18112                    curr = null;
18113                    it++;
18114                    NT++;
18115                } else {
18116                    // Skip to the next ResolveInfo in the final list.
18117                    it++;
18118                    curt = null;
18119                }
18120            }
18121        }
18122        while (ir < NR) {
18123            if (receivers == null) {
18124                receivers = new ArrayList();
18125            }
18126            receivers.add(registeredReceivers.get(ir));
18127            ir++;
18128        }
18129
18130        if ((receivers != null && receivers.size() > 0)
18131                || resultTo != null) {
18132            BroadcastQueue queue = broadcastQueueForIntent(intent);
18133            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18134                    callerPackage, callingPid, callingUid, resolvedType,
18135                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18136                    resultData, resultExtras, ordered, sticky, false, userId);
18137
18138            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18139                    + ": prev had " + queue.mOrderedBroadcasts.size());
18140            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18141                    "Enqueueing broadcast " + r.intent.getAction());
18142
18143            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18144            if (!replaced) {
18145                queue.enqueueOrderedBroadcastLocked(r);
18146                queue.scheduleBroadcastsLocked();
18147            }
18148        } else {
18149            // There was nobody interested in the broadcast, but we still want to record
18150            // that it happened.
18151            if (intent.getComponent() == null && intent.getPackage() == null
18152                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18153                // This was an implicit broadcast... let's record it for posterity.
18154                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18155            }
18156        }
18157
18158        return ActivityManager.BROADCAST_SUCCESS;
18159    }
18160
18161    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18162            int skipCount, long dispatchTime) {
18163        final long now = SystemClock.elapsedRealtime();
18164        if (mCurBroadcastStats == null ||
18165                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18166            mLastBroadcastStats = mCurBroadcastStats;
18167            if (mLastBroadcastStats != null) {
18168                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18169                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18170            }
18171            mCurBroadcastStats = new BroadcastStats();
18172        }
18173        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18174    }
18175
18176    final Intent verifyBroadcastLocked(Intent intent) {
18177        // Refuse possible leaked file descriptors
18178        if (intent != null && intent.hasFileDescriptors() == true) {
18179            throw new IllegalArgumentException("File descriptors passed in Intent");
18180        }
18181
18182        int flags = intent.getFlags();
18183
18184        if (!mProcessesReady) {
18185            // if the caller really truly claims to know what they're doing, go
18186            // ahead and allow the broadcast without launching any receivers
18187            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18188                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18189            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18190                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18191                        + " before boot completion");
18192                throw new IllegalStateException("Cannot broadcast before boot completed");
18193            }
18194        }
18195
18196        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18197            throw new IllegalArgumentException(
18198                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18199        }
18200
18201        return intent;
18202    }
18203
18204    public final int broadcastIntent(IApplicationThread caller,
18205            Intent intent, String resolvedType, IIntentReceiver resultTo,
18206            int resultCode, String resultData, Bundle resultExtras,
18207            String[] requiredPermissions, int appOp, Bundle bOptions,
18208            boolean serialized, boolean sticky, int userId) {
18209        enforceNotIsolatedCaller("broadcastIntent");
18210        synchronized(this) {
18211            intent = verifyBroadcastLocked(intent);
18212
18213            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18214            final int callingPid = Binder.getCallingPid();
18215            final int callingUid = Binder.getCallingUid();
18216            final long origId = Binder.clearCallingIdentity();
18217            int res = broadcastIntentLocked(callerApp,
18218                    callerApp != null ? callerApp.info.packageName : null,
18219                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18220                    requiredPermissions, appOp, bOptions, serialized, sticky,
18221                    callingPid, callingUid, userId);
18222            Binder.restoreCallingIdentity(origId);
18223            return res;
18224        }
18225    }
18226
18227
18228    int broadcastIntentInPackage(String packageName, int uid,
18229            Intent intent, String resolvedType, IIntentReceiver resultTo,
18230            int resultCode, String resultData, Bundle resultExtras,
18231            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18232            int userId) {
18233        synchronized(this) {
18234            intent = verifyBroadcastLocked(intent);
18235
18236            final long origId = Binder.clearCallingIdentity();
18237            String[] requiredPermissions = requiredPermission == null ? null
18238                    : new String[] {requiredPermission};
18239            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18240                    resultTo, resultCode, resultData, resultExtras,
18241                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18242                    sticky, -1, uid, userId);
18243            Binder.restoreCallingIdentity(origId);
18244            return res;
18245        }
18246    }
18247
18248    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18249        // Refuse possible leaked file descriptors
18250        if (intent != null && intent.hasFileDescriptors() == true) {
18251            throw new IllegalArgumentException("File descriptors passed in Intent");
18252        }
18253
18254        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18255                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18256
18257        synchronized(this) {
18258            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18259                    != PackageManager.PERMISSION_GRANTED) {
18260                String msg = "Permission Denial: unbroadcastIntent() from pid="
18261                        + Binder.getCallingPid()
18262                        + ", uid=" + Binder.getCallingUid()
18263                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18264                Slog.w(TAG, msg);
18265                throw new SecurityException(msg);
18266            }
18267            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18268            if (stickies != null) {
18269                ArrayList<Intent> list = stickies.get(intent.getAction());
18270                if (list != null) {
18271                    int N = list.size();
18272                    int i;
18273                    for (i=0; i<N; i++) {
18274                        if (intent.filterEquals(list.get(i))) {
18275                            list.remove(i);
18276                            break;
18277                        }
18278                    }
18279                    if (list.size() <= 0) {
18280                        stickies.remove(intent.getAction());
18281                    }
18282                }
18283                if (stickies.size() <= 0) {
18284                    mStickyBroadcasts.remove(userId);
18285                }
18286            }
18287        }
18288    }
18289
18290    void backgroundServicesFinishedLocked(int userId) {
18291        for (BroadcastQueue queue : mBroadcastQueues) {
18292            queue.backgroundServicesFinishedLocked(userId);
18293        }
18294    }
18295
18296    public void finishReceiver(IBinder who, int resultCode, String resultData,
18297            Bundle resultExtras, boolean resultAbort, int flags) {
18298        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18299
18300        // Refuse possible leaked file descriptors
18301        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18302            throw new IllegalArgumentException("File descriptors passed in Bundle");
18303        }
18304
18305        final long origId = Binder.clearCallingIdentity();
18306        try {
18307            boolean doNext = false;
18308            BroadcastRecord r;
18309
18310            synchronized(this) {
18311                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18312                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18313                r = queue.getMatchingOrderedReceiver(who);
18314                if (r != null) {
18315                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18316                        resultData, resultExtras, resultAbort, true);
18317                }
18318            }
18319
18320            if (doNext) {
18321                r.queue.processNextBroadcast(false);
18322            }
18323            trimApplications();
18324        } finally {
18325            Binder.restoreCallingIdentity(origId);
18326        }
18327    }
18328
18329    // =========================================================
18330    // INSTRUMENTATION
18331    // =========================================================
18332
18333    public boolean startInstrumentation(ComponentName className,
18334            String profileFile, int flags, Bundle arguments,
18335            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18336            int userId, String abiOverride) {
18337        enforceNotIsolatedCaller("startInstrumentation");
18338        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18339                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18340        // Refuse possible leaked file descriptors
18341        if (arguments != null && arguments.hasFileDescriptors()) {
18342            throw new IllegalArgumentException("File descriptors passed in Bundle");
18343        }
18344
18345        synchronized(this) {
18346            InstrumentationInfo ii = null;
18347            ApplicationInfo ai = null;
18348            try {
18349                ii = mContext.getPackageManager().getInstrumentationInfo(
18350                    className, STOCK_PM_FLAGS);
18351                ai = AppGlobals.getPackageManager().getApplicationInfo(
18352                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18353            } catch (PackageManager.NameNotFoundException e) {
18354            } catch (RemoteException e) {
18355            }
18356            if (ii == null) {
18357                reportStartInstrumentationFailureLocked(watcher, className,
18358                        "Unable to find instrumentation info for: " + className);
18359                return false;
18360            }
18361            if (ai == null) {
18362                reportStartInstrumentationFailureLocked(watcher, className,
18363                        "Unable to find instrumentation target package: " + ii.targetPackage);
18364                return false;
18365            }
18366            if (!ai.hasCode()) {
18367                reportStartInstrumentationFailureLocked(watcher, className,
18368                        "Instrumentation target has no code: " + ii.targetPackage);
18369                return false;
18370            }
18371
18372            int match = mContext.getPackageManager().checkSignatures(
18373                    ii.targetPackage, ii.packageName);
18374            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18375                String msg = "Permission Denial: starting instrumentation "
18376                        + className + " from pid="
18377                        + Binder.getCallingPid()
18378                        + ", uid=" + Binder.getCallingPid()
18379                        + " not allowed because package " + ii.packageName
18380                        + " does not have a signature matching the target "
18381                        + ii.targetPackage;
18382                reportStartInstrumentationFailureLocked(watcher, className, msg);
18383                throw new SecurityException(msg);
18384            }
18385
18386            final long origId = Binder.clearCallingIdentity();
18387            // Instrumentation can kill and relaunch even persistent processes
18388            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18389                    "start instr");
18390            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18391            app.instrumentationClass = className;
18392            app.instrumentationInfo = ai;
18393            app.instrumentationProfileFile = profileFile;
18394            app.instrumentationArguments = arguments;
18395            app.instrumentationWatcher = watcher;
18396            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18397            app.instrumentationResultClass = className;
18398            Binder.restoreCallingIdentity(origId);
18399        }
18400
18401        return true;
18402    }
18403
18404    /**
18405     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18406     * error to the logs, but if somebody is watching, send the report there too.  This enables
18407     * the "am" command to report errors with more information.
18408     *
18409     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18410     * @param cn The component name of the instrumentation.
18411     * @param report The error report.
18412     */
18413    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18414            ComponentName cn, String report) {
18415        Slog.w(TAG, report);
18416        if (watcher != null) {
18417            Bundle results = new Bundle();
18418            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18419            results.putString("Error", report);
18420            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18421        }
18422    }
18423
18424    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18425        if (app.instrumentationWatcher != null) {
18426            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18427                    app.instrumentationClass, resultCode, results);
18428        }
18429
18430        // Can't call out of the system process with a lock held, so post a message.
18431        if (app.instrumentationUiAutomationConnection != null) {
18432            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18433                    app.instrumentationUiAutomationConnection).sendToTarget();
18434        }
18435
18436        app.instrumentationWatcher = null;
18437        app.instrumentationUiAutomationConnection = null;
18438        app.instrumentationClass = null;
18439        app.instrumentationInfo = null;
18440        app.instrumentationProfileFile = null;
18441        app.instrumentationArguments = null;
18442
18443        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18444                "finished inst");
18445    }
18446
18447    public void finishInstrumentation(IApplicationThread target,
18448            int resultCode, Bundle results) {
18449        int userId = UserHandle.getCallingUserId();
18450        // Refuse possible leaked file descriptors
18451        if (results != null && results.hasFileDescriptors()) {
18452            throw new IllegalArgumentException("File descriptors passed in Intent");
18453        }
18454
18455        synchronized(this) {
18456            ProcessRecord app = getRecordForAppLocked(target);
18457            if (app == null) {
18458                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18459                return;
18460            }
18461            final long origId = Binder.clearCallingIdentity();
18462            finishInstrumentationLocked(app, resultCode, results);
18463            Binder.restoreCallingIdentity(origId);
18464        }
18465    }
18466
18467    // =========================================================
18468    // CONFIGURATION
18469    // =========================================================
18470
18471    public ConfigurationInfo getDeviceConfigurationInfo() {
18472        ConfigurationInfo config = new ConfigurationInfo();
18473        synchronized (this) {
18474            config.reqTouchScreen = mConfiguration.touchscreen;
18475            config.reqKeyboardType = mConfiguration.keyboard;
18476            config.reqNavigation = mConfiguration.navigation;
18477            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18478                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18479                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18480            }
18481            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18482                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18483                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18484            }
18485            config.reqGlEsVersion = GL_ES_VERSION;
18486        }
18487        return config;
18488    }
18489
18490    ActivityStack getFocusedStack() {
18491        return mStackSupervisor.getFocusedStack();
18492    }
18493
18494    @Override
18495    public int getFocusedStackId() throws RemoteException {
18496        ActivityStack focusedStack = getFocusedStack();
18497        if (focusedStack != null) {
18498            return focusedStack.getStackId();
18499        }
18500        return -1;
18501    }
18502
18503    public Configuration getConfiguration() {
18504        Configuration ci;
18505        synchronized(this) {
18506            ci = new Configuration(mConfiguration);
18507            ci.userSetLocale = false;
18508        }
18509        return ci;
18510    }
18511
18512    @Override
18513    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18514        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18515        synchronized (this) {
18516            mSuppressResizeConfigChanges = suppress;
18517        }
18518    }
18519
18520    @Override
18521    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18522        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18523        if (fromStackId == HOME_STACK_ID) {
18524            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18525        }
18526        synchronized (this) {
18527            final long origId = Binder.clearCallingIdentity();
18528            try {
18529                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18530            } finally {
18531                Binder.restoreCallingIdentity(origId);
18532            }
18533        }
18534    }
18535
18536    @Override
18537    public void updatePersistentConfiguration(Configuration values) {
18538        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18539                "updateConfiguration()");
18540        enforceWriteSettingsPermission("updateConfiguration()");
18541        if (values == null) {
18542            throw new NullPointerException("Configuration must not be null");
18543        }
18544
18545        int userId = UserHandle.getCallingUserId();
18546
18547        synchronized(this) {
18548            final long origId = Binder.clearCallingIdentity();
18549            updateConfigurationLocked(values, null, false, true, userId);
18550            Binder.restoreCallingIdentity(origId);
18551        }
18552    }
18553
18554    private void updateFontScaleIfNeeded() {
18555        final int currentUserId;
18556        synchronized(this) {
18557            currentUserId = mUserController.getCurrentUserIdLocked();
18558        }
18559        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18560                FONT_SCALE, 1.0f, currentUserId);
18561        if (mConfiguration.fontScale != scaleFactor) {
18562            final Configuration configuration = mWindowManager.computeNewConfiguration();
18563            configuration.fontScale = scaleFactor;
18564            updatePersistentConfiguration(configuration);
18565        }
18566    }
18567
18568    private void enforceWriteSettingsPermission(String func) {
18569        int uid = Binder.getCallingUid();
18570        if (uid == Process.ROOT_UID) {
18571            return;
18572        }
18573
18574        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18575                Settings.getPackageNameForUid(mContext, uid), false)) {
18576            return;
18577        }
18578
18579        String msg = "Permission Denial: " + func + " from pid="
18580                + Binder.getCallingPid()
18581                + ", uid=" + uid
18582                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18583        Slog.w(TAG, msg);
18584        throw new SecurityException(msg);
18585    }
18586
18587    public void updateConfiguration(Configuration values) {
18588        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18589                "updateConfiguration()");
18590
18591        synchronized(this) {
18592            if (values == null && mWindowManager != null) {
18593                // sentinel: fetch the current configuration from the window manager
18594                values = mWindowManager.computeNewConfiguration();
18595            }
18596
18597            if (mWindowManager != null) {
18598                mProcessList.applyDisplaySize(mWindowManager);
18599            }
18600
18601            final long origId = Binder.clearCallingIdentity();
18602            if (values != null) {
18603                Settings.System.clearConfiguration(values);
18604            }
18605            updateConfigurationLocked(values, null, false);
18606            Binder.restoreCallingIdentity(origId);
18607        }
18608    }
18609
18610    void updateUserConfigurationLocked() {
18611        Configuration configuration = new Configuration(mConfiguration);
18612        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18613                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18614        updateConfigurationLocked(configuration, null, false);
18615    }
18616
18617    boolean updateConfigurationLocked(Configuration values,
18618            ActivityRecord starting, boolean initLocale) {
18619        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18620        return updateConfigurationLocked(values, starting, initLocale, false,
18621                UserHandle.USER_NULL);
18622    }
18623
18624    // To cache the list of supported system locales
18625    private String[] mSupportedSystemLocales = null;
18626
18627    /**
18628     * Do either or both things: (1) change the current configuration, and (2)
18629     * make sure the given activity is running with the (now) current
18630     * configuration.  Returns true if the activity has been left running, or
18631     * false if <var>starting</var> is being destroyed to match the new
18632     * configuration.
18633     *
18634     * @param userId is only used when persistent parameter is set to true to persist configuration
18635     *               for that particular user
18636     */
18637    private boolean updateConfigurationLocked(Configuration values,
18638            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18639        int changes = 0;
18640
18641        if (mWindowManager != null) {
18642            mWindowManager.deferSurfaceLayout();
18643        }
18644        if (values != null) {
18645            Configuration newConfig = new Configuration(mConfiguration);
18646            changes = newConfig.updateFrom(values);
18647            if (changes != 0) {
18648                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18649                        "Updating configuration to: " + values);
18650
18651                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18652
18653                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18654                    final LocaleList locales = values.getLocales();
18655                    int bestLocaleIndex = 0;
18656                    if (locales.size() > 1) {
18657                        if (mSupportedSystemLocales == null) {
18658                            mSupportedSystemLocales =
18659                                    Resources.getSystem().getAssets().getLocales();
18660                        }
18661                        bestLocaleIndex = Math.max(0,
18662                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18663                    }
18664                    SystemProperties.set("persist.sys.locale",
18665                            locales.get(bestLocaleIndex).toLanguageTag());
18666                    LocaleList.setDefault(locales, bestLocaleIndex);
18667                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18668                            locales.get(bestLocaleIndex)));
18669                }
18670
18671                mConfigurationSeq++;
18672                if (mConfigurationSeq <= 0) {
18673                    mConfigurationSeq = 1;
18674                }
18675                newConfig.seq = mConfigurationSeq;
18676                mConfiguration = newConfig;
18677                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18678                mUsageStatsService.reportConfigurationChange(newConfig,
18679                        mUserController.getCurrentUserIdLocked());
18680                //mUsageStatsService.noteStartConfig(newConfig);
18681
18682                final Configuration configCopy = new Configuration(mConfiguration);
18683
18684                // TODO: If our config changes, should we auto dismiss any currently
18685                // showing dialogs?
18686                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18687
18688                AttributeCache ac = AttributeCache.instance();
18689                if (ac != null) {
18690                    ac.updateConfiguration(configCopy);
18691                }
18692
18693                // Make sure all resources in our process are updated
18694                // right now, so that anyone who is going to retrieve
18695                // resource values after we return will be sure to get
18696                // the new ones.  This is especially important during
18697                // boot, where the first config change needs to guarantee
18698                // all resources have that config before following boot
18699                // code is executed.
18700                mSystemThread.applyConfigurationToResources(configCopy);
18701
18702                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18703                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18704                    msg.obj = new Configuration(configCopy);
18705                    msg.arg1 = userId;
18706                    mHandler.sendMessage(msg);
18707                }
18708
18709                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18710                if (isDensityChange) {
18711                    // Reset the unsupported display size dialog.
18712                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18713
18714                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18715                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18716                }
18717
18718                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18719                    ProcessRecord app = mLruProcesses.get(i);
18720                    try {
18721                        if (app.thread != null) {
18722                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18723                                    + app.processName + " new config " + mConfiguration);
18724                            app.thread.scheduleConfigurationChanged(configCopy);
18725                        }
18726                    } catch (Exception e) {
18727                    }
18728                }
18729                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18730                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18731                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18732                        | Intent.FLAG_RECEIVER_FOREGROUND);
18733                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18734                        null, AppOpsManager.OP_NONE, null, false, false,
18735                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18736                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18737                    // Tell the shortcut manager that the system locale changed.  It needs to know
18738                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18739                    // we "push" from here, rather than having the service listen to the broadcast.
18740                    final ShortcutServiceInternal shortcutService =
18741                            LocalServices.getService(ShortcutServiceInternal.class);
18742                    if (shortcutService != null) {
18743                        shortcutService.onSystemLocaleChangedNoLock();
18744                    }
18745
18746                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18747                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18748                    if (!mProcessesReady) {
18749                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18750                    }
18751                    broadcastIntentLocked(null, null, intent,
18752                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18753                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18754                }
18755            }
18756            // Update the configuration with WM first and check if any of the stacks need to be
18757            // resized due to the configuration change. If so, resize the stacks now and do any
18758            // relaunches if necessary. This way we don't need to relaunch again below in
18759            // ensureActivityConfigurationLocked().
18760            if (mWindowManager != null) {
18761                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18762                if (resizedStacks != null) {
18763                    for (int stackId : resizedStacks) {
18764                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18765                        mStackSupervisor.resizeStackLocked(
18766                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18767                    }
18768                }
18769            }
18770        }
18771
18772        boolean kept = true;
18773        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18774        // mainStack is null during startup.
18775        if (mainStack != null) {
18776            if (changes != 0 && starting == null) {
18777                // If the configuration changed, and the caller is not already
18778                // in the process of starting an activity, then find the top
18779                // activity to check if its configuration needs to change.
18780                starting = mainStack.topRunningActivityLocked();
18781            }
18782
18783            if (starting != null) {
18784                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18785                // And we need to make sure at this point that all other activities
18786                // are made visible with the correct configuration.
18787                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18788                        !PRESERVE_WINDOWS);
18789            }
18790        }
18791        if (mWindowManager != null) {
18792            mWindowManager.continueSurfaceLayout();
18793        }
18794        return kept;
18795    }
18796
18797    /**
18798     * Decide based on the configuration whether we should shouw the ANR,
18799     * crash, etc dialogs.  The idea is that if there is no affordnace to
18800     * press the on-screen buttons, we shouldn't show the dialog.
18801     *
18802     * A thought: SystemUI might also want to get told about this, the Power
18803     * dialog / global actions also might want different behaviors.
18804     */
18805    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18806        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18807                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18808                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18809        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18810                                    == Configuration.UI_MODE_TYPE_CAR);
18811        return inputMethodExists && uiIsNotCarType && !inVrMode;
18812    }
18813
18814    @Override
18815    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18816        synchronized (this) {
18817            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18818            if (srec != null) {
18819                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18820            }
18821        }
18822        return false;
18823    }
18824
18825    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18826            Intent resultData) {
18827
18828        synchronized (this) {
18829            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18830            if (r != null) {
18831                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18832            }
18833            return false;
18834        }
18835    }
18836
18837    public int getLaunchedFromUid(IBinder activityToken) {
18838        ActivityRecord srec;
18839        synchronized (this) {
18840            srec = ActivityRecord.forTokenLocked(activityToken);
18841        }
18842        if (srec == null) {
18843            return -1;
18844        }
18845        return srec.launchedFromUid;
18846    }
18847
18848    public String getLaunchedFromPackage(IBinder activityToken) {
18849        ActivityRecord srec;
18850        synchronized (this) {
18851            srec = ActivityRecord.forTokenLocked(activityToken);
18852        }
18853        if (srec == null) {
18854            return null;
18855        }
18856        return srec.launchedFromPackage;
18857    }
18858
18859    // =========================================================
18860    // LIFETIME MANAGEMENT
18861    // =========================================================
18862
18863    // Returns which broadcast queue the app is the current [or imminent] receiver
18864    // on, or 'null' if the app is not an active broadcast recipient.
18865    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18866        BroadcastRecord r = app.curReceiver;
18867        if (r != null) {
18868            return r.queue;
18869        }
18870
18871        // It's not the current receiver, but it might be starting up to become one
18872        synchronized (this) {
18873            for (BroadcastQueue queue : mBroadcastQueues) {
18874                r = queue.mPendingBroadcast;
18875                if (r != null && r.curApp == app) {
18876                    // found it; report which queue it's in
18877                    return queue;
18878                }
18879            }
18880        }
18881
18882        return null;
18883    }
18884
18885    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18886            int targetUid, ComponentName targetComponent, String targetProcess) {
18887        if (!mTrackingAssociations) {
18888            return null;
18889        }
18890        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18891                = mAssociations.get(targetUid);
18892        if (components == null) {
18893            components = new ArrayMap<>();
18894            mAssociations.put(targetUid, components);
18895        }
18896        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18897        if (sourceUids == null) {
18898            sourceUids = new SparseArray<>();
18899            components.put(targetComponent, sourceUids);
18900        }
18901        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18902        if (sourceProcesses == null) {
18903            sourceProcesses = new ArrayMap<>();
18904            sourceUids.put(sourceUid, sourceProcesses);
18905        }
18906        Association ass = sourceProcesses.get(sourceProcess);
18907        if (ass == null) {
18908            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18909                    targetProcess);
18910            sourceProcesses.put(sourceProcess, ass);
18911        }
18912        ass.mCount++;
18913        ass.mNesting++;
18914        if (ass.mNesting == 1) {
18915            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18916            ass.mLastState = sourceState;
18917        }
18918        return ass;
18919    }
18920
18921    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18922            ComponentName targetComponent) {
18923        if (!mTrackingAssociations) {
18924            return;
18925        }
18926        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18927                = mAssociations.get(targetUid);
18928        if (components == null) {
18929            return;
18930        }
18931        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18932        if (sourceUids == null) {
18933            return;
18934        }
18935        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18936        if (sourceProcesses == null) {
18937            return;
18938        }
18939        Association ass = sourceProcesses.get(sourceProcess);
18940        if (ass == null || ass.mNesting <= 0) {
18941            return;
18942        }
18943        ass.mNesting--;
18944        if (ass.mNesting == 0) {
18945            long uptime = SystemClock.uptimeMillis();
18946            ass.mTime += uptime - ass.mStartTime;
18947            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18948                    += uptime - ass.mLastStateUptime;
18949            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18950        }
18951    }
18952
18953    private void noteUidProcessState(final int uid, final int state) {
18954        mBatteryStatsService.noteUidProcessState(uid, state);
18955        if (mTrackingAssociations) {
18956            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18957                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18958                        = mAssociations.valueAt(i1);
18959                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18960                    SparseArray<ArrayMap<String, Association>> sourceUids
18961                            = targetComponents.valueAt(i2);
18962                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18963                    if (sourceProcesses != null) {
18964                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18965                            Association ass = sourceProcesses.valueAt(i4);
18966                            if (ass.mNesting >= 1) {
18967                                // currently associated
18968                                long uptime = SystemClock.uptimeMillis();
18969                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18970                                        += uptime - ass.mLastStateUptime;
18971                                ass.mLastState = state;
18972                                ass.mLastStateUptime = uptime;
18973                            }
18974                        }
18975                    }
18976                }
18977            }
18978        }
18979    }
18980
18981    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18982            boolean doingAll, long now) {
18983        if (mAdjSeq == app.adjSeq) {
18984            // This adjustment has already been computed.
18985            return app.curRawAdj;
18986        }
18987
18988        if (app.thread == null) {
18989            app.adjSeq = mAdjSeq;
18990            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18991            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18992            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18993        }
18994
18995        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18996        app.adjSource = null;
18997        app.adjTarget = null;
18998        app.empty = false;
18999        app.cached = false;
19000
19001        final int activitiesSize = app.activities.size();
19002
19003        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19004            // The max adjustment doesn't allow this app to be anything
19005            // below foreground, so it is not worth doing work for it.
19006            app.adjType = "fixed";
19007            app.adjSeq = mAdjSeq;
19008            app.curRawAdj = app.maxAdj;
19009            app.foregroundActivities = false;
19010            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19011            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19012            // System processes can do UI, and when they do we want to have
19013            // them trim their memory after the user leaves the UI.  To
19014            // facilitate this, here we need to determine whether or not it
19015            // is currently showing UI.
19016            app.systemNoUi = true;
19017            if (app == TOP_APP) {
19018                app.systemNoUi = false;
19019                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19020                app.adjType = "pers-top-activity";
19021            } else if (activitiesSize > 0) {
19022                for (int j = 0; j < activitiesSize; j++) {
19023                    final ActivityRecord r = app.activities.get(j);
19024                    if (r.visible) {
19025                        app.systemNoUi = false;
19026                    }
19027                }
19028            }
19029            if (!app.systemNoUi) {
19030                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19031            }
19032            return (app.curAdj=app.maxAdj);
19033        }
19034
19035        app.systemNoUi = false;
19036
19037        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19038
19039        // Determine the importance of the process, starting with most
19040        // important to least, and assign an appropriate OOM adjustment.
19041        int adj;
19042        int schedGroup;
19043        int procState;
19044        boolean foregroundActivities = false;
19045        BroadcastQueue queue;
19046        if (app == TOP_APP) {
19047            // The last app on the list is the foreground app.
19048            adj = ProcessList.FOREGROUND_APP_ADJ;
19049            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19050            app.adjType = "top-activity";
19051            foregroundActivities = true;
19052            procState = PROCESS_STATE_CUR_TOP;
19053        } else if (app.instrumentationClass != null) {
19054            // Don't want to kill running instrumentation.
19055            adj = ProcessList.FOREGROUND_APP_ADJ;
19056            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19057            app.adjType = "instrumentation";
19058            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19059        } else if ((queue = isReceivingBroadcast(app)) != null) {
19060            // An app that is currently receiving a broadcast also
19061            // counts as being in the foreground for OOM killer purposes.
19062            // It's placed in a sched group based on the nature of the
19063            // broadcast as reflected by which queue it's active in.
19064            adj = ProcessList.FOREGROUND_APP_ADJ;
19065            schedGroup = (queue == mFgBroadcastQueue)
19066                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19067            app.adjType = "broadcast";
19068            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19069        } else if (app.executingServices.size() > 0) {
19070            // An app that is currently executing a service callback also
19071            // counts as being in the foreground.
19072            adj = ProcessList.FOREGROUND_APP_ADJ;
19073            schedGroup = app.execServicesFg ?
19074                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19075            app.adjType = "exec-service";
19076            procState = ActivityManager.PROCESS_STATE_SERVICE;
19077            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19078        } else {
19079            // As far as we know the process is empty.  We may change our mind later.
19080            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19081            // At this point we don't actually know the adjustment.  Use the cached adj
19082            // value that the caller wants us to.
19083            adj = cachedAdj;
19084            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19085            app.cached = true;
19086            app.empty = true;
19087            app.adjType = "cch-empty";
19088        }
19089
19090        // Examine all activities if not already foreground.
19091        if (!foregroundActivities && activitiesSize > 0) {
19092            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19093            for (int j = 0; j < activitiesSize; j++) {
19094                final ActivityRecord r = app.activities.get(j);
19095                if (r.app != app) {
19096                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19097                            + " instead of expected " + app);
19098                    if (r.app == null || (r.app.uid == app.uid)) {
19099                        // Only fix things up when they look sane
19100                        r.app = app;
19101                    } else {
19102                        continue;
19103                    }
19104                }
19105                if (r.visible) {
19106                    // App has a visible activity; only upgrade adjustment.
19107                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19108                        adj = ProcessList.VISIBLE_APP_ADJ;
19109                        app.adjType = "visible";
19110                    }
19111                    if (procState > PROCESS_STATE_CUR_TOP) {
19112                        procState = PROCESS_STATE_CUR_TOP;
19113                    }
19114                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19115                    app.cached = false;
19116                    app.empty = false;
19117                    foregroundActivities = true;
19118                    if (r.task != null && minLayer > 0) {
19119                        final int layer = r.task.mLayerRank;
19120                        if (layer >= 0 && minLayer > layer) {
19121                            minLayer = layer;
19122                        }
19123                    }
19124                    break;
19125                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19126                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19127                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19128                        app.adjType = "pausing";
19129                    }
19130                    if (procState > PROCESS_STATE_CUR_TOP) {
19131                        procState = PROCESS_STATE_CUR_TOP;
19132                    }
19133                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19134                    app.cached = false;
19135                    app.empty = false;
19136                    foregroundActivities = true;
19137                } else if (r.state == ActivityState.STOPPING) {
19138                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19139                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19140                        app.adjType = "stopping";
19141                    }
19142                    // For the process state, we will at this point consider the
19143                    // process to be cached.  It will be cached either as an activity
19144                    // or empty depending on whether the activity is finishing.  We do
19145                    // this so that we can treat the process as cached for purposes of
19146                    // memory trimming (determing current memory level, trim command to
19147                    // send to process) since there can be an arbitrary number of stopping
19148                    // processes and they should soon all go into the cached state.
19149                    if (!r.finishing) {
19150                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19151                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19152                        }
19153                    }
19154                    app.cached = false;
19155                    app.empty = false;
19156                    foregroundActivities = true;
19157                } else {
19158                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19159                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19160                        app.adjType = "cch-act";
19161                    }
19162                }
19163            }
19164            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19165                adj += minLayer;
19166            }
19167        }
19168
19169        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19170                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19171            if (app.foregroundServices) {
19172                // The user is aware of this app, so make it visible.
19173                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19174                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19175                app.cached = false;
19176                app.adjType = "fg-service";
19177                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19178            } else if (app.forcingToForeground != null) {
19179                // The user is aware of this app, so make it visible.
19180                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19181                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19182                app.cached = false;
19183                app.adjType = "force-fg";
19184                app.adjSource = app.forcingToForeground;
19185                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19186            }
19187        }
19188
19189        if (app == mHeavyWeightProcess) {
19190            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19191                // We don't want to kill the current heavy-weight process.
19192                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19193                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19194                app.cached = false;
19195                app.adjType = "heavy";
19196            }
19197            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19198                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19199            }
19200        }
19201
19202        if (app == mHomeProcess) {
19203            if (adj > ProcessList.HOME_APP_ADJ) {
19204                // This process is hosting what we currently consider to be the
19205                // home app, so we don't want to let it go into the background.
19206                adj = ProcessList.HOME_APP_ADJ;
19207                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19208                app.cached = false;
19209                app.adjType = "home";
19210            }
19211            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19212                procState = ActivityManager.PROCESS_STATE_HOME;
19213            }
19214        }
19215
19216        if (app == mPreviousProcess && app.activities.size() > 0) {
19217            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19218                // This was the previous process that showed UI to the user.
19219                // We want to try to keep it around more aggressively, to give
19220                // a good experience around switching between two apps.
19221                adj = ProcessList.PREVIOUS_APP_ADJ;
19222                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19223                app.cached = false;
19224                app.adjType = "previous";
19225            }
19226            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19227                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19228            }
19229        }
19230
19231        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19232                + " reason=" + app.adjType);
19233
19234        // By default, we use the computed adjustment.  It may be changed if
19235        // there are applications dependent on our services or providers, but
19236        // this gives us a baseline and makes sure we don't get into an
19237        // infinite recursion.
19238        app.adjSeq = mAdjSeq;
19239        app.curRawAdj = adj;
19240        app.hasStartedServices = false;
19241
19242        if (mBackupTarget != null && app == mBackupTarget.app) {
19243            // If possible we want to avoid killing apps while they're being backed up
19244            if (adj > ProcessList.BACKUP_APP_ADJ) {
19245                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19246                adj = ProcessList.BACKUP_APP_ADJ;
19247                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19248                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19249                }
19250                app.adjType = "backup";
19251                app.cached = false;
19252            }
19253            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19254                procState = ActivityManager.PROCESS_STATE_BACKUP;
19255            }
19256        }
19257
19258        boolean mayBeTop = false;
19259
19260        for (int is = app.services.size()-1;
19261                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19262                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19263                        || procState > ActivityManager.PROCESS_STATE_TOP);
19264                is--) {
19265            ServiceRecord s = app.services.valueAt(is);
19266            if (s.startRequested) {
19267                app.hasStartedServices = true;
19268                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19269                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19270                }
19271                if (app.hasShownUi && app != mHomeProcess) {
19272                    // If this process has shown some UI, let it immediately
19273                    // go to the LRU list because it may be pretty heavy with
19274                    // UI stuff.  We'll tag it with a label just to help
19275                    // debug and understand what is going on.
19276                    if (adj > ProcessList.SERVICE_ADJ) {
19277                        app.adjType = "cch-started-ui-services";
19278                    }
19279                } else {
19280                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19281                        // This service has seen some activity within
19282                        // recent memory, so we will keep its process ahead
19283                        // of the background processes.
19284                        if (adj > ProcessList.SERVICE_ADJ) {
19285                            adj = ProcessList.SERVICE_ADJ;
19286                            app.adjType = "started-services";
19287                            app.cached = false;
19288                        }
19289                    }
19290                    // If we have let the service slide into the background
19291                    // state, still have some text describing what it is doing
19292                    // even though the service no longer has an impact.
19293                    if (adj > ProcessList.SERVICE_ADJ) {
19294                        app.adjType = "cch-started-services";
19295                    }
19296                }
19297            }
19298
19299            app.whitelistManager = false;
19300
19301            for (int conni = s.connections.size()-1;
19302                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19303                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19304                            || procState > ActivityManager.PROCESS_STATE_TOP);
19305                    conni--) {
19306                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19307                for (int i = 0;
19308                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19309                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19310                                || procState > ActivityManager.PROCESS_STATE_TOP);
19311                        i++) {
19312                    // XXX should compute this based on the max of
19313                    // all connected clients.
19314                    ConnectionRecord cr = clist.get(i);
19315                    if (cr.binding.client == app) {
19316                        // Binding to ourself is not interesting.
19317                        continue;
19318                    }
19319                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19320                        app.whitelistManager = true;
19321                    }
19322
19323                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19324                        ProcessRecord client = cr.binding.client;
19325                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19326                                TOP_APP, doingAll, now);
19327                        int clientProcState = client.curProcState;
19328                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19329                            // If the other app is cached for any reason, for purposes here
19330                            // we are going to consider it empty.  The specific cached state
19331                            // doesn't propagate except under certain conditions.
19332                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19333                        }
19334                        String adjType = null;
19335                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19336                            // Not doing bind OOM management, so treat
19337                            // this guy more like a started service.
19338                            if (app.hasShownUi && app != mHomeProcess) {
19339                                // If this process has shown some UI, let it immediately
19340                                // go to the LRU list because it may be pretty heavy with
19341                                // UI stuff.  We'll tag it with a label just to help
19342                                // debug and understand what is going on.
19343                                if (adj > clientAdj) {
19344                                    adjType = "cch-bound-ui-services";
19345                                }
19346                                app.cached = false;
19347                                clientAdj = adj;
19348                                clientProcState = procState;
19349                            } else {
19350                                if (now >= (s.lastActivity
19351                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19352                                    // This service has not seen activity within
19353                                    // recent memory, so allow it to drop to the
19354                                    // LRU list if there is no other reason to keep
19355                                    // it around.  We'll also tag it with a label just
19356                                    // to help debug and undertand what is going on.
19357                                    if (adj > clientAdj) {
19358                                        adjType = "cch-bound-services";
19359                                    }
19360                                    clientAdj = adj;
19361                                }
19362                            }
19363                        }
19364                        if (adj > clientAdj) {
19365                            // If this process has recently shown UI, and
19366                            // the process that is binding to it is less
19367                            // important than being visible, then we don't
19368                            // care about the binding as much as we care
19369                            // about letting this process get into the LRU
19370                            // list to be killed and restarted if needed for
19371                            // memory.
19372                            if (app.hasShownUi && app != mHomeProcess
19373                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19374                                adjType = "cch-bound-ui-services";
19375                            } else {
19376                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19377                                        |Context.BIND_IMPORTANT)) != 0) {
19378                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19379                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19380                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19381                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19382                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19383                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19384                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19385                                    adj = clientAdj;
19386                                } else {
19387                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19388                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19389                                    }
19390                                }
19391                                if (!client.cached) {
19392                                    app.cached = false;
19393                                }
19394                                adjType = "service";
19395                            }
19396                        }
19397                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19398                            // This will treat important bound services identically to
19399                            // the top app, which may behave differently than generic
19400                            // foreground work.
19401                            if (client.curSchedGroup > schedGroup) {
19402                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19403                                    schedGroup = client.curSchedGroup;
19404                                } else {
19405                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19406                                }
19407                            }
19408                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19409                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19410                                    // Special handling of clients who are in the top state.
19411                                    // We *may* want to consider this process to be in the
19412                                    // top state as well, but only if there is not another
19413                                    // reason for it to be running.  Being on the top is a
19414                                    // special state, meaning you are specifically running
19415                                    // for the current top app.  If the process is already
19416                                    // running in the background for some other reason, it
19417                                    // is more important to continue considering it to be
19418                                    // in the background state.
19419                                    mayBeTop = true;
19420                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19421                                } else {
19422                                    // Special handling for above-top states (persistent
19423                                    // processes).  These should not bring the current process
19424                                    // into the top state, since they are not on top.  Instead
19425                                    // give them the best state after that.
19426                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19427                                        clientProcState =
19428                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19429                                    } else if (mWakefulness
19430                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19431                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19432                                                    != 0) {
19433                                        clientProcState =
19434                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19435                                    } else {
19436                                        clientProcState =
19437                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19438                                    }
19439                                }
19440                            }
19441                        } else {
19442                            if (clientProcState <
19443                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19444                                clientProcState =
19445                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19446                            }
19447                        }
19448                        if (procState > clientProcState) {
19449                            procState = clientProcState;
19450                        }
19451                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19452                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19453                            app.pendingUiClean = true;
19454                        }
19455                        if (adjType != null) {
19456                            app.adjType = adjType;
19457                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19458                                    .REASON_SERVICE_IN_USE;
19459                            app.adjSource = cr.binding.client;
19460                            app.adjSourceProcState = clientProcState;
19461                            app.adjTarget = s.name;
19462                        }
19463                    }
19464                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19465                        app.treatLikeActivity = true;
19466                    }
19467                    final ActivityRecord a = cr.activity;
19468                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19469                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19470                            (a.visible || a.state == ActivityState.RESUMED ||
19471                             a.state == ActivityState.PAUSING)) {
19472                            adj = ProcessList.FOREGROUND_APP_ADJ;
19473                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19474                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19475                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19476                                } else {
19477                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19478                                }
19479                            }
19480                            app.cached = false;
19481                            app.adjType = "service";
19482                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19483                                    .REASON_SERVICE_IN_USE;
19484                            app.adjSource = a;
19485                            app.adjSourceProcState = procState;
19486                            app.adjTarget = s.name;
19487                        }
19488                    }
19489                }
19490            }
19491        }
19492
19493        for (int provi = app.pubProviders.size()-1;
19494                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19495                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19496                        || procState > ActivityManager.PROCESS_STATE_TOP);
19497                provi--) {
19498            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19499            for (int i = cpr.connections.size()-1;
19500                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19501                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19502                            || procState > ActivityManager.PROCESS_STATE_TOP);
19503                    i--) {
19504                ContentProviderConnection conn = cpr.connections.get(i);
19505                ProcessRecord client = conn.client;
19506                if (client == app) {
19507                    // Being our own client is not interesting.
19508                    continue;
19509                }
19510                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19511                int clientProcState = client.curProcState;
19512                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19513                    // If the other app is cached for any reason, for purposes here
19514                    // we are going to consider it empty.
19515                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19516                }
19517                if (adj > clientAdj) {
19518                    if (app.hasShownUi && app != mHomeProcess
19519                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19520                        app.adjType = "cch-ui-provider";
19521                    } else {
19522                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19523                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19524                        app.adjType = "provider";
19525                    }
19526                    app.cached &= client.cached;
19527                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19528                            .REASON_PROVIDER_IN_USE;
19529                    app.adjSource = client;
19530                    app.adjSourceProcState = clientProcState;
19531                    app.adjTarget = cpr.name;
19532                }
19533                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19534                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19535                        // Special handling of clients who are in the top state.
19536                        // We *may* want to consider this process to be in the
19537                        // top state as well, but only if there is not another
19538                        // reason for it to be running.  Being on the top is a
19539                        // special state, meaning you are specifically running
19540                        // for the current top app.  If the process is already
19541                        // running in the background for some other reason, it
19542                        // is more important to continue considering it to be
19543                        // in the background state.
19544                        mayBeTop = true;
19545                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19546                    } else {
19547                        // Special handling for above-top states (persistent
19548                        // processes).  These should not bring the current process
19549                        // into the top state, since they are not on top.  Instead
19550                        // give them the best state after that.
19551                        clientProcState =
19552                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19553                    }
19554                }
19555                if (procState > clientProcState) {
19556                    procState = clientProcState;
19557                }
19558                if (client.curSchedGroup > schedGroup) {
19559                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19560                }
19561            }
19562            // If the provider has external (non-framework) process
19563            // dependencies, ensure that its adjustment is at least
19564            // FOREGROUND_APP_ADJ.
19565            if (cpr.hasExternalProcessHandles()) {
19566                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19567                    adj = ProcessList.FOREGROUND_APP_ADJ;
19568                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19569                    app.cached = false;
19570                    app.adjType = "provider";
19571                    app.adjTarget = cpr.name;
19572                }
19573                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19574                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19575                }
19576            }
19577        }
19578
19579        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19580            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19581                adj = ProcessList.PREVIOUS_APP_ADJ;
19582                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19583                app.cached = false;
19584                app.adjType = "provider";
19585            }
19586            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19587                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19588            }
19589        }
19590
19591        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19592            // A client of one of our services or providers is in the top state.  We
19593            // *may* want to be in the top state, but not if we are already running in
19594            // the background for some other reason.  For the decision here, we are going
19595            // to pick out a few specific states that we want to remain in when a client
19596            // is top (states that tend to be longer-term) and otherwise allow it to go
19597            // to the top state.
19598            switch (procState) {
19599                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19600                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19601                case ActivityManager.PROCESS_STATE_SERVICE:
19602                    // These all are longer-term states, so pull them up to the top
19603                    // of the background states, but not all the way to the top state.
19604                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19605                    break;
19606                default:
19607                    // Otherwise, top is a better choice, so take it.
19608                    procState = ActivityManager.PROCESS_STATE_TOP;
19609                    break;
19610            }
19611        }
19612
19613        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19614            if (app.hasClientActivities) {
19615                // This is a cached process, but with client activities.  Mark it so.
19616                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19617                app.adjType = "cch-client-act";
19618            } else if (app.treatLikeActivity) {
19619                // This is a cached process, but somebody wants us to treat it like it has
19620                // an activity, okay!
19621                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19622                app.adjType = "cch-as-act";
19623            }
19624        }
19625
19626        if (adj == ProcessList.SERVICE_ADJ) {
19627            if (doingAll) {
19628                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19629                mNewNumServiceProcs++;
19630                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19631                if (!app.serviceb) {
19632                    // This service isn't far enough down on the LRU list to
19633                    // normally be a B service, but if we are low on RAM and it
19634                    // is large we want to force it down since we would prefer to
19635                    // keep launcher over it.
19636                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19637                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19638                        app.serviceHighRam = true;
19639                        app.serviceb = true;
19640                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19641                    } else {
19642                        mNewNumAServiceProcs++;
19643                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19644                    }
19645                } else {
19646                    app.serviceHighRam = false;
19647                }
19648            }
19649            if (app.serviceb) {
19650                adj = ProcessList.SERVICE_B_ADJ;
19651            }
19652        }
19653
19654        app.curRawAdj = adj;
19655
19656        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19657        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19658        if (adj > app.maxAdj) {
19659            adj = app.maxAdj;
19660            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19661                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19662            }
19663        }
19664
19665        // Do final modification to adj.  Everything we do between here and applying
19666        // the final setAdj must be done in this function, because we will also use
19667        // it when computing the final cached adj later.  Note that we don't need to
19668        // worry about this for max adj above, since max adj will always be used to
19669        // keep it out of the cached vaues.
19670        app.curAdj = app.modifyRawOomAdj(adj);
19671        app.curSchedGroup = schedGroup;
19672        app.curProcState = procState;
19673        app.foregroundActivities = foregroundActivities;
19674
19675        return app.curRawAdj;
19676    }
19677
19678    /**
19679     * Record new PSS sample for a process.
19680     */
19681    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19682            long now) {
19683        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19684                swapPss * 1024);
19685        proc.lastPssTime = now;
19686        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19687        if (DEBUG_PSS) Slog.d(TAG_PSS,
19688                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19689                + " state=" + ProcessList.makeProcStateString(procState));
19690        if (proc.initialIdlePss == 0) {
19691            proc.initialIdlePss = pss;
19692        }
19693        proc.lastPss = pss;
19694        proc.lastSwapPss = swapPss;
19695        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19696            proc.lastCachedPss = pss;
19697            proc.lastCachedSwapPss = swapPss;
19698        }
19699
19700        final SparseArray<Pair<Long, String>> watchUids
19701                = mMemWatchProcesses.getMap().get(proc.processName);
19702        Long check = null;
19703        if (watchUids != null) {
19704            Pair<Long, String> val = watchUids.get(proc.uid);
19705            if (val == null) {
19706                val = watchUids.get(0);
19707            }
19708            if (val != null) {
19709                check = val.first;
19710            }
19711        }
19712        if (check != null) {
19713            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19714                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19715                if (!isDebuggable) {
19716                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19717                        isDebuggable = true;
19718                    }
19719                }
19720                if (isDebuggable) {
19721                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19722                    final ProcessRecord myProc = proc;
19723                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19724                    mMemWatchDumpProcName = proc.processName;
19725                    mMemWatchDumpFile = heapdumpFile.toString();
19726                    mMemWatchDumpPid = proc.pid;
19727                    mMemWatchDumpUid = proc.uid;
19728                    BackgroundThread.getHandler().post(new Runnable() {
19729                        @Override
19730                        public void run() {
19731                            revokeUriPermission(ActivityThread.currentActivityThread()
19732                                            .getApplicationThread(),
19733                                    DumpHeapActivity.JAVA_URI,
19734                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19735                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19736                                    UserHandle.myUserId());
19737                            ParcelFileDescriptor fd = null;
19738                            try {
19739                                heapdumpFile.delete();
19740                                fd = ParcelFileDescriptor.open(heapdumpFile,
19741                                        ParcelFileDescriptor.MODE_CREATE |
19742                                                ParcelFileDescriptor.MODE_TRUNCATE |
19743                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19744                                                ParcelFileDescriptor.MODE_APPEND);
19745                                IApplicationThread thread = myProc.thread;
19746                                if (thread != null) {
19747                                    try {
19748                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19749                                                "Requesting dump heap from "
19750                                                + myProc + " to " + heapdumpFile);
19751                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19752                                    } catch (RemoteException e) {
19753                                    }
19754                                }
19755                            } catch (FileNotFoundException e) {
19756                                e.printStackTrace();
19757                            } finally {
19758                                if (fd != null) {
19759                                    try {
19760                                        fd.close();
19761                                    } catch (IOException e) {
19762                                    }
19763                                }
19764                            }
19765                        }
19766                    });
19767                } else {
19768                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19769                            + ", but debugging not enabled");
19770                }
19771            }
19772        }
19773    }
19774
19775    /**
19776     * Schedule PSS collection of a process.
19777     */
19778    void requestPssLocked(ProcessRecord proc, int procState) {
19779        if (mPendingPssProcesses.contains(proc)) {
19780            return;
19781        }
19782        if (mPendingPssProcesses.size() == 0) {
19783            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19784        }
19785        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19786        proc.pssProcState = procState;
19787        mPendingPssProcesses.add(proc);
19788    }
19789
19790    /**
19791     * Schedule PSS collection of all processes.
19792     */
19793    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19794        if (!always) {
19795            if (now < (mLastFullPssTime +
19796                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19797                return;
19798            }
19799        }
19800        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19801        mLastFullPssTime = now;
19802        mFullPssPending = true;
19803        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19804        mPendingPssProcesses.clear();
19805        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19806            ProcessRecord app = mLruProcesses.get(i);
19807            if (app.thread == null
19808                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19809                continue;
19810            }
19811            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19812                app.pssProcState = app.setProcState;
19813                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19814                        mTestPssMode, isSleepingLocked(), now);
19815                mPendingPssProcesses.add(app);
19816            }
19817        }
19818        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19819    }
19820
19821    public void setTestPssMode(boolean enabled) {
19822        synchronized (this) {
19823            mTestPssMode = enabled;
19824            if (enabled) {
19825                // Whenever we enable the mode, we want to take a snapshot all of current
19826                // process mem use.
19827                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19828            }
19829        }
19830    }
19831
19832    /**
19833     * Ask a given process to GC right now.
19834     */
19835    final void performAppGcLocked(ProcessRecord app) {
19836        try {
19837            app.lastRequestedGc = SystemClock.uptimeMillis();
19838            if (app.thread != null) {
19839                if (app.reportLowMemory) {
19840                    app.reportLowMemory = false;
19841                    app.thread.scheduleLowMemory();
19842                } else {
19843                    app.thread.processInBackground();
19844                }
19845            }
19846        } catch (Exception e) {
19847            // whatever.
19848        }
19849    }
19850
19851    /**
19852     * Returns true if things are idle enough to perform GCs.
19853     */
19854    private final boolean canGcNowLocked() {
19855        boolean processingBroadcasts = false;
19856        for (BroadcastQueue q : mBroadcastQueues) {
19857            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19858                processingBroadcasts = true;
19859            }
19860        }
19861        return !processingBroadcasts
19862                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19863    }
19864
19865    /**
19866     * Perform GCs on all processes that are waiting for it, but only
19867     * if things are idle.
19868     */
19869    final void performAppGcsLocked() {
19870        final int N = mProcessesToGc.size();
19871        if (N <= 0) {
19872            return;
19873        }
19874        if (canGcNowLocked()) {
19875            while (mProcessesToGc.size() > 0) {
19876                ProcessRecord proc = mProcessesToGc.remove(0);
19877                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19878                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19879                            <= SystemClock.uptimeMillis()) {
19880                        // To avoid spamming the system, we will GC processes one
19881                        // at a time, waiting a few seconds between each.
19882                        performAppGcLocked(proc);
19883                        scheduleAppGcsLocked();
19884                        return;
19885                    } else {
19886                        // It hasn't been long enough since we last GCed this
19887                        // process...  put it in the list to wait for its time.
19888                        addProcessToGcListLocked(proc);
19889                        break;
19890                    }
19891                }
19892            }
19893
19894            scheduleAppGcsLocked();
19895        }
19896    }
19897
19898    /**
19899     * If all looks good, perform GCs on all processes waiting for them.
19900     */
19901    final void performAppGcsIfAppropriateLocked() {
19902        if (canGcNowLocked()) {
19903            performAppGcsLocked();
19904            return;
19905        }
19906        // Still not idle, wait some more.
19907        scheduleAppGcsLocked();
19908    }
19909
19910    /**
19911     * Schedule the execution of all pending app GCs.
19912     */
19913    final void scheduleAppGcsLocked() {
19914        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19915
19916        if (mProcessesToGc.size() > 0) {
19917            // Schedule a GC for the time to the next process.
19918            ProcessRecord proc = mProcessesToGc.get(0);
19919            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19920
19921            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19922            long now = SystemClock.uptimeMillis();
19923            if (when < (now+GC_TIMEOUT)) {
19924                when = now + GC_TIMEOUT;
19925            }
19926            mHandler.sendMessageAtTime(msg, when);
19927        }
19928    }
19929
19930    /**
19931     * Add a process to the array of processes waiting to be GCed.  Keeps the
19932     * list in sorted order by the last GC time.  The process can't already be
19933     * on the list.
19934     */
19935    final void addProcessToGcListLocked(ProcessRecord proc) {
19936        boolean added = false;
19937        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19938            if (mProcessesToGc.get(i).lastRequestedGc <
19939                    proc.lastRequestedGc) {
19940                added = true;
19941                mProcessesToGc.add(i+1, proc);
19942                break;
19943            }
19944        }
19945        if (!added) {
19946            mProcessesToGc.add(0, proc);
19947        }
19948    }
19949
19950    /**
19951     * Set up to ask a process to GC itself.  This will either do it
19952     * immediately, or put it on the list of processes to gc the next
19953     * time things are idle.
19954     */
19955    final void scheduleAppGcLocked(ProcessRecord app) {
19956        long now = SystemClock.uptimeMillis();
19957        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19958            return;
19959        }
19960        if (!mProcessesToGc.contains(app)) {
19961            addProcessToGcListLocked(app);
19962            scheduleAppGcsLocked();
19963        }
19964    }
19965
19966    final void checkExcessivePowerUsageLocked(boolean doKills) {
19967        updateCpuStatsNow();
19968
19969        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19970        boolean doWakeKills = doKills;
19971        boolean doCpuKills = doKills;
19972        if (mLastPowerCheckRealtime == 0) {
19973            doWakeKills = false;
19974        }
19975        if (mLastPowerCheckUptime == 0) {
19976            doCpuKills = false;
19977        }
19978        if (stats.isScreenOn()) {
19979            doWakeKills = false;
19980        }
19981        final long curRealtime = SystemClock.elapsedRealtime();
19982        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19983        final long curUptime = SystemClock.uptimeMillis();
19984        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19985        mLastPowerCheckRealtime = curRealtime;
19986        mLastPowerCheckUptime = curUptime;
19987        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19988            doWakeKills = false;
19989        }
19990        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19991            doCpuKills = false;
19992        }
19993        int i = mLruProcesses.size();
19994        while (i > 0) {
19995            i--;
19996            ProcessRecord app = mLruProcesses.get(i);
19997            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19998                long wtime;
19999                synchronized (stats) {
20000                    wtime = stats.getProcessWakeTime(app.info.uid,
20001                            app.pid, curRealtime);
20002                }
20003                long wtimeUsed = wtime - app.lastWakeTime;
20004                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20005                if (DEBUG_POWER) {
20006                    StringBuilder sb = new StringBuilder(128);
20007                    sb.append("Wake for ");
20008                    app.toShortString(sb);
20009                    sb.append(": over ");
20010                    TimeUtils.formatDuration(realtimeSince, sb);
20011                    sb.append(" used ");
20012                    TimeUtils.formatDuration(wtimeUsed, sb);
20013                    sb.append(" (");
20014                    sb.append((wtimeUsed*100)/realtimeSince);
20015                    sb.append("%)");
20016                    Slog.i(TAG_POWER, sb.toString());
20017                    sb.setLength(0);
20018                    sb.append("CPU for ");
20019                    app.toShortString(sb);
20020                    sb.append(": over ");
20021                    TimeUtils.formatDuration(uptimeSince, sb);
20022                    sb.append(" used ");
20023                    TimeUtils.formatDuration(cputimeUsed, sb);
20024                    sb.append(" (");
20025                    sb.append((cputimeUsed*100)/uptimeSince);
20026                    sb.append("%)");
20027                    Slog.i(TAG_POWER, sb.toString());
20028                }
20029                // If a process has held a wake lock for more
20030                // than 50% of the time during this period,
20031                // that sounds bad.  Kill!
20032                if (doWakeKills && realtimeSince > 0
20033                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20034                    synchronized (stats) {
20035                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20036                                realtimeSince, wtimeUsed);
20037                    }
20038                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20039                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20040                } else if (doCpuKills && uptimeSince > 0
20041                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20042                    synchronized (stats) {
20043                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20044                                uptimeSince, cputimeUsed);
20045                    }
20046                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20047                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20048                } else {
20049                    app.lastWakeTime = wtime;
20050                    app.lastCpuTime = app.curCpuTime;
20051                }
20052            }
20053        }
20054    }
20055
20056    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20057            long nowElapsed) {
20058        boolean success = true;
20059
20060        if (app.curRawAdj != app.setRawAdj) {
20061            app.setRawAdj = app.curRawAdj;
20062        }
20063
20064        int changes = 0;
20065
20066        if (app.curAdj != app.setAdj) {
20067            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20068            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20069                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20070                    + app.adjType);
20071            app.setAdj = app.curAdj;
20072        }
20073
20074        if (app.setSchedGroup != app.curSchedGroup) {
20075            app.setSchedGroup = app.curSchedGroup;
20076            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20077                    "Setting sched group of " + app.processName
20078                    + " to " + app.curSchedGroup);
20079            if (app.waitingToKill != null && app.curReceiver == null
20080                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20081                app.kill(app.waitingToKill, true);
20082                success = false;
20083            } else {
20084                int processGroup;
20085                switch (app.curSchedGroup) {
20086                    case ProcessList.SCHED_GROUP_BACKGROUND:
20087                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20088                        break;
20089                    case ProcessList.SCHED_GROUP_TOP_APP:
20090                        processGroup = Process.THREAD_GROUP_TOP_APP;
20091                        break;
20092                    default:
20093                        processGroup = Process.THREAD_GROUP_DEFAULT;
20094                        break;
20095                }
20096                if (true) {
20097                    long oldId = Binder.clearCallingIdentity();
20098                    try {
20099                        Process.setProcessGroup(app.pid, processGroup);
20100                    } catch (Exception e) {
20101                        Slog.w(TAG, "Failed setting process group of " + app.pid
20102                                + " to " + app.curSchedGroup);
20103                        e.printStackTrace();
20104                    } finally {
20105                        Binder.restoreCallingIdentity(oldId);
20106                    }
20107                } else {
20108                    if (app.thread != null) {
20109                        try {
20110                            app.thread.setSchedulingGroup(processGroup);
20111                        } catch (RemoteException e) {
20112                        }
20113                    }
20114                }
20115            }
20116        }
20117        if (app.repForegroundActivities != app.foregroundActivities) {
20118            app.repForegroundActivities = app.foregroundActivities;
20119            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20120        }
20121        if (app.repProcState != app.curProcState) {
20122            app.repProcState = app.curProcState;
20123            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20124            if (app.thread != null) {
20125                try {
20126                    if (false) {
20127                        //RuntimeException h = new RuntimeException("here");
20128                        Slog.i(TAG, "Sending new process state " + app.repProcState
20129                                + " to " + app /*, h*/);
20130                    }
20131                    app.thread.setProcessState(app.repProcState);
20132                } catch (RemoteException e) {
20133                }
20134            }
20135        }
20136        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20137                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20138            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20139                // Experimental code to more aggressively collect pss while
20140                // running test...  the problem is that this tends to collect
20141                // the data right when a process is transitioning between process
20142                // states, which well tend to give noisy data.
20143                long start = SystemClock.uptimeMillis();
20144                long pss = Debug.getPss(app.pid, mTmpLong, null);
20145                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20146                mPendingPssProcesses.remove(app);
20147                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20148                        + " to " + app.curProcState + ": "
20149                        + (SystemClock.uptimeMillis()-start) + "ms");
20150            }
20151            app.lastStateTime = now;
20152            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20153                    mTestPssMode, isSleepingLocked(), now);
20154            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20155                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20156                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20157                    + (app.nextPssTime-now) + ": " + app);
20158        } else {
20159            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20160                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20161                    mTestPssMode)))) {
20162                requestPssLocked(app, app.setProcState);
20163                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20164                        mTestPssMode, isSleepingLocked(), now);
20165            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20166                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20167        }
20168        if (app.setProcState != app.curProcState) {
20169            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20170                    "Proc state change of " + app.processName
20171                            + " to " + app.curProcState);
20172            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20173            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20174            if (setImportant && !curImportant) {
20175                // This app is no longer something we consider important enough to allow to
20176                // use arbitrary amounts of battery power.  Note
20177                // its current wake lock time to later know to kill it if
20178                // it is not behaving well.
20179                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20180                synchronized (stats) {
20181                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20182                            app.pid, nowElapsed);
20183                }
20184                app.lastCpuTime = app.curCpuTime;
20185
20186            }
20187            // Inform UsageStats of important process state change
20188            // Must be called before updating setProcState
20189            maybeUpdateUsageStatsLocked(app, nowElapsed);
20190
20191            app.setProcState = app.curProcState;
20192            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20193                app.notCachedSinceIdle = false;
20194            }
20195            if (!doingAll) {
20196                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20197            } else {
20198                app.procStateChanged = true;
20199            }
20200        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20201                > USAGE_STATS_INTERACTION_INTERVAL) {
20202            // For apps that sit around for a long time in the interactive state, we need
20203            // to report this at least once a day so they don't go idle.
20204            maybeUpdateUsageStatsLocked(app, nowElapsed);
20205        }
20206
20207        if (changes != 0) {
20208            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20209                    "Changes in " + app + ": " + changes);
20210            int i = mPendingProcessChanges.size()-1;
20211            ProcessChangeItem item = null;
20212            while (i >= 0) {
20213                item = mPendingProcessChanges.get(i);
20214                if (item.pid == app.pid) {
20215                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20216                            "Re-using existing item: " + item);
20217                    break;
20218                }
20219                i--;
20220            }
20221            if (i < 0) {
20222                // No existing item in pending changes; need a new one.
20223                final int NA = mAvailProcessChanges.size();
20224                if (NA > 0) {
20225                    item = mAvailProcessChanges.remove(NA-1);
20226                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20227                            "Retrieving available item: " + item);
20228                } else {
20229                    item = new ProcessChangeItem();
20230                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20231                            "Allocating new item: " + item);
20232                }
20233                item.changes = 0;
20234                item.pid = app.pid;
20235                item.uid = app.info.uid;
20236                if (mPendingProcessChanges.size() == 0) {
20237                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20238                            "*** Enqueueing dispatch processes changed!");
20239                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20240                }
20241                mPendingProcessChanges.add(item);
20242            }
20243            item.changes |= changes;
20244            item.processState = app.repProcState;
20245            item.foregroundActivities = app.repForegroundActivities;
20246            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20247                    "Item " + Integer.toHexString(System.identityHashCode(item))
20248                    + " " + app.toShortString() + ": changes=" + item.changes
20249                    + " procState=" + item.processState
20250                    + " foreground=" + item.foregroundActivities
20251                    + " type=" + app.adjType + " source=" + app.adjSource
20252                    + " target=" + app.adjTarget);
20253        }
20254
20255        return success;
20256    }
20257
20258    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20259        final UidRecord.ChangeItem pendingChange;
20260        if (uidRec == null || uidRec.pendingChange == null) {
20261            if (mPendingUidChanges.size() == 0) {
20262                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20263                        "*** Enqueueing dispatch uid changed!");
20264                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20265            }
20266            final int NA = mAvailUidChanges.size();
20267            if (NA > 0) {
20268                pendingChange = mAvailUidChanges.remove(NA-1);
20269                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20270                        "Retrieving available item: " + pendingChange);
20271            } else {
20272                pendingChange = new UidRecord.ChangeItem();
20273                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20274                        "Allocating new item: " + pendingChange);
20275            }
20276            if (uidRec != null) {
20277                uidRec.pendingChange = pendingChange;
20278                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20279                    // If this uid is going away, and we haven't yet reported it is gone,
20280                    // then do so now.
20281                    change = UidRecord.CHANGE_GONE_IDLE;
20282                }
20283            } else if (uid < 0) {
20284                throw new IllegalArgumentException("No UidRecord or uid");
20285            }
20286            pendingChange.uidRecord = uidRec;
20287            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20288            mPendingUidChanges.add(pendingChange);
20289        } else {
20290            pendingChange = uidRec.pendingChange;
20291            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20292                change = UidRecord.CHANGE_GONE_IDLE;
20293            }
20294        }
20295        pendingChange.change = change;
20296        pendingChange.processState = uidRec != null
20297                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20298    }
20299
20300    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20301            String authority) {
20302        if (app == null) return;
20303        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20304            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20305            if (userState == null) return;
20306            final long now = SystemClock.elapsedRealtime();
20307            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20308            if (lastReported == null || lastReported < now - 60 * 1000L) {
20309                mUsageStatsService.reportContentProviderUsage(
20310                        authority, providerPkgName, app.userId);
20311                userState.mProviderLastReportedFg.put(authority, now);
20312            }
20313        }
20314    }
20315
20316    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20317        if (DEBUG_USAGE_STATS) {
20318            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20319                    + "] state changes: old = " + app.setProcState + ", new = "
20320                    + app.curProcState);
20321        }
20322        if (mUsageStatsService == null) {
20323            return;
20324        }
20325        boolean isInteraction;
20326        // To avoid some abuse patterns, we are going to be careful about what we consider
20327        // to be an app interaction.  Being the top activity doesn't count while the display
20328        // is sleeping, nor do short foreground services.
20329        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20330            isInteraction = true;
20331            app.fgInteractionTime = 0;
20332        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20333            if (app.fgInteractionTime == 0) {
20334                app.fgInteractionTime = nowElapsed;
20335                isInteraction = false;
20336            } else {
20337                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20338            }
20339        } else {
20340            isInteraction = app.curProcState
20341                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20342            app.fgInteractionTime = 0;
20343        }
20344        if (isInteraction && (!app.reportedInteraction
20345                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20346            app.interactionEventTime = nowElapsed;
20347            String[] packages = app.getPackageList();
20348            if (packages != null) {
20349                for (int i = 0; i < packages.length; i++) {
20350                    mUsageStatsService.reportEvent(packages[i], app.userId,
20351                            UsageEvents.Event.SYSTEM_INTERACTION);
20352                }
20353            }
20354        }
20355        app.reportedInteraction = isInteraction;
20356        if (!isInteraction) {
20357            app.interactionEventTime = 0;
20358        }
20359    }
20360
20361    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20362        if (proc.thread != null) {
20363            if (proc.baseProcessTracker != null) {
20364                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20365            }
20366        }
20367    }
20368
20369    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20370            ProcessRecord TOP_APP, boolean doingAll, long now) {
20371        if (app.thread == null) {
20372            return false;
20373        }
20374
20375        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20376
20377        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20378    }
20379
20380    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20381            boolean oomAdj) {
20382        if (isForeground != proc.foregroundServices) {
20383            proc.foregroundServices = isForeground;
20384            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20385                    proc.info.uid);
20386            if (isForeground) {
20387                if (curProcs == null) {
20388                    curProcs = new ArrayList<ProcessRecord>();
20389                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20390                }
20391                if (!curProcs.contains(proc)) {
20392                    curProcs.add(proc);
20393                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20394                            proc.info.packageName, proc.info.uid);
20395                }
20396            } else {
20397                if (curProcs != null) {
20398                    if (curProcs.remove(proc)) {
20399                        mBatteryStatsService.noteEvent(
20400                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20401                                proc.info.packageName, proc.info.uid);
20402                        if (curProcs.size() <= 0) {
20403                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20404                        }
20405                    }
20406                }
20407            }
20408            if (oomAdj) {
20409                updateOomAdjLocked();
20410            }
20411        }
20412    }
20413
20414    private final ActivityRecord resumedAppLocked() {
20415        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20416        String pkg;
20417        int uid;
20418        if (act != null) {
20419            pkg = act.packageName;
20420            uid = act.info.applicationInfo.uid;
20421        } else {
20422            pkg = null;
20423            uid = -1;
20424        }
20425        // Has the UID or resumed package name changed?
20426        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20427                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20428            if (mCurResumedPackage != null) {
20429                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20430                        mCurResumedPackage, mCurResumedUid);
20431            }
20432            mCurResumedPackage = pkg;
20433            mCurResumedUid = uid;
20434            if (mCurResumedPackage != null) {
20435                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20436                        mCurResumedPackage, mCurResumedUid);
20437            }
20438        }
20439        return act;
20440    }
20441
20442    final boolean updateOomAdjLocked(ProcessRecord app) {
20443        final ActivityRecord TOP_ACT = resumedAppLocked();
20444        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20445        final boolean wasCached = app.cached;
20446
20447        mAdjSeq++;
20448
20449        // This is the desired cached adjusment we want to tell it to use.
20450        // If our app is currently cached, we know it, and that is it.  Otherwise,
20451        // we don't know it yet, and it needs to now be cached we will then
20452        // need to do a complete oom adj.
20453        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20454                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20455        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20456                SystemClock.uptimeMillis());
20457        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20458            // Changed to/from cached state, so apps after it in the LRU
20459            // list may also be changed.
20460            updateOomAdjLocked();
20461        }
20462        return success;
20463    }
20464
20465    final void updateOomAdjLocked() {
20466        final ActivityRecord TOP_ACT = resumedAppLocked();
20467        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20468        final long now = SystemClock.uptimeMillis();
20469        final long nowElapsed = SystemClock.elapsedRealtime();
20470        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20471        final int N = mLruProcesses.size();
20472
20473        if (false) {
20474            RuntimeException e = new RuntimeException();
20475            e.fillInStackTrace();
20476            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20477        }
20478
20479        // Reset state in all uid records.
20480        for (int i=mActiveUids.size()-1; i>=0; i--) {
20481            final UidRecord uidRec = mActiveUids.valueAt(i);
20482            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20483                    "Starting update of " + uidRec);
20484            uidRec.reset();
20485        }
20486
20487        mStackSupervisor.rankTaskLayersIfNeeded();
20488
20489        mAdjSeq++;
20490        mNewNumServiceProcs = 0;
20491        mNewNumAServiceProcs = 0;
20492
20493        final int emptyProcessLimit;
20494        final int cachedProcessLimit;
20495        if (mProcessLimit <= 0) {
20496            emptyProcessLimit = cachedProcessLimit = 0;
20497        } else if (mProcessLimit == 1) {
20498            emptyProcessLimit = 1;
20499            cachedProcessLimit = 0;
20500        } else {
20501            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20502            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20503        }
20504
20505        // Let's determine how many processes we have running vs.
20506        // how many slots we have for background processes; we may want
20507        // to put multiple processes in a slot of there are enough of
20508        // them.
20509        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20510                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20511        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20512        if (numEmptyProcs > cachedProcessLimit) {
20513            // If there are more empty processes than our limit on cached
20514            // processes, then use the cached process limit for the factor.
20515            // This ensures that the really old empty processes get pushed
20516            // down to the bottom, so if we are running low on memory we will
20517            // have a better chance at keeping around more cached processes
20518            // instead of a gazillion empty processes.
20519            numEmptyProcs = cachedProcessLimit;
20520        }
20521        int emptyFactor = numEmptyProcs/numSlots;
20522        if (emptyFactor < 1) emptyFactor = 1;
20523        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20524        if (cachedFactor < 1) cachedFactor = 1;
20525        int stepCached = 0;
20526        int stepEmpty = 0;
20527        int numCached = 0;
20528        int numEmpty = 0;
20529        int numTrimming = 0;
20530
20531        mNumNonCachedProcs = 0;
20532        mNumCachedHiddenProcs = 0;
20533
20534        // First update the OOM adjustment for each of the
20535        // application processes based on their current state.
20536        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20537        int nextCachedAdj = curCachedAdj+1;
20538        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20539        int nextEmptyAdj = curEmptyAdj+2;
20540        for (int i=N-1; i>=0; i--) {
20541            ProcessRecord app = mLruProcesses.get(i);
20542            if (!app.killedByAm && app.thread != null) {
20543                app.procStateChanged = false;
20544                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20545
20546                // If we haven't yet assigned the final cached adj
20547                // to the process, do that now.
20548                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20549                    switch (app.curProcState) {
20550                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20551                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20552                            // This process is a cached process holding activities...
20553                            // assign it the next cached value for that type, and then
20554                            // step that cached level.
20555                            app.curRawAdj = curCachedAdj;
20556                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20557                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20558                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20559                                    + ")");
20560                            if (curCachedAdj != nextCachedAdj) {
20561                                stepCached++;
20562                                if (stepCached >= cachedFactor) {
20563                                    stepCached = 0;
20564                                    curCachedAdj = nextCachedAdj;
20565                                    nextCachedAdj += 2;
20566                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20567                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20568                                    }
20569                                }
20570                            }
20571                            break;
20572                        default:
20573                            // For everything else, assign next empty cached process
20574                            // level and bump that up.  Note that this means that
20575                            // long-running services that have dropped down to the
20576                            // cached level will be treated as empty (since their process
20577                            // state is still as a service), which is what we want.
20578                            app.curRawAdj = curEmptyAdj;
20579                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20580                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20581                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20582                                    + ")");
20583                            if (curEmptyAdj != nextEmptyAdj) {
20584                                stepEmpty++;
20585                                if (stepEmpty >= emptyFactor) {
20586                                    stepEmpty = 0;
20587                                    curEmptyAdj = nextEmptyAdj;
20588                                    nextEmptyAdj += 2;
20589                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20590                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20591                                    }
20592                                }
20593                            }
20594                            break;
20595                    }
20596                }
20597
20598                applyOomAdjLocked(app, true, now, nowElapsed);
20599
20600                // Count the number of process types.
20601                switch (app.curProcState) {
20602                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20603                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20604                        mNumCachedHiddenProcs++;
20605                        numCached++;
20606                        if (numCached > cachedProcessLimit) {
20607                            app.kill("cached #" + numCached, true);
20608                        }
20609                        break;
20610                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20611                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20612                                && app.lastActivityTime < oldTime) {
20613                            app.kill("empty for "
20614                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20615                                    / 1000) + "s", true);
20616                        } else {
20617                            numEmpty++;
20618                            if (numEmpty > emptyProcessLimit) {
20619                                app.kill("empty #" + numEmpty, true);
20620                            }
20621                        }
20622                        break;
20623                    default:
20624                        mNumNonCachedProcs++;
20625                        break;
20626                }
20627
20628                if (app.isolated && app.services.size() <= 0) {
20629                    // If this is an isolated process, and there are no
20630                    // services running in it, then the process is no longer
20631                    // needed.  We agressively kill these because we can by
20632                    // definition not re-use the same process again, and it is
20633                    // good to avoid having whatever code was running in them
20634                    // left sitting around after no longer needed.
20635                    app.kill("isolated not needed", true);
20636                } else {
20637                    // Keeping this process, update its uid.
20638                    final UidRecord uidRec = app.uidRecord;
20639                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20640                        uidRec.curProcState = app.curProcState;
20641                    }
20642                }
20643
20644                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20645                        && !app.killedByAm) {
20646                    numTrimming++;
20647                }
20648            }
20649        }
20650
20651        mNumServiceProcs = mNewNumServiceProcs;
20652
20653        // Now determine the memory trimming level of background processes.
20654        // Unfortunately we need to start at the back of the list to do this
20655        // properly.  We only do this if the number of background apps we
20656        // are managing to keep around is less than half the maximum we desire;
20657        // if we are keeping a good number around, we'll let them use whatever
20658        // memory they want.
20659        final int numCachedAndEmpty = numCached + numEmpty;
20660        int memFactor;
20661        if (numCached <= ProcessList.TRIM_CACHED_APPS
20662                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20663            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20664                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20665            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20666                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20667            } else {
20668                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20669            }
20670        } else {
20671            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20672        }
20673        // We always allow the memory level to go up (better).  We only allow it to go
20674        // down if we are in a state where that is allowed, *and* the total number of processes
20675        // has gone down since last time.
20676        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20677                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20678                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20679        if (memFactor > mLastMemoryLevel) {
20680            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20681                memFactor = mLastMemoryLevel;
20682                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20683            }
20684        }
20685        if (memFactor != mLastMemoryLevel) {
20686            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20687        }
20688        mLastMemoryLevel = memFactor;
20689        mLastNumProcesses = mLruProcesses.size();
20690        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20691        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20692        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20693            if (mLowRamStartTime == 0) {
20694                mLowRamStartTime = now;
20695            }
20696            int step = 0;
20697            int fgTrimLevel;
20698            switch (memFactor) {
20699                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20700                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20701                    break;
20702                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20703                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20704                    break;
20705                default:
20706                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20707                    break;
20708            }
20709            int factor = numTrimming/3;
20710            int minFactor = 2;
20711            if (mHomeProcess != null) minFactor++;
20712            if (mPreviousProcess != null) minFactor++;
20713            if (factor < minFactor) factor = minFactor;
20714            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20715            for (int i=N-1; i>=0; i--) {
20716                ProcessRecord app = mLruProcesses.get(i);
20717                if (allChanged || app.procStateChanged) {
20718                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20719                    app.procStateChanged = false;
20720                }
20721                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20722                        && !app.killedByAm) {
20723                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20724                        try {
20725                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20726                                    "Trimming memory of " + app.processName + " to " + curLevel);
20727                            app.thread.scheduleTrimMemory(curLevel);
20728                        } catch (RemoteException e) {
20729                        }
20730                        if (false) {
20731                            // For now we won't do this; our memory trimming seems
20732                            // to be good enough at this point that destroying
20733                            // activities causes more harm than good.
20734                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20735                                    && app != mHomeProcess && app != mPreviousProcess) {
20736                                // Need to do this on its own message because the stack may not
20737                                // be in a consistent state at this point.
20738                                // For these apps we will also finish their activities
20739                                // to help them free memory.
20740                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20741                            }
20742                        }
20743                    }
20744                    app.trimMemoryLevel = curLevel;
20745                    step++;
20746                    if (step >= factor) {
20747                        step = 0;
20748                        switch (curLevel) {
20749                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20750                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20751                                break;
20752                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20753                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20754                                break;
20755                        }
20756                    }
20757                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20758                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20759                            && app.thread != null) {
20760                        try {
20761                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20762                                    "Trimming memory of heavy-weight " + app.processName
20763                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20764                            app.thread.scheduleTrimMemory(
20765                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20766                        } catch (RemoteException e) {
20767                        }
20768                    }
20769                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20770                } else {
20771                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20772                            || app.systemNoUi) && app.pendingUiClean) {
20773                        // If this application is now in the background and it
20774                        // had done UI, then give it the special trim level to
20775                        // have it free UI resources.
20776                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20777                        if (app.trimMemoryLevel < level && app.thread != null) {
20778                            try {
20779                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20780                                        "Trimming memory of bg-ui " + app.processName
20781                                        + " to " + level);
20782                                app.thread.scheduleTrimMemory(level);
20783                            } catch (RemoteException e) {
20784                            }
20785                        }
20786                        app.pendingUiClean = false;
20787                    }
20788                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20789                        try {
20790                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20791                                    "Trimming memory of fg " + app.processName
20792                                    + " to " + fgTrimLevel);
20793                            app.thread.scheduleTrimMemory(fgTrimLevel);
20794                        } catch (RemoteException e) {
20795                        }
20796                    }
20797                    app.trimMemoryLevel = fgTrimLevel;
20798                }
20799            }
20800        } else {
20801            if (mLowRamStartTime != 0) {
20802                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20803                mLowRamStartTime = 0;
20804            }
20805            for (int i=N-1; i>=0; i--) {
20806                ProcessRecord app = mLruProcesses.get(i);
20807                if (allChanged || app.procStateChanged) {
20808                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20809                    app.procStateChanged = false;
20810                }
20811                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20812                        || app.systemNoUi) && app.pendingUiClean) {
20813                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20814                            && app.thread != null) {
20815                        try {
20816                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20817                                    "Trimming memory of ui hidden " + app.processName
20818                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20819                            app.thread.scheduleTrimMemory(
20820                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20821                        } catch (RemoteException e) {
20822                        }
20823                    }
20824                    app.pendingUiClean = false;
20825                }
20826                app.trimMemoryLevel = 0;
20827            }
20828        }
20829
20830        if (mAlwaysFinishActivities) {
20831            // Need to do this on its own message because the stack may not
20832            // be in a consistent state at this point.
20833            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20834        }
20835
20836        if (allChanged) {
20837            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20838        }
20839
20840        // Update from any uid changes.
20841        for (int i=mActiveUids.size()-1; i>=0; i--) {
20842            final UidRecord uidRec = mActiveUids.valueAt(i);
20843            int uidChange = UidRecord.CHANGE_PROCSTATE;
20844            if (uidRec.setProcState != uidRec.curProcState) {
20845                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20846                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20847                        + " to " + uidRec.curProcState);
20848                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20849                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20850                        uidRec.lastBackgroundTime = nowElapsed;
20851                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20852                            // Note: the background settle time is in elapsed realtime, while
20853                            // the handler time base is uptime.  All this means is that we may
20854                            // stop background uids later than we had intended, but that only
20855                            // happens because the device was sleeping so we are okay anyway.
20856                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20857                        }
20858                    }
20859                } else {
20860                    if (uidRec.idle) {
20861                        uidChange = UidRecord.CHANGE_ACTIVE;
20862                        uidRec.idle = false;
20863                    }
20864                    uidRec.lastBackgroundTime = 0;
20865                }
20866                uidRec.setProcState = uidRec.curProcState;
20867                enqueueUidChangeLocked(uidRec, -1, uidChange);
20868                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20869            }
20870        }
20871
20872        if (mProcessStats.shouldWriteNowLocked(now)) {
20873            mHandler.post(new Runnable() {
20874                @Override public void run() {
20875                    synchronized (ActivityManagerService.this) {
20876                        mProcessStats.writeStateAsyncLocked();
20877                    }
20878                }
20879            });
20880        }
20881
20882        if (DEBUG_OOM_ADJ) {
20883            final long duration = SystemClock.uptimeMillis() - now;
20884            if (false) {
20885                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20886                        new RuntimeException("here").fillInStackTrace());
20887            } else {
20888                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20889            }
20890        }
20891    }
20892
20893    final void idleUids() {
20894        synchronized (this) {
20895            final long nowElapsed = SystemClock.elapsedRealtime();
20896            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20897            long nextTime = 0;
20898            for (int i=mActiveUids.size()-1; i>=0; i--) {
20899                final UidRecord uidRec = mActiveUids.valueAt(i);
20900                final long bgTime = uidRec.lastBackgroundTime;
20901                if (bgTime > 0 && !uidRec.idle) {
20902                    if (bgTime <= maxBgTime) {
20903                        uidRec.idle = true;
20904                        doStopUidLocked(uidRec.uid, uidRec);
20905                    } else {
20906                        if (nextTime == 0 || nextTime > bgTime) {
20907                            nextTime = bgTime;
20908                        }
20909                    }
20910                }
20911            }
20912            if (nextTime > 0) {
20913                mHandler.removeMessages(IDLE_UIDS_MSG);
20914                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20915                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20916            }
20917        }
20918    }
20919
20920    final void runInBackgroundDisabled(int uid) {
20921        synchronized (this) {
20922            UidRecord uidRec = mActiveUids.get(uid);
20923            if (uidRec != null) {
20924                // This uid is actually running...  should it be considered background now?
20925                if (uidRec.idle) {
20926                    doStopUidLocked(uidRec.uid, uidRec);
20927                }
20928            } else {
20929                // This uid isn't actually running...  still send a report about it being "stopped".
20930                doStopUidLocked(uid, null);
20931            }
20932        }
20933    }
20934
20935    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20936        mServices.stopInBackgroundLocked(uid);
20937        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20938    }
20939
20940    final void trimApplications() {
20941        synchronized (this) {
20942            int i;
20943
20944            // First remove any unused application processes whose package
20945            // has been removed.
20946            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20947                final ProcessRecord app = mRemovedProcesses.get(i);
20948                if (app.activities.size() == 0
20949                        && app.curReceiver == null && app.services.size() == 0) {
20950                    Slog.i(
20951                        TAG, "Exiting empty application process "
20952                        + app.toShortString() + " ("
20953                        + (app.thread != null ? app.thread.asBinder() : null)
20954                        + ")\n");
20955                    if (app.pid > 0 && app.pid != MY_PID) {
20956                        app.kill("empty", false);
20957                    } else {
20958                        try {
20959                            app.thread.scheduleExit();
20960                        } catch (Exception e) {
20961                            // Ignore exceptions.
20962                        }
20963                    }
20964                    cleanUpApplicationRecordLocked(app, false, true, -1);
20965                    mRemovedProcesses.remove(i);
20966
20967                    if (app.persistent) {
20968                        addAppLocked(app.info, false, null /* ABI override */);
20969                    }
20970                }
20971            }
20972
20973            // Now update the oom adj for all processes.
20974            updateOomAdjLocked();
20975        }
20976    }
20977
20978    /** This method sends the specified signal to each of the persistent apps */
20979    public void signalPersistentProcesses(int sig) throws RemoteException {
20980        if (sig != Process.SIGNAL_USR1) {
20981            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20982        }
20983
20984        synchronized (this) {
20985            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20986                    != PackageManager.PERMISSION_GRANTED) {
20987                throw new SecurityException("Requires permission "
20988                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20989            }
20990
20991            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20992                ProcessRecord r = mLruProcesses.get(i);
20993                if (r.thread != null && r.persistent) {
20994                    Process.sendSignal(r.pid, sig);
20995                }
20996            }
20997        }
20998    }
20999
21000    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21001        if (proc == null || proc == mProfileProc) {
21002            proc = mProfileProc;
21003            profileType = mProfileType;
21004            clearProfilerLocked();
21005        }
21006        if (proc == null) {
21007            return;
21008        }
21009        try {
21010            proc.thread.profilerControl(false, null, profileType);
21011        } catch (RemoteException e) {
21012            throw new IllegalStateException("Process disappeared");
21013        }
21014    }
21015
21016    private void clearProfilerLocked() {
21017        if (mProfileFd != null) {
21018            try {
21019                mProfileFd.close();
21020            } catch (IOException e) {
21021            }
21022        }
21023        mProfileApp = null;
21024        mProfileProc = null;
21025        mProfileFile = null;
21026        mProfileType = 0;
21027        mAutoStopProfiler = false;
21028        mSamplingInterval = 0;
21029    }
21030
21031    public boolean profileControl(String process, int userId, boolean start,
21032            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21033
21034        try {
21035            synchronized (this) {
21036                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21037                // its own permission.
21038                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21039                        != PackageManager.PERMISSION_GRANTED) {
21040                    throw new SecurityException("Requires permission "
21041                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21042                }
21043
21044                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21045                    throw new IllegalArgumentException("null profile info or fd");
21046                }
21047
21048                ProcessRecord proc = null;
21049                if (process != null) {
21050                    proc = findProcessLocked(process, userId, "profileControl");
21051                }
21052
21053                if (start && (proc == null || proc.thread == null)) {
21054                    throw new IllegalArgumentException("Unknown process: " + process);
21055                }
21056
21057                if (start) {
21058                    stopProfilerLocked(null, 0);
21059                    setProfileApp(proc.info, proc.processName, profilerInfo);
21060                    mProfileProc = proc;
21061                    mProfileType = profileType;
21062                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21063                    try {
21064                        fd = fd.dup();
21065                    } catch (IOException e) {
21066                        fd = null;
21067                    }
21068                    profilerInfo.profileFd = fd;
21069                    proc.thread.profilerControl(start, profilerInfo, profileType);
21070                    fd = null;
21071                    mProfileFd = null;
21072                } else {
21073                    stopProfilerLocked(proc, profileType);
21074                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21075                        try {
21076                            profilerInfo.profileFd.close();
21077                        } catch (IOException e) {
21078                        }
21079                    }
21080                }
21081
21082                return true;
21083            }
21084        } catch (RemoteException e) {
21085            throw new IllegalStateException("Process disappeared");
21086        } finally {
21087            if (profilerInfo != null && profilerInfo.profileFd != null) {
21088                try {
21089                    profilerInfo.profileFd.close();
21090                } catch (IOException e) {
21091                }
21092            }
21093        }
21094    }
21095
21096    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21097        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21098                userId, true, ALLOW_FULL_ONLY, callName, null);
21099        ProcessRecord proc = null;
21100        try {
21101            int pid = Integer.parseInt(process);
21102            synchronized (mPidsSelfLocked) {
21103                proc = mPidsSelfLocked.get(pid);
21104            }
21105        } catch (NumberFormatException e) {
21106        }
21107
21108        if (proc == null) {
21109            ArrayMap<String, SparseArray<ProcessRecord>> all
21110                    = mProcessNames.getMap();
21111            SparseArray<ProcessRecord> procs = all.get(process);
21112            if (procs != null && procs.size() > 0) {
21113                proc = procs.valueAt(0);
21114                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21115                    for (int i=1; i<procs.size(); i++) {
21116                        ProcessRecord thisProc = procs.valueAt(i);
21117                        if (thisProc.userId == userId) {
21118                            proc = thisProc;
21119                            break;
21120                        }
21121                    }
21122                }
21123            }
21124        }
21125
21126        return proc;
21127    }
21128
21129    public boolean dumpHeap(String process, int userId, boolean managed,
21130            String path, ParcelFileDescriptor fd) throws RemoteException {
21131
21132        try {
21133            synchronized (this) {
21134                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21135                // its own permission (same as profileControl).
21136                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21137                        != PackageManager.PERMISSION_GRANTED) {
21138                    throw new SecurityException("Requires permission "
21139                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21140                }
21141
21142                if (fd == null) {
21143                    throw new IllegalArgumentException("null fd");
21144                }
21145
21146                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21147                if (proc == null || proc.thread == null) {
21148                    throw new IllegalArgumentException("Unknown process: " + process);
21149                }
21150
21151                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21152                if (!isDebuggable) {
21153                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21154                        throw new SecurityException("Process not debuggable: " + proc);
21155                    }
21156                }
21157
21158                proc.thread.dumpHeap(managed, path, fd);
21159                fd = null;
21160                return true;
21161            }
21162        } catch (RemoteException e) {
21163            throw new IllegalStateException("Process disappeared");
21164        } finally {
21165            if (fd != null) {
21166                try {
21167                    fd.close();
21168                } catch (IOException e) {
21169                }
21170            }
21171        }
21172    }
21173
21174    @Override
21175    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21176            String reportPackage) {
21177        if (processName != null) {
21178            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21179                    "setDumpHeapDebugLimit()");
21180        } else {
21181            synchronized (mPidsSelfLocked) {
21182                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21183                if (proc == null) {
21184                    throw new SecurityException("No process found for calling pid "
21185                            + Binder.getCallingPid());
21186                }
21187                if (!Build.IS_DEBUGGABLE
21188                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21189                    throw new SecurityException("Not running a debuggable build");
21190                }
21191                processName = proc.processName;
21192                uid = proc.uid;
21193                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21194                    throw new SecurityException("Package " + reportPackage + " is not running in "
21195                            + proc);
21196                }
21197            }
21198        }
21199        synchronized (this) {
21200            if (maxMemSize > 0) {
21201                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21202            } else {
21203                if (uid != 0) {
21204                    mMemWatchProcesses.remove(processName, uid);
21205                } else {
21206                    mMemWatchProcesses.getMap().remove(processName);
21207                }
21208            }
21209        }
21210    }
21211
21212    @Override
21213    public void dumpHeapFinished(String path) {
21214        synchronized (this) {
21215            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21216                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21217                        + " does not match last pid " + mMemWatchDumpPid);
21218                return;
21219            }
21220            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21221                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21222                        + " does not match last path " + mMemWatchDumpFile);
21223                return;
21224            }
21225            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21226            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21227        }
21228    }
21229
21230    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21231    public void monitor() {
21232        synchronized (this) { }
21233    }
21234
21235    void onCoreSettingsChange(Bundle settings) {
21236        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21237            ProcessRecord processRecord = mLruProcesses.get(i);
21238            try {
21239                if (processRecord.thread != null) {
21240                    processRecord.thread.setCoreSettings(settings);
21241                }
21242            } catch (RemoteException re) {
21243                /* ignore */
21244            }
21245        }
21246    }
21247
21248    // Multi-user methods
21249
21250    /**
21251     * Start user, if its not already running, but don't bring it to foreground.
21252     */
21253    @Override
21254    public boolean startUserInBackground(final int userId) {
21255        return mUserController.startUser(userId, /* foreground */ false);
21256    }
21257
21258    @Override
21259    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21260        return mUserController.unlockUser(userId, token, secret, listener);
21261    }
21262
21263    @Override
21264    public boolean switchUser(final int targetUserId) {
21265        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21266        UserInfo currentUserInfo;
21267        UserInfo targetUserInfo;
21268        synchronized (this) {
21269            int currentUserId = mUserController.getCurrentUserIdLocked();
21270            currentUserInfo = mUserController.getUserInfo(currentUserId);
21271            targetUserInfo = mUserController.getUserInfo(targetUserId);
21272            if (targetUserInfo == null) {
21273                Slog.w(TAG, "No user info for user #" + targetUserId);
21274                return false;
21275            }
21276            if (!targetUserInfo.supportsSwitchTo()) {
21277                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21278                return false;
21279            }
21280            if (targetUserInfo.isManagedProfile()) {
21281                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21282                return false;
21283            }
21284            mUserController.setTargetUserIdLocked(targetUserId);
21285        }
21286        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21287        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21288        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21289        return true;
21290    }
21291
21292    void scheduleStartProfilesLocked() {
21293        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21294            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21295                    DateUtils.SECOND_IN_MILLIS);
21296        }
21297    }
21298
21299    @Override
21300    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21301        return mUserController.stopUser(userId, force, callback);
21302    }
21303
21304    @Override
21305    public UserInfo getCurrentUser() {
21306        return mUserController.getCurrentUser();
21307    }
21308
21309    @Override
21310    public boolean isUserRunning(int userId, int flags) {
21311        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21312                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21313            String msg = "Permission Denial: isUserRunning() from pid="
21314                    + Binder.getCallingPid()
21315                    + ", uid=" + Binder.getCallingUid()
21316                    + " requires " + INTERACT_ACROSS_USERS;
21317            Slog.w(TAG, msg);
21318            throw new SecurityException(msg);
21319        }
21320        synchronized (this) {
21321            return mUserController.isUserRunningLocked(userId, flags);
21322        }
21323    }
21324
21325    @Override
21326    public int[] getRunningUserIds() {
21327        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21328                != PackageManager.PERMISSION_GRANTED) {
21329            String msg = "Permission Denial: isUserRunning() from pid="
21330                    + Binder.getCallingPid()
21331                    + ", uid=" + Binder.getCallingUid()
21332                    + " requires " + INTERACT_ACROSS_USERS;
21333            Slog.w(TAG, msg);
21334            throw new SecurityException(msg);
21335        }
21336        synchronized (this) {
21337            return mUserController.getStartedUserArrayLocked();
21338        }
21339    }
21340
21341    @Override
21342    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21343        mUserController.registerUserSwitchObserver(observer);
21344    }
21345
21346    @Override
21347    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21348        mUserController.unregisterUserSwitchObserver(observer);
21349    }
21350
21351    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21352        if (info == null) return null;
21353        ApplicationInfo newInfo = new ApplicationInfo(info);
21354        newInfo.initForUser(userId);
21355        return newInfo;
21356    }
21357
21358    public boolean isUserStopped(int userId) {
21359        synchronized (this) {
21360            return mUserController.getStartedUserStateLocked(userId) == null;
21361        }
21362    }
21363
21364    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21365        if (aInfo == null
21366                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21367            return aInfo;
21368        }
21369
21370        ActivityInfo info = new ActivityInfo(aInfo);
21371        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21372        return info;
21373    }
21374
21375    private boolean processSanityChecksLocked(ProcessRecord process) {
21376        if (process == null || process.thread == null) {
21377            return false;
21378        }
21379
21380        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21381        if (!isDebuggable) {
21382            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21383                return false;
21384            }
21385        }
21386
21387        return true;
21388    }
21389
21390    public boolean startBinderTracking() throws RemoteException {
21391        synchronized (this) {
21392            mBinderTransactionTrackingEnabled = true;
21393            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21394            // permission (same as profileControl).
21395            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21396                    != PackageManager.PERMISSION_GRANTED) {
21397                throw new SecurityException("Requires permission "
21398                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21399            }
21400
21401            for (int i = 0; i < mLruProcesses.size(); i++) {
21402                ProcessRecord process = mLruProcesses.get(i);
21403                if (!processSanityChecksLocked(process)) {
21404                    continue;
21405                }
21406                try {
21407                    process.thread.startBinderTracking();
21408                } catch (RemoteException e) {
21409                    Log.v(TAG, "Process disappared");
21410                }
21411            }
21412            return true;
21413        }
21414    }
21415
21416    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21417        try {
21418            synchronized (this) {
21419                mBinderTransactionTrackingEnabled = false;
21420                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21421                // permission (same as profileControl).
21422                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21423                        != PackageManager.PERMISSION_GRANTED) {
21424                    throw new SecurityException("Requires permission "
21425                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21426                }
21427
21428                if (fd == null) {
21429                    throw new IllegalArgumentException("null fd");
21430                }
21431
21432                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21433                pw.println("Binder transaction traces for all processes.\n");
21434                for (ProcessRecord process : mLruProcesses) {
21435                    if (!processSanityChecksLocked(process)) {
21436                        continue;
21437                    }
21438
21439                    pw.println("Traces for process: " + process.processName);
21440                    pw.flush();
21441                    try {
21442                        TransferPipe tp = new TransferPipe();
21443                        try {
21444                            process.thread.stopBinderTrackingAndDump(
21445                                    tp.getWriteFd().getFileDescriptor());
21446                            tp.go(fd.getFileDescriptor());
21447                        } finally {
21448                            tp.kill();
21449                        }
21450                    } catch (IOException e) {
21451                        pw.println("Failure while dumping IPC traces from " + process +
21452                                ".  Exception: " + e);
21453                        pw.flush();
21454                    } catch (RemoteException e) {
21455                        pw.println("Got a RemoteException while dumping IPC traces from " +
21456                                process + ".  Exception: " + e);
21457                        pw.flush();
21458                    }
21459                }
21460                fd = null;
21461                return true;
21462            }
21463        } finally {
21464            if (fd != null) {
21465                try {
21466                    fd.close();
21467                } catch (IOException e) {
21468                }
21469            }
21470        }
21471    }
21472
21473    private final class LocalService extends ActivityManagerInternal {
21474        @Override
21475        public void onWakefulnessChanged(int wakefulness) {
21476            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21477        }
21478
21479        @Override
21480        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21481                String processName, String abiOverride, int uid, Runnable crashHandler) {
21482            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21483                    processName, abiOverride, uid, crashHandler);
21484        }
21485
21486        @Override
21487        public SleepToken acquireSleepToken(String tag) {
21488            Preconditions.checkNotNull(tag);
21489
21490            ComponentName requestedVrService = null;
21491            ComponentName callingVrActivity = null;
21492            int userId = -1;
21493            synchronized (ActivityManagerService.this) {
21494                if (mFocusedActivity != null) {
21495                    requestedVrService = mFocusedActivity.requestedVrComponent;
21496                    callingVrActivity = mFocusedActivity.info.getComponentName();
21497                    userId = mFocusedActivity.userId;
21498                }
21499            }
21500
21501            if (requestedVrService != null) {
21502                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21503            }
21504
21505            synchronized (ActivityManagerService.this) {
21506                SleepTokenImpl token = new SleepTokenImpl(tag);
21507                mSleepTokens.add(token);
21508                updateSleepIfNeededLocked();
21509                return token;
21510            }
21511        }
21512
21513        @Override
21514        public ComponentName getHomeActivityForUser(int userId) {
21515            synchronized (ActivityManagerService.this) {
21516                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21517                return homeActivity == null ? null : homeActivity.realActivity;
21518            }
21519        }
21520
21521        @Override
21522        public void onUserRemoved(int userId) {
21523            synchronized (ActivityManagerService.this) {
21524                ActivityManagerService.this.onUserStoppedLocked(userId);
21525            }
21526        }
21527
21528        @Override
21529        public void onLocalVoiceInteractionStarted(IBinder activity,
21530                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21531            synchronized (ActivityManagerService.this) {
21532                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21533                        voiceSession, voiceInteractor);
21534            }
21535        }
21536
21537        @Override
21538        public void notifyStartingWindowDrawn() {
21539            synchronized (ActivityManagerService.this) {
21540                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21541            }
21542        }
21543
21544        @Override
21545        public void notifyAppTransitionStarting(int reason) {
21546            synchronized (ActivityManagerService.this) {
21547                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21548            }
21549        }
21550
21551        @Override
21552        public void notifyAppTransitionFinished() {
21553            synchronized (ActivityManagerService.this) {
21554                mStackSupervisor.notifyAppTransitionDone();
21555            }
21556        }
21557
21558        @Override
21559        public void notifyAppTransitionCancelled() {
21560            synchronized (ActivityManagerService.this) {
21561                mStackSupervisor.notifyAppTransitionDone();
21562            }
21563        }
21564
21565        @Override
21566        public List<IBinder> getTopVisibleActivities() {
21567            synchronized (ActivityManagerService.this) {
21568                return mStackSupervisor.getTopVisibleActivities();
21569            }
21570        }
21571
21572        @Override
21573        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21574            synchronized (ActivityManagerService.this) {
21575                mStackSupervisor.setDockedStackMinimized(minimized);
21576            }
21577        }
21578
21579        @Override
21580        public void killForegroundAppsForUser(int userHandle) {
21581            synchronized (ActivityManagerService.this) {
21582                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21583                final int NP = mProcessNames.getMap().size();
21584                for (int ip = 0; ip < NP; ip++) {
21585                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21586                    final int NA = apps.size();
21587                    for (int ia = 0; ia < NA; ia++) {
21588                        final ProcessRecord app = apps.valueAt(ia);
21589                        if (app.persistent) {
21590                            // We don't kill persistent processes.
21591                            continue;
21592                        }
21593                        if (app.removed) {
21594                            procs.add(app);
21595                        } else if (app.userId == userHandle && app.foregroundActivities) {
21596                            app.removed = true;
21597                            procs.add(app);
21598                        }
21599                    }
21600                }
21601
21602                final int N = procs.size();
21603                for (int i = 0; i < N; i++) {
21604                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21605                }
21606            }
21607        }
21608
21609        @Override
21610        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21611            if (!(target instanceof PendingIntentRecord)) {
21612                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21613                return;
21614            }
21615            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21616        }
21617    }
21618
21619    private final class SleepTokenImpl extends SleepToken {
21620        private final String mTag;
21621        private final long mAcquireTime;
21622
21623        public SleepTokenImpl(String tag) {
21624            mTag = tag;
21625            mAcquireTime = SystemClock.uptimeMillis();
21626        }
21627
21628        @Override
21629        public void release() {
21630            synchronized (ActivityManagerService.this) {
21631                if (mSleepTokens.remove(this)) {
21632                    updateSleepIfNeededLocked();
21633                }
21634            }
21635        }
21636
21637        @Override
21638        public String toString() {
21639            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21640        }
21641    }
21642
21643    /**
21644     * An implementation of IAppTask, that allows an app to manage its own tasks via
21645     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21646     * only the process that calls getAppTasks() can call the AppTask methods.
21647     */
21648    class AppTaskImpl extends IAppTask.Stub {
21649        private int mTaskId;
21650        private int mCallingUid;
21651
21652        public AppTaskImpl(int taskId, int callingUid) {
21653            mTaskId = taskId;
21654            mCallingUid = callingUid;
21655        }
21656
21657        private void checkCaller() {
21658            if (mCallingUid != Binder.getCallingUid()) {
21659                throw new SecurityException("Caller " + mCallingUid
21660                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21661            }
21662        }
21663
21664        @Override
21665        public void finishAndRemoveTask() {
21666            checkCaller();
21667
21668            synchronized (ActivityManagerService.this) {
21669                long origId = Binder.clearCallingIdentity();
21670                try {
21671                    // We remove the task from recents to preserve backwards
21672                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21673                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21674                    }
21675                } finally {
21676                    Binder.restoreCallingIdentity(origId);
21677                }
21678            }
21679        }
21680
21681        @Override
21682        public ActivityManager.RecentTaskInfo getTaskInfo() {
21683            checkCaller();
21684
21685            synchronized (ActivityManagerService.this) {
21686                long origId = Binder.clearCallingIdentity();
21687                try {
21688                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21689                    if (tr == null) {
21690                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21691                    }
21692                    return createRecentTaskInfoFromTaskRecord(tr);
21693                } finally {
21694                    Binder.restoreCallingIdentity(origId);
21695                }
21696            }
21697        }
21698
21699        @Override
21700        public void moveToFront() {
21701            checkCaller();
21702            // Will bring task to front if it already has a root activity.
21703            final long origId = Binder.clearCallingIdentity();
21704            try {
21705                synchronized (this) {
21706                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21707                }
21708            } finally {
21709                Binder.restoreCallingIdentity(origId);
21710            }
21711        }
21712
21713        @Override
21714        public int startActivity(IBinder whoThread, String callingPackage,
21715                Intent intent, String resolvedType, Bundle bOptions) {
21716            checkCaller();
21717
21718            int callingUser = UserHandle.getCallingUserId();
21719            TaskRecord tr;
21720            IApplicationThread appThread;
21721            synchronized (ActivityManagerService.this) {
21722                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21723                if (tr == null) {
21724                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21725                }
21726                appThread = ApplicationThreadNative.asInterface(whoThread);
21727                if (appThread == null) {
21728                    throw new IllegalArgumentException("Bad app thread " + appThread);
21729                }
21730            }
21731            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21732                    resolvedType, null, null, null, null, 0, 0, null, null,
21733                    null, bOptions, false, callingUser, null, tr);
21734        }
21735
21736        @Override
21737        public void setExcludeFromRecents(boolean exclude) {
21738            checkCaller();
21739
21740            synchronized (ActivityManagerService.this) {
21741                long origId = Binder.clearCallingIdentity();
21742                try {
21743                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21744                    if (tr == null) {
21745                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21746                    }
21747                    Intent intent = tr.getBaseIntent();
21748                    if (exclude) {
21749                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21750                    } else {
21751                        intent.setFlags(intent.getFlags()
21752                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21753                    }
21754                } finally {
21755                    Binder.restoreCallingIdentity(origId);
21756                }
21757            }
21758        }
21759    }
21760
21761    /**
21762     * Kill processes for the user with id userId and that depend on the package named packageName
21763     */
21764    @Override
21765    public void killPackageDependents(String packageName, int userId) {
21766        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21767        if (packageName == null) {
21768            throw new NullPointerException(
21769                    "Cannot kill the dependents of a package without its name.");
21770        }
21771
21772        long callingId = Binder.clearCallingIdentity();
21773        IPackageManager pm = AppGlobals.getPackageManager();
21774        int pkgUid = -1;
21775        try {
21776            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21777        } catch (RemoteException e) {
21778        }
21779        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21780            throw new IllegalArgumentException(
21781                    "Cannot kill dependents of non-existing package " + packageName);
21782        }
21783        try {
21784            synchronized(this) {
21785                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21786                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21787                        "dep: " + packageName);
21788            }
21789        } finally {
21790            Binder.restoreCallingIdentity(callingId);
21791        }
21792    }
21793}
21794