ActivityManagerService.java revision b7380a1c0ce8848ef10ba54966c296b5b505dd30
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.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    private static final class PriorityState {
644        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
645        // the current thread is currently in. When it drops down to zero, we will no longer boost
646        // the thread's priority.
647        private int regionCounter = 0;
648
649        // The thread's previous priority before boosting.
650        private int prevPriority = Integer.MIN_VALUE;
651    }
652
653    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
654        @Override protected PriorityState initialValue() {
655            return new PriorityState();
656        }
657    };
658
659    static void boostPriorityForLockedSection() {
660        int tid = Process.myTid();
661        int prevPriority = Process.getThreadPriority(tid);
662        PriorityState state = sThreadPriorityState.get();
663        if (state.regionCounter == 0 && prevPriority > -2) {
664            state.prevPriority = prevPriority;
665            Process.setThreadPriority(tid, -2);
666        }
667        state.regionCounter++;
668    }
669
670    static void resetPriorityAfterLockedSection() {
671        PriorityState state = sThreadPriorityState.get();
672        state.regionCounter--;
673        if (state.regionCounter == 0 && state.prevPriority > -2) {
674            Process.setThreadPriority(Process.myTid(), state.prevPriority);
675        }
676    }
677
678    public class PendingAssistExtras extends Binder implements Runnable {
679        public final ActivityRecord activity;
680        public final Bundle extras;
681        public final Intent intent;
682        public final String hint;
683        public final IResultReceiver receiver;
684        public final int userHandle;
685        public boolean haveResult = false;
686        public Bundle result = null;
687        public AssistStructure structure = null;
688        public AssistContent content = null;
689        public Bundle receiverExtras;
690
691        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
692                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
693            activity = _activity;
694            extras = _extras;
695            intent = _intent;
696            hint = _hint;
697            receiver = _receiver;
698            receiverExtras = _receiverExtras;
699            userHandle = _userHandle;
700        }
701        @Override
702        public void run() {
703            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
704            synchronized (this) {
705                haveResult = true;
706                notifyAll();
707            }
708            pendingAssistExtrasTimedOut(this);
709        }
710    }
711
712    final ArrayList<PendingAssistExtras> mPendingAssistExtras
713            = new ArrayList<PendingAssistExtras>();
714
715    /**
716     * Process management.
717     */
718    final ProcessList mProcessList = new ProcessList();
719
720    /**
721     * All of the applications we currently have running organized by name.
722     * The keys are strings of the application package name (as
723     * returned by the package manager), and the keys are ApplicationRecord
724     * objects.
725     */
726    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
727
728    /**
729     * Tracking long-term execution of processes to look for abuse and other
730     * bad app behavior.
731     */
732    final ProcessStatsService mProcessStats;
733
734    /**
735     * The currently running isolated processes.
736     */
737    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
738
739    /**
740     * Counter for assigning isolated process uids, to avoid frequently reusing the
741     * same ones.
742     */
743    int mNextIsolatedProcessUid = 0;
744
745    /**
746     * The currently running heavy-weight process, if any.
747     */
748    ProcessRecord mHeavyWeightProcess = null;
749
750    /**
751     * All of the processes we currently have running organized by pid.
752     * The keys are the pid running the application.
753     *
754     * <p>NOTE: This object is protected by its own lock, NOT the global
755     * activity manager lock!
756     */
757    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
758
759    /**
760     * All of the processes that have been forced to be foreground.  The key
761     * is the pid of the caller who requested it (we hold a death
762     * link on it).
763     */
764    abstract class ForegroundToken implements IBinder.DeathRecipient {
765        int pid;
766        IBinder token;
767    }
768    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
769
770    /**
771     * List of records for processes that someone had tried to start before the
772     * system was ready.  We don't start them at that point, but ensure they
773     * are started by the time booting is complete.
774     */
775    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of persistent applications that are in the process
779     * of being started.
780     */
781    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Processes that are being forcibly torn down.
785     */
786    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
787
788    /**
789     * List of running applications, sorted by recent usage.
790     * The first entry in the list is the least recently used.
791     */
792    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
793
794    /**
795     * Where in mLruProcesses that the processes hosting activities start.
796     */
797    int mLruProcessActivityStart = 0;
798
799    /**
800     * Where in mLruProcesses that the processes hosting services start.
801     * This is after (lower index) than mLruProcessesActivityStart.
802     */
803    int mLruProcessServiceStart = 0;
804
805    /**
806     * List of processes that should gc as soon as things are idle.
807     */
808    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
809
810    /**
811     * Processes we want to collect PSS data from.
812     */
813    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
814
815    private boolean mBinderTransactionTrackingEnabled = false;
816
817    /**
818     * Last time we requested PSS data of all processes.
819     */
820    long mLastFullPssTime = SystemClock.uptimeMillis();
821
822    /**
823     * If set, the next time we collect PSS data we should do a full collection
824     * with data from native processes and the kernel.
825     */
826    boolean mFullPssPending = false;
827
828    /**
829     * This is the process holding what we currently consider to be
830     * the "home" activity.
831     */
832    ProcessRecord mHomeProcess;
833
834    /**
835     * This is the process holding the activity the user last visited that
836     * is in a different process from the one they are currently in.
837     */
838    ProcessRecord mPreviousProcess;
839
840    /**
841     * The time at which the previous process was last visible.
842     */
843    long mPreviousProcessVisibleTime;
844
845    /**
846     * Track all uids that have actively running processes.
847     */
848    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
849
850    /**
851     * This is for verifying the UID report flow.
852     */
853    static final boolean VALIDATE_UID_STATES = true;
854    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
855
856    /**
857     * Packages that the user has asked to have run in screen size
858     * compatibility mode instead of filling the screen.
859     */
860    final CompatModePackages mCompatModePackages;
861
862    /**
863     * Set of IntentSenderRecord objects that are currently active.
864     */
865    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
866            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
867
868    /**
869     * Fingerprints (hashCode()) of stack traces that we've
870     * already logged DropBox entries for.  Guarded by itself.  If
871     * something (rogue user app) forces this over
872     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
873     */
874    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
875    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
876
877    /**
878     * Strict Mode background batched logging state.
879     *
880     * The string buffer is guarded by itself, and its lock is also
881     * used to determine if another batched write is already
882     * in-flight.
883     */
884    private final StringBuilder mStrictModeBuffer = new StringBuilder();
885
886    /**
887     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
888     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
889     */
890    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
891
892    /**
893     * Resolver for broadcast intents to registered receivers.
894     * Holds BroadcastFilter (subclass of IntentFilter).
895     */
896    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
897            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
898        @Override
899        protected boolean allowFilterResult(
900                BroadcastFilter filter, List<BroadcastFilter> dest) {
901            IBinder target = filter.receiverList.receiver.asBinder();
902            for (int i = dest.size() - 1; i >= 0; i--) {
903                if (dest.get(i).receiverList.receiver.asBinder() == target) {
904                    return false;
905                }
906            }
907            return true;
908        }
909
910        @Override
911        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
912            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
913                    || userId == filter.owningUserId) {
914                return super.newResult(filter, match, userId);
915            }
916            return null;
917        }
918
919        @Override
920        protected BroadcastFilter[] newArray(int size) {
921            return new BroadcastFilter[size];
922        }
923
924        @Override
925        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
926            return packageName.equals(filter.packageName);
927        }
928    };
929
930    /**
931     * State of all active sticky broadcasts per user.  Keys are the action of the
932     * sticky Intent, values are an ArrayList of all broadcasted intents with
933     * that action (which should usually be one).  The SparseArray is keyed
934     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
935     * for stickies that are sent to all users.
936     */
937    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
938            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
939
940    final ActiveServices mServices;
941
942    final static class Association {
943        final int mSourceUid;
944        final String mSourceProcess;
945        final int mTargetUid;
946        final ComponentName mTargetComponent;
947        final String mTargetProcess;
948
949        int mCount;
950        long mTime;
951
952        int mNesting;
953        long mStartTime;
954
955        // states of the source process when the bind occurred.
956        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
957        long mLastStateUptime;
958        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
959                - ActivityManager.MIN_PROCESS_STATE+1];
960
961        Association(int sourceUid, String sourceProcess, int targetUid,
962                ComponentName targetComponent, String targetProcess) {
963            mSourceUid = sourceUid;
964            mSourceProcess = sourceProcess;
965            mTargetUid = targetUid;
966            mTargetComponent = targetComponent;
967            mTargetProcess = targetProcess;
968        }
969    }
970
971    /**
972     * When service association tracking is enabled, this is all of the associations we
973     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
974     * -> association data.
975     */
976    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
977            mAssociations = new SparseArray<>();
978    boolean mTrackingAssociations;
979
980    /**
981     * Backup/restore process management
982     */
983    String mBackupAppName = null;
984    BackupRecord mBackupTarget = null;
985
986    final ProviderMap mProviderMap;
987
988    /**
989     * List of content providers who have clients waiting for them.  The
990     * application is currently being launched and the provider will be
991     * removed from this list once it is published.
992     */
993    final ArrayList<ContentProviderRecord> mLaunchingProviders
994            = new ArrayList<ContentProviderRecord>();
995
996    /**
997     * File storing persisted {@link #mGrantedUriPermissions}.
998     */
999    private final AtomicFile mGrantFile;
1000
1001    /** XML constants used in {@link #mGrantFile} */
1002    private static final String TAG_URI_GRANTS = "uri-grants";
1003    private static final String TAG_URI_GRANT = "uri-grant";
1004    private static final String ATTR_USER_HANDLE = "userHandle";
1005    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1006    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1007    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1008    private static final String ATTR_TARGET_PKG = "targetPkg";
1009    private static final String ATTR_URI = "uri";
1010    private static final String ATTR_MODE_FLAGS = "modeFlags";
1011    private static final String ATTR_CREATED_TIME = "createdTime";
1012    private static final String ATTR_PREFIX = "prefix";
1013
1014    /**
1015     * Global set of specific {@link Uri} permissions that have been granted.
1016     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1017     * to {@link UriPermission#uri} to {@link UriPermission}.
1018     */
1019    @GuardedBy("this")
1020    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1021            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1022
1023    public static class GrantUri {
1024        public final int sourceUserId;
1025        public final Uri uri;
1026        public boolean prefix;
1027
1028        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1029            this.sourceUserId = sourceUserId;
1030            this.uri = uri;
1031            this.prefix = prefix;
1032        }
1033
1034        @Override
1035        public int hashCode() {
1036            int hashCode = 1;
1037            hashCode = 31 * hashCode + sourceUserId;
1038            hashCode = 31 * hashCode + uri.hashCode();
1039            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1040            return hashCode;
1041        }
1042
1043        @Override
1044        public boolean equals(Object o) {
1045            if (o instanceof GrantUri) {
1046                GrantUri other = (GrantUri) o;
1047                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1048                        && prefix == other.prefix;
1049            }
1050            return false;
1051        }
1052
1053        @Override
1054        public String toString() {
1055            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1056            if (prefix) result += " [prefix]";
1057            return result;
1058        }
1059
1060        public String toSafeString() {
1061            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1062            if (prefix) result += " [prefix]";
1063            return result;
1064        }
1065
1066        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1067            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1068                    ContentProvider.getUriWithoutUserId(uri), false);
1069        }
1070    }
1071
1072    CoreSettingsObserver mCoreSettingsObserver;
1073
1074    FontScaleSettingObserver mFontScaleSettingObserver;
1075
1076    private final class FontScaleSettingObserver extends ContentObserver {
1077        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1078
1079        public FontScaleSettingObserver() {
1080            super(mHandler);
1081            ContentResolver resolver = mContext.getContentResolver();
1082            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1083        }
1084
1085        @Override
1086        public void onChange(boolean selfChange, Uri uri) {
1087            if (mFontScaleUri.equals(uri)) {
1088                updateFontScaleIfNeeded();
1089            }
1090        }
1091    }
1092
1093    /**
1094     * Thread-local storage used to carry caller permissions over through
1095     * indirect content-provider access.
1096     */
1097    private class Identity {
1098        public final IBinder token;
1099        public final int pid;
1100        public final int uid;
1101
1102        Identity(IBinder _token, int _pid, int _uid) {
1103            token = _token;
1104            pid = _pid;
1105            uid = _uid;
1106        }
1107    }
1108
1109    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1110
1111    /**
1112     * All information we have collected about the runtime performance of
1113     * any user id that can impact battery performance.
1114     */
1115    final BatteryStatsService mBatteryStatsService;
1116
1117    /**
1118     * Information about component usage
1119     */
1120    UsageStatsManagerInternal mUsageStatsService;
1121
1122    /**
1123     * Access to DeviceIdleController service.
1124     */
1125    DeviceIdleController.LocalService mLocalDeviceIdleController;
1126
1127    /**
1128     * Information about and control over application operations
1129     */
1130    final AppOpsService mAppOpsService;
1131
1132    /**
1133     * Current configuration information.  HistoryRecord objects are given
1134     * a reference to this object to indicate which configuration they are
1135     * currently running in, so this object must be kept immutable.
1136     */
1137    Configuration mConfiguration = new Configuration();
1138
1139    /**
1140     * Current sequencing integer of the configuration, for skipping old
1141     * configurations.
1142     */
1143    int mConfigurationSeq = 0;
1144
1145    boolean mSuppressResizeConfigChanges = false;
1146
1147    /**
1148     * Hardware-reported OpenGLES version.
1149     */
1150    final int GL_ES_VERSION;
1151
1152    /**
1153     * List of initialization arguments to pass to all processes when binding applications to them.
1154     * For example, references to the commonly used services.
1155     */
1156    HashMap<String, IBinder> mAppBindArgs;
1157
1158    /**
1159     * Temporary to avoid allocations.  Protected by main lock.
1160     */
1161    final StringBuilder mStringBuilder = new StringBuilder(256);
1162
1163    /**
1164     * Used to control how we initialize the service.
1165     */
1166    ComponentName mTopComponent;
1167    String mTopAction = Intent.ACTION_MAIN;
1168    String mTopData;
1169
1170    volatile boolean mProcessesReady = false;
1171    volatile boolean mSystemReady = false;
1172    volatile boolean mOnBattery = false;
1173    volatile int mFactoryTest;
1174
1175    @GuardedBy("this") boolean mBooting = false;
1176    @GuardedBy("this") boolean mCallFinishBooting = false;
1177    @GuardedBy("this") boolean mBootAnimationComplete = false;
1178    @GuardedBy("this") boolean mLaunchWarningShown = false;
1179    @GuardedBy("this") boolean mCheckedForSetup = false;
1180
1181    Context mContext;
1182
1183    /**
1184     * The time at which we will allow normal application switches again,
1185     * after a call to {@link #stopAppSwitches()}.
1186     */
1187    long mAppSwitchesAllowedTime;
1188
1189    /**
1190     * This is set to true after the first switch after mAppSwitchesAllowedTime
1191     * is set; any switches after that will clear the time.
1192     */
1193    boolean mDidAppSwitch;
1194
1195    /**
1196     * Last time (in realtime) at which we checked for power usage.
1197     */
1198    long mLastPowerCheckRealtime;
1199
1200    /**
1201     * Last time (in uptime) at which we checked for power usage.
1202     */
1203    long mLastPowerCheckUptime;
1204
1205    /**
1206     * Set while we are wanting to sleep, to prevent any
1207     * activities from being started/resumed.
1208     */
1209    private boolean mSleeping = false;
1210
1211    /**
1212     * The process state used for processes that are running the top activities.
1213     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1214     */
1215    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1216
1217    /**
1218     * Set while we are running a voice interaction.  This overrides
1219     * sleeping while it is active.
1220     */
1221    private IVoiceInteractionSession mRunningVoice;
1222
1223    /**
1224     * For some direct access we need to power manager.
1225     */
1226    PowerManagerInternal mLocalPowerManager;
1227
1228    /**
1229     * We want to hold a wake lock while running a voice interaction session, since
1230     * this may happen with the screen off and we need to keep the CPU running to
1231     * be able to continue to interact with the user.
1232     */
1233    PowerManager.WakeLock mVoiceWakeLock;
1234
1235    /**
1236     * State of external calls telling us if the device is awake or asleep.
1237     */
1238    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1239
1240    /**
1241     * A list of tokens that cause the top activity to be put to sleep.
1242     * They are used by components that may hide and block interaction with underlying
1243     * activities.
1244     */
1245    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1246
1247    static final int LOCK_SCREEN_HIDDEN = 0;
1248    static final int LOCK_SCREEN_LEAVING = 1;
1249    static final int LOCK_SCREEN_SHOWN = 2;
1250    /**
1251     * State of external call telling us if the lock screen is shown.
1252     */
1253    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1254
1255    /**
1256     * Set if we are shutting down the system, similar to sleeping.
1257     */
1258    boolean mShuttingDown = false;
1259
1260    /**
1261     * Current sequence id for oom_adj computation traversal.
1262     */
1263    int mAdjSeq = 0;
1264
1265    /**
1266     * Current sequence id for process LRU updating.
1267     */
1268    int mLruSeq = 0;
1269
1270    /**
1271     * Keep track of the non-cached/empty process we last found, to help
1272     * determine how to distribute cached/empty processes next time.
1273     */
1274    int mNumNonCachedProcs = 0;
1275
1276    /**
1277     * Keep track of the number of cached hidden procs, to balance oom adj
1278     * distribution between those and empty procs.
1279     */
1280    int mNumCachedHiddenProcs = 0;
1281
1282    /**
1283     * Keep track of the number of service processes we last found, to
1284     * determine on the next iteration which should be B services.
1285     */
1286    int mNumServiceProcs = 0;
1287    int mNewNumAServiceProcs = 0;
1288    int mNewNumServiceProcs = 0;
1289
1290    /**
1291     * Allow the current computed overall memory level of the system to go down?
1292     * This is set to false when we are killing processes for reasons other than
1293     * memory management, so that the now smaller process list will not be taken as
1294     * an indication that memory is tighter.
1295     */
1296    boolean mAllowLowerMemLevel = false;
1297
1298    /**
1299     * The last computed memory level, for holding when we are in a state that
1300     * processes are going away for other reasons.
1301     */
1302    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1303
1304    /**
1305     * The last total number of process we have, to determine if changes actually look
1306     * like a shrinking number of process due to lower RAM.
1307     */
1308    int mLastNumProcesses;
1309
1310    /**
1311     * The uptime of the last time we performed idle maintenance.
1312     */
1313    long mLastIdleTime = SystemClock.uptimeMillis();
1314
1315    /**
1316     * Total time spent with RAM that has been added in the past since the last idle time.
1317     */
1318    long mLowRamTimeSinceLastIdle = 0;
1319
1320    /**
1321     * If RAM is currently low, when that horrible situation started.
1322     */
1323    long mLowRamStartTime = 0;
1324
1325    /**
1326     * For reporting to battery stats the current top application.
1327     */
1328    private String mCurResumedPackage = null;
1329    private int mCurResumedUid = -1;
1330
1331    /**
1332     * For reporting to battery stats the apps currently running foreground
1333     * service.  The ProcessMap is package/uid tuples; each of these contain
1334     * an array of the currently foreground processes.
1335     */
1336    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1337            = new ProcessMap<ArrayList<ProcessRecord>>();
1338
1339    /**
1340     * This is set if we had to do a delayed dexopt of an app before launching
1341     * it, to increase the ANR timeouts in that case.
1342     */
1343    boolean mDidDexOpt;
1344
1345    /**
1346     * Set if the systemServer made a call to enterSafeMode.
1347     */
1348    boolean mSafeMode;
1349
1350    /**
1351     * If true, we are running under a test environment so will sample PSS from processes
1352     * much more rapidly to try to collect better data when the tests are rapidly
1353     * running through apps.
1354     */
1355    boolean mTestPssMode = false;
1356
1357    String mDebugApp = null;
1358    boolean mWaitForDebugger = false;
1359    boolean mDebugTransient = false;
1360    String mOrigDebugApp = null;
1361    boolean mOrigWaitForDebugger = false;
1362    boolean mAlwaysFinishActivities = false;
1363    boolean mLenientBackgroundCheck = false;
1364    boolean mForceResizableActivities;
1365    boolean mSupportsMultiWindow;
1366    boolean mSupportsFreeformWindowManagement;
1367    boolean mSupportsPictureInPicture;
1368    boolean mSupportsLeanbackOnly;
1369    Rect mDefaultPinnedStackBounds;
1370    IActivityController mController = null;
1371    boolean mControllerIsAMonkey = false;
1372    String mProfileApp = null;
1373    ProcessRecord mProfileProc = null;
1374    String mProfileFile;
1375    ParcelFileDescriptor mProfileFd;
1376    int mSamplingInterval = 0;
1377    boolean mAutoStopProfiler = false;
1378    int mProfileType = 0;
1379    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1380    String mMemWatchDumpProcName;
1381    String mMemWatchDumpFile;
1382    int mMemWatchDumpPid;
1383    int mMemWatchDumpUid;
1384    String mTrackAllocationApp = null;
1385    String mNativeDebuggingApp = null;
1386
1387    final long[] mTmpLong = new long[2];
1388
1389    static final class ProcessChangeItem {
1390        static final int CHANGE_ACTIVITIES = 1<<0;
1391        static final int CHANGE_PROCESS_STATE = 1<<1;
1392        int changes;
1393        int uid;
1394        int pid;
1395        int processState;
1396        boolean foregroundActivities;
1397    }
1398
1399    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1400    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1401
1402    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1403    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1404
1405    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1406    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1407
1408    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1409    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1410
1411    /**
1412     * Runtime CPU use collection thread.  This object's lock is used to
1413     * perform synchronization with the thread (notifying it to run).
1414     */
1415    final Thread mProcessCpuThread;
1416
1417    /**
1418     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1419     * Must acquire this object's lock when accessing it.
1420     * NOTE: this lock will be held while doing long operations (trawling
1421     * through all processes in /proc), so it should never be acquired by
1422     * any critical paths such as when holding the main activity manager lock.
1423     */
1424    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1425            MONITOR_THREAD_CPU_USAGE);
1426    final AtomicLong mLastCpuTime = new AtomicLong(0);
1427    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1428
1429    long mLastWriteTime = 0;
1430
1431    /**
1432     * Used to retain an update lock when the foreground activity is in
1433     * immersive mode.
1434     */
1435    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1436
1437    /**
1438     * Set to true after the system has finished booting.
1439     */
1440    boolean mBooted = false;
1441
1442    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1443    int mProcessLimitOverride = -1;
1444
1445    WindowManagerService mWindowManager;
1446    final ActivityThread mSystemThread;
1447
1448    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1449        final ProcessRecord mApp;
1450        final int mPid;
1451        final IApplicationThread mAppThread;
1452
1453        AppDeathRecipient(ProcessRecord app, int pid,
1454                IApplicationThread thread) {
1455            if (DEBUG_ALL) Slog.v(
1456                TAG, "New death recipient " + this
1457                + " for thread " + thread.asBinder());
1458            mApp = app;
1459            mPid = pid;
1460            mAppThread = thread;
1461        }
1462
1463        @Override
1464        public void binderDied() {
1465            if (DEBUG_ALL) Slog.v(
1466                TAG, "Death received in " + this
1467                + " for thread " + mAppThread.asBinder());
1468            synchronized(ActivityManagerService.this) {
1469                appDiedLocked(mApp, mPid, mAppThread, true);
1470            }
1471        }
1472    }
1473
1474    static final int SHOW_ERROR_UI_MSG = 1;
1475    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1476    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1477    static final int UPDATE_CONFIGURATION_MSG = 4;
1478    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1479    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1480    static final int SERVICE_TIMEOUT_MSG = 12;
1481    static final int UPDATE_TIME_ZONE = 13;
1482    static final int SHOW_UID_ERROR_UI_MSG = 14;
1483    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1484    static final int PROC_START_TIMEOUT_MSG = 20;
1485    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1486    static final int KILL_APPLICATION_MSG = 22;
1487    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1488    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1489    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1490    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1491    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1492    static final int CLEAR_DNS_CACHE_MSG = 28;
1493    static final int UPDATE_HTTP_PROXY_MSG = 29;
1494    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1495    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1496    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1497    static final int REPORT_MEM_USAGE_MSG = 33;
1498    static final int REPORT_USER_SWITCH_MSG = 34;
1499    static final int CONTINUE_USER_SWITCH_MSG = 35;
1500    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1501    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1502    static final int PERSIST_URI_GRANTS_MSG = 38;
1503    static final int REQUEST_ALL_PSS_MSG = 39;
1504    static final int START_PROFILES_MSG = 40;
1505    static final int UPDATE_TIME = 41;
1506    static final int SYSTEM_USER_START_MSG = 42;
1507    static final int SYSTEM_USER_CURRENT_MSG = 43;
1508    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1509    static final int FINISH_BOOTING_MSG = 45;
1510    static final int START_USER_SWITCH_UI_MSG = 46;
1511    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1512    static final int DISMISS_DIALOG_UI_MSG = 48;
1513    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1514    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1515    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1516    static final int DELETE_DUMPHEAP_MSG = 52;
1517    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1518    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1519    static final int REPORT_TIME_TRACKER_MSG = 55;
1520    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1521    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1522    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1523    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1524    static final int IDLE_UIDS_MSG = 60;
1525    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1526    static final int LOG_STACK_STATE = 62;
1527    static final int VR_MODE_CHANGE_MSG = 63;
1528    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1529    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1530    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1531    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1532    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1533    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1534    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1535
1536    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1537    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1538    static final int FIRST_COMPAT_MODE_MSG = 300;
1539    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1540
1541    static ServiceThread sKillThread = null;
1542    static KillHandler sKillHandler = null;
1543
1544    CompatModeDialog mCompatModeDialog;
1545    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1546    long mLastMemUsageReportTime = 0;
1547
1548    /**
1549     * Flag whether the current user is a "monkey", i.e. whether
1550     * the UI is driven by a UI automation tool.
1551     */
1552    private boolean mUserIsMonkey;
1553
1554    /** Flag whether the device has a Recents UI */
1555    boolean mHasRecents;
1556
1557    /** The dimensions of the thumbnails in the Recents UI. */
1558    int mThumbnailWidth;
1559    int mThumbnailHeight;
1560    float mFullscreenThumbnailScale;
1561
1562    final ServiceThread mHandlerThread;
1563    final MainHandler mHandler;
1564    final UiHandler mUiHandler;
1565
1566    PackageManagerInternal mPackageManagerInt;
1567
1568    // VoiceInteraction session ID that changes for each new request except when
1569    // being called for multiwindow assist in a single session.
1570    private int mViSessionId = 1000;
1571
1572    final class KillHandler extends Handler {
1573        static final int KILL_PROCESS_GROUP_MSG = 4000;
1574
1575        public KillHandler(Looper looper) {
1576            super(looper, null, true);
1577        }
1578
1579        @Override
1580        public void handleMessage(Message msg) {
1581            switch (msg.what) {
1582                case KILL_PROCESS_GROUP_MSG:
1583                {
1584                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1585                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1586                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1587                }
1588                break;
1589
1590                default:
1591                    super.handleMessage(msg);
1592            }
1593        }
1594    }
1595
1596    final class UiHandler extends Handler {
1597        public UiHandler() {
1598            super(com.android.server.UiThread.get().getLooper(), null, true);
1599        }
1600
1601        @Override
1602        public void handleMessage(Message msg) {
1603            switch (msg.what) {
1604            case SHOW_ERROR_UI_MSG: {
1605                mAppErrors.handleShowAppErrorUi(msg);
1606                ensureBootCompleted();
1607            } break;
1608            case SHOW_NOT_RESPONDING_UI_MSG: {
1609                mAppErrors.handleShowAnrUi(msg);
1610                ensureBootCompleted();
1611            } break;
1612            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1613                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1614                synchronized (ActivityManagerService.this) {
1615                    ProcessRecord proc = (ProcessRecord) data.get("app");
1616                    if (proc == null) {
1617                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1618                        break;
1619                    }
1620                    if (proc.crashDialog != null) {
1621                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1622                        return;
1623                    }
1624                    AppErrorResult res = (AppErrorResult) data.get("result");
1625                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1626                        Dialog d = new StrictModeViolationDialog(mContext,
1627                                ActivityManagerService.this, res, proc);
1628                        d.show();
1629                        proc.crashDialog = d;
1630                    } else {
1631                        // The device is asleep, so just pretend that the user
1632                        // saw a crash dialog and hit "force quit".
1633                        res.set(0);
1634                    }
1635                }
1636                ensureBootCompleted();
1637            } break;
1638            case SHOW_FACTORY_ERROR_UI_MSG: {
1639                Dialog d = new FactoryErrorDialog(
1640                    mContext, msg.getData().getCharSequence("msg"));
1641                d.show();
1642                ensureBootCompleted();
1643            } break;
1644            case WAIT_FOR_DEBUGGER_UI_MSG: {
1645                synchronized (ActivityManagerService.this) {
1646                    ProcessRecord app = (ProcessRecord)msg.obj;
1647                    if (msg.arg1 != 0) {
1648                        if (!app.waitedForDebugger) {
1649                            Dialog d = new AppWaitingForDebuggerDialog(
1650                                    ActivityManagerService.this,
1651                                    mContext, app);
1652                            app.waitDialog = d;
1653                            app.waitedForDebugger = true;
1654                            d.show();
1655                        }
1656                    } else {
1657                        if (app.waitDialog != null) {
1658                            app.waitDialog.dismiss();
1659                            app.waitDialog = null;
1660                        }
1661                    }
1662                }
1663            } break;
1664            case SHOW_UID_ERROR_UI_MSG: {
1665                if (mShowDialogs) {
1666                    AlertDialog d = new BaseErrorDialog(mContext);
1667                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1668                    d.setCancelable(false);
1669                    d.setTitle(mContext.getText(R.string.android_system_label));
1670                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1671                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1672                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1673                    d.show();
1674                }
1675            } break;
1676            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1677                if (mShowDialogs) {
1678                    AlertDialog d = new BaseErrorDialog(mContext);
1679                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1680                    d.setCancelable(false);
1681                    d.setTitle(mContext.getText(R.string.android_system_label));
1682                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1683                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1684                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1685                    d.show();
1686                }
1687            } break;
1688            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1689                synchronized (ActivityManagerService.this) {
1690                    ActivityRecord ar = (ActivityRecord) msg.obj;
1691                    if (mCompatModeDialog != null) {
1692                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1693                                ar.info.applicationInfo.packageName)) {
1694                            return;
1695                        }
1696                        mCompatModeDialog.dismiss();
1697                        mCompatModeDialog = null;
1698                    }
1699                    if (ar != null && false) {
1700                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1701                                ar.packageName)) {
1702                            int mode = mCompatModePackages.computeCompatModeLocked(
1703                                    ar.info.applicationInfo);
1704                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1705                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1706                                mCompatModeDialog = new CompatModeDialog(
1707                                        ActivityManagerService.this, mContext,
1708                                        ar.info.applicationInfo);
1709                                mCompatModeDialog.show();
1710                            }
1711                        }
1712                    }
1713                }
1714                break;
1715            }
1716            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1717                synchronized (ActivityManagerService.this) {
1718                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1719                    if (mUnsupportedDisplaySizeDialog != null) {
1720                        mUnsupportedDisplaySizeDialog.dismiss();
1721                        mUnsupportedDisplaySizeDialog = null;
1722                    }
1723                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1724                            ar.packageName)) {
1725                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1726                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1727                        mUnsupportedDisplaySizeDialog.show();
1728                    }
1729                }
1730                break;
1731            }
1732            case START_USER_SWITCH_UI_MSG: {
1733                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1734                break;
1735            }
1736            case DISMISS_DIALOG_UI_MSG: {
1737                final Dialog d = (Dialog) msg.obj;
1738                d.dismiss();
1739                break;
1740            }
1741            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1742                dispatchProcessesChanged();
1743                break;
1744            }
1745            case DISPATCH_PROCESS_DIED_UI_MSG: {
1746                final int pid = msg.arg1;
1747                final int uid = msg.arg2;
1748                dispatchProcessDied(pid, uid);
1749                break;
1750            }
1751            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1752                dispatchUidsChanged();
1753            } break;
1754            }
1755        }
1756    }
1757
1758    final class MainHandler extends Handler {
1759        public MainHandler(Looper looper) {
1760            super(looper, null, true);
1761        }
1762
1763        @Override
1764        public void handleMessage(Message msg) {
1765            switch (msg.what) {
1766            case UPDATE_CONFIGURATION_MSG: {
1767                final ContentResolver resolver = mContext.getContentResolver();
1768                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1769                        msg.arg1);
1770            } break;
1771            case GC_BACKGROUND_PROCESSES_MSG: {
1772                synchronized (ActivityManagerService.this) {
1773                    performAppGcsIfAppropriateLocked();
1774                }
1775            } break;
1776            case SERVICE_TIMEOUT_MSG: {
1777                if (mDidDexOpt) {
1778                    mDidDexOpt = false;
1779                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1780                    nmsg.obj = msg.obj;
1781                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1782                    return;
1783                }
1784                mServices.serviceTimeout((ProcessRecord)msg.obj);
1785            } break;
1786            case UPDATE_TIME_ZONE: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimeZone();
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799            } break;
1800            case CLEAR_DNS_CACHE_MSG: {
1801                synchronized (ActivityManagerService.this) {
1802                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1803                        ProcessRecord r = mLruProcesses.get(i);
1804                        if (r.thread != null) {
1805                            try {
1806                                r.thread.clearDnsCache();
1807                            } catch (RemoteException ex) {
1808                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1809                            }
1810                        }
1811                    }
1812                }
1813            } break;
1814            case UPDATE_HTTP_PROXY_MSG: {
1815                ProxyInfo proxy = (ProxyInfo)msg.obj;
1816                String host = "";
1817                String port = "";
1818                String exclList = "";
1819                Uri pacFileUrl = Uri.EMPTY;
1820                if (proxy != null) {
1821                    host = proxy.getHost();
1822                    port = Integer.toString(proxy.getPort());
1823                    exclList = proxy.getExclusionListAsString();
1824                    pacFileUrl = proxy.getPacFileUrl();
1825                }
1826                synchronized (ActivityManagerService.this) {
1827                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1828                        ProcessRecord r = mLruProcesses.get(i);
1829                        if (r.thread != null) {
1830                            try {
1831                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1832                            } catch (RemoteException ex) {
1833                                Slog.w(TAG, "Failed to update http proxy for: " +
1834                                        r.info.processName);
1835                            }
1836                        }
1837                    }
1838                }
1839            } break;
1840            case PROC_START_TIMEOUT_MSG: {
1841                if (mDidDexOpt) {
1842                    mDidDexOpt = false;
1843                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1844                    nmsg.obj = msg.obj;
1845                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1846                    return;
1847                }
1848                ProcessRecord app = (ProcessRecord)msg.obj;
1849                synchronized (ActivityManagerService.this) {
1850                    processStartTimedOutLocked(app);
1851                }
1852            } break;
1853            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1854                ProcessRecord app = (ProcessRecord)msg.obj;
1855                synchronized (ActivityManagerService.this) {
1856                    processContentProviderPublishTimedOutLocked(app);
1857                }
1858            } break;
1859            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1862                }
1863            } break;
1864            case KILL_APPLICATION_MSG: {
1865                synchronized (ActivityManagerService.this) {
1866                    final int appId = msg.arg1;
1867                    final int userId = msg.arg2;
1868                    Bundle bundle = (Bundle)msg.obj;
1869                    String pkg = bundle.getString("pkg");
1870                    String reason = bundle.getString("reason");
1871                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1872                            false, userId, reason);
1873                }
1874            } break;
1875            case FINALIZE_PENDING_INTENT_MSG: {
1876                ((PendingIntentRecord)msg.obj).completeFinalize();
1877            } break;
1878            case POST_HEAVY_NOTIFICATION_MSG: {
1879                INotificationManager inm = NotificationManager.getService();
1880                if (inm == null) {
1881                    return;
1882                }
1883
1884                ActivityRecord root = (ActivityRecord)msg.obj;
1885                ProcessRecord process = root.app;
1886                if (process == null) {
1887                    return;
1888                }
1889
1890                try {
1891                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1892                    String text = mContext.getString(R.string.heavy_weight_notification,
1893                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1894                    Notification notification = new Notification.Builder(context)
1895                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1896                            .setWhen(0)
1897                            .setOngoing(true)
1898                            .setTicker(text)
1899                            .setColor(mContext.getColor(
1900                                    com.android.internal.R.color.system_notification_accent_color))
1901                            .setContentTitle(text)
1902                            .setContentText(
1903                                    mContext.getText(R.string.heavy_weight_notification_detail))
1904                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1905                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1906                                    new UserHandle(root.userId)))
1907                            .build();
1908                    try {
1909                        int[] outId = new int[1];
1910                        inm.enqueueNotificationWithTag("android", "android", null,
1911                                R.string.heavy_weight_notification,
1912                                notification, outId, root.userId);
1913                    } catch (RuntimeException e) {
1914                        Slog.w(ActivityManagerService.TAG,
1915                                "Error showing notification for heavy-weight app", e);
1916                    } catch (RemoteException e) {
1917                    }
1918                } catch (NameNotFoundException e) {
1919                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1920                }
1921            } break;
1922            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1923                INotificationManager inm = NotificationManager.getService();
1924                if (inm == null) {
1925                    return;
1926                }
1927                try {
1928                    inm.cancelNotificationWithTag("android", null,
1929                            R.string.heavy_weight_notification,  msg.arg1);
1930                } catch (RuntimeException e) {
1931                    Slog.w(ActivityManagerService.TAG,
1932                            "Error canceling notification for service", e);
1933                } catch (RemoteException e) {
1934                }
1935            } break;
1936            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1937                synchronized (ActivityManagerService.this) {
1938                    checkExcessivePowerUsageLocked(true);
1939                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1940                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1941                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1942                }
1943            } break;
1944            case REPORT_MEM_USAGE_MSG: {
1945                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1946                Thread thread = new Thread() {
1947                    @Override public void run() {
1948                        reportMemUsage(memInfos);
1949                    }
1950                };
1951                thread.start();
1952                break;
1953            }
1954            case REPORT_USER_SWITCH_MSG: {
1955                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1956                break;
1957            }
1958            case CONTINUE_USER_SWITCH_MSG: {
1959                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1960                break;
1961            }
1962            case USER_SWITCH_TIMEOUT_MSG: {
1963                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964                break;
1965            }
1966            case IMMERSIVE_MODE_LOCK_MSG: {
1967                final boolean nextState = (msg.arg1 != 0);
1968                if (mUpdateLock.isHeld() != nextState) {
1969                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1970                            "Applying new update lock state '" + nextState
1971                            + "' for " + (ActivityRecord)msg.obj);
1972                    if (nextState) {
1973                        mUpdateLock.acquire();
1974                    } else {
1975                        mUpdateLock.release();
1976                    }
1977                }
1978                break;
1979            }
1980            case PERSIST_URI_GRANTS_MSG: {
1981                writeGrantedUriPermissions();
1982                break;
1983            }
1984            case REQUEST_ALL_PSS_MSG: {
1985                synchronized (ActivityManagerService.this) {
1986                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1987                }
1988                break;
1989            }
1990            case START_PROFILES_MSG: {
1991                synchronized (ActivityManagerService.this) {
1992                    mUserController.startProfilesLocked();
1993                }
1994                break;
1995            }
1996            case UPDATE_TIME: {
1997                synchronized (ActivityManagerService.this) {
1998                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999                        ProcessRecord r = mLruProcesses.get(i);
2000                        if (r.thread != null) {
2001                            try {
2002                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2003                            } catch (RemoteException ex) {
2004                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2005                            }
2006                        }
2007                    }
2008                }
2009                break;
2010            }
2011            case SYSTEM_USER_START_MSG: {
2012                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2013                        Integer.toString(msg.arg1), msg.arg1);
2014                mSystemServiceManager.startUser(msg.arg1);
2015                break;
2016            }
2017            case SYSTEM_USER_UNLOCK_MSG: {
2018                final int userId = msg.arg1;
2019                mSystemServiceManager.unlockUser(userId);
2020                synchronized (ActivityManagerService.this) {
2021                    mRecentTasks.loadUserRecentsLocked(userId);
2022                }
2023                if (userId == UserHandle.USER_SYSTEM) {
2024                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2025                }
2026                installEncryptionUnawareProviders(userId);
2027                mUserController.finishUserUnlocked((UserState) msg.obj);
2028                break;
2029            }
2030            case SYSTEM_USER_CURRENT_MSG: {
2031                mBatteryStatsService.noteEvent(
2032                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2033                        Integer.toString(msg.arg2), msg.arg2);
2034                mBatteryStatsService.noteEvent(
2035                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2036                        Integer.toString(msg.arg1), msg.arg1);
2037                mSystemServiceManager.switchUser(msg.arg1);
2038                break;
2039            }
2040            case ENTER_ANIMATION_COMPLETE_MSG: {
2041                synchronized (ActivityManagerService.this) {
2042                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2043                    if (r != null && r.app != null && r.app.thread != null) {
2044                        try {
2045                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2046                        } catch (RemoteException e) {
2047                        }
2048                    }
2049                }
2050                break;
2051            }
2052            case FINISH_BOOTING_MSG: {
2053                if (msg.arg1 != 0) {
2054                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2055                    finishBooting();
2056                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2057                }
2058                if (msg.arg2 != 0) {
2059                    enableScreenAfterBoot();
2060                }
2061                break;
2062            }
2063            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2064                try {
2065                    Locale l = (Locale) msg.obj;
2066                    IBinder service = ServiceManager.getService("mount");
2067                    IMountService mountService = IMountService.Stub.asInterface(service);
2068                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2069                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2070                } catch (RemoteException e) {
2071                    Log.e(TAG, "Error storing locale for decryption UI", e);
2072                }
2073                break;
2074            }
2075            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2076                synchronized (ActivityManagerService.this) {
2077                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2078                        try {
2079                            // Make a one-way callback to the listener
2080                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2081                        } catch (RemoteException e){
2082                            // Handled by the RemoteCallbackList
2083                        }
2084                    }
2085                    mTaskStackListeners.finishBroadcast();
2086                }
2087                break;
2088            }
2089            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2090                synchronized (ActivityManagerService.this) {
2091                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2092                        try {
2093                            // Make a one-way callback to the listener
2094                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2095                        } catch (RemoteException e){
2096                            // Handled by the RemoteCallbackList
2097                        }
2098                    }
2099                    mTaskStackListeners.finishBroadcast();
2100                }
2101                break;
2102            }
2103            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2104                synchronized (ActivityManagerService.this) {
2105                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2106                        try {
2107                            // Make a one-way callback to the listener
2108                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2109                        } catch (RemoteException e){
2110                            // Handled by the RemoteCallbackList
2111                        }
2112                    }
2113                    mTaskStackListeners.finishBroadcast();
2114                }
2115                break;
2116            }
2117            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2118                synchronized (ActivityManagerService.this) {
2119                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2120                        try {
2121                            // Make a one-way callback to the listener
2122                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2123                        } catch (RemoteException e){
2124                            // Handled by the RemoteCallbackList
2125                        }
2126                    }
2127                    mTaskStackListeners.finishBroadcast();
2128                }
2129                break;
2130            }
2131            case NOTIFY_FORCED_RESIZABLE_MSG: {
2132                synchronized (ActivityManagerService.this) {
2133                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2134                        try {
2135                            // Make a one-way callback to the listener
2136                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2137                                    (String) msg.obj, msg.arg1);
2138                        } catch (RemoteException e){
2139                            // Handled by the RemoteCallbackList
2140                        }
2141                    }
2142                    mTaskStackListeners.finishBroadcast();
2143                }
2144                break;
2145            }
2146                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2147                    synchronized (ActivityManagerService.this) {
2148                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2149                            try {
2150                                // Make a one-way callback to the listener
2151                                mTaskStackListeners.getBroadcastItem(i)
2152                                        .onActivityDismissingDockedStack();
2153                            } catch (RemoteException e){
2154                                // Handled by the RemoteCallbackList
2155                            }
2156                        }
2157                        mTaskStackListeners.finishBroadcast();
2158                    }
2159                    break;
2160                }
2161            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2162                final int uid = msg.arg1;
2163                final byte[] firstPacket = (byte[]) msg.obj;
2164
2165                synchronized (mPidsSelfLocked) {
2166                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2167                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2168                        if (p.uid == uid) {
2169                            try {
2170                                p.thread.notifyCleartextNetwork(firstPacket);
2171                            } catch (RemoteException ignored) {
2172                            }
2173                        }
2174                    }
2175                }
2176                break;
2177            }
2178            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2179                final String procName;
2180                final int uid;
2181                final long memLimit;
2182                final String reportPackage;
2183                synchronized (ActivityManagerService.this) {
2184                    procName = mMemWatchDumpProcName;
2185                    uid = mMemWatchDumpUid;
2186                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2187                    if (val == null) {
2188                        val = mMemWatchProcesses.get(procName, 0);
2189                    }
2190                    if (val != null) {
2191                        memLimit = val.first;
2192                        reportPackage = val.second;
2193                    } else {
2194                        memLimit = 0;
2195                        reportPackage = null;
2196                    }
2197                }
2198                if (procName == null) {
2199                    return;
2200                }
2201
2202                if (DEBUG_PSS) Slog.d(TAG_PSS,
2203                        "Showing dump heap notification from " + procName + "/" + uid);
2204
2205                INotificationManager inm = NotificationManager.getService();
2206                if (inm == null) {
2207                    return;
2208                }
2209
2210                String text = mContext.getString(R.string.dump_heap_notification, procName);
2211
2212
2213                Intent deleteIntent = new Intent();
2214                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2215                Intent intent = new Intent();
2216                intent.setClassName("android", DumpHeapActivity.class.getName());
2217                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2218                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2219                if (reportPackage != null) {
2220                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2221                }
2222                int userId = UserHandle.getUserId(uid);
2223                Notification notification = new Notification.Builder(mContext)
2224                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2225                        .setWhen(0)
2226                        .setOngoing(true)
2227                        .setAutoCancel(true)
2228                        .setTicker(text)
2229                        .setColor(mContext.getColor(
2230                                com.android.internal.R.color.system_notification_accent_color))
2231                        .setContentTitle(text)
2232                        .setContentText(
2233                                mContext.getText(R.string.dump_heap_notification_detail))
2234                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2235                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2236                                new UserHandle(userId)))
2237                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2238                                deleteIntent, 0, UserHandle.SYSTEM))
2239                        .build();
2240
2241                try {
2242                    int[] outId = new int[1];
2243                    inm.enqueueNotificationWithTag("android", "android", null,
2244                            R.string.dump_heap_notification,
2245                            notification, outId, userId);
2246                } catch (RuntimeException e) {
2247                    Slog.w(ActivityManagerService.TAG,
2248                            "Error showing notification for dump heap", e);
2249                } catch (RemoteException e) {
2250                }
2251            } break;
2252            case DELETE_DUMPHEAP_MSG: {
2253                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2254                        DumpHeapActivity.JAVA_URI,
2255                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2256                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2257                        UserHandle.myUserId());
2258                synchronized (ActivityManagerService.this) {
2259                    mMemWatchDumpFile = null;
2260                    mMemWatchDumpProcName = null;
2261                    mMemWatchDumpPid = -1;
2262                    mMemWatchDumpUid = -1;
2263                }
2264            } break;
2265            case FOREGROUND_PROFILE_CHANGED_MSG: {
2266                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2267            } break;
2268            case REPORT_TIME_TRACKER_MSG: {
2269                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2270                tracker.deliverResult(mContext);
2271            } break;
2272            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2273                mUserController.dispatchUserSwitchComplete(msg.arg1);
2274            } break;
2275            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2276                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2277                try {
2278                    connection.shutdown();
2279                } catch (RemoteException e) {
2280                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2281                }
2282                // Only a UiAutomation can set this flag and now that
2283                // it is finished we make sure it is reset to its default.
2284                mUserIsMonkey = false;
2285            } break;
2286            case APP_BOOST_DEACTIVATE_MSG: {
2287                synchronized(ActivityManagerService.this) {
2288                    if (mIsBoosted) {
2289                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2290                            nativeMigrateFromBoost();
2291                            mIsBoosted = false;
2292                            mBoostStartTime = 0;
2293                        } else {
2294                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2295                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2296                        }
2297                    }
2298                }
2299            } break;
2300            case IDLE_UIDS_MSG: {
2301                idleUids();
2302            } break;
2303            case LOG_STACK_STATE: {
2304                synchronized (ActivityManagerService.this) {
2305                    mStackSupervisor.logStackState();
2306                }
2307            } break;
2308            case VR_MODE_CHANGE_MSG: {
2309                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2310                final ActivityRecord r = (ActivityRecord) msg.obj;
2311                boolean vrMode;
2312                ComponentName requestedPackage;
2313                ComponentName callingPackage;
2314                int userId;
2315                synchronized (ActivityManagerService.this) {
2316                    vrMode = r.requestedVrComponent != null;
2317                    requestedPackage = r.requestedVrComponent;
2318                    userId = r.userId;
2319                    callingPackage = r.info.getComponentName();
2320                    if (mInVrMode != vrMode) {
2321                        mInVrMode = vrMode;
2322                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2323                    }
2324                }
2325                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2326            } break;
2327            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2328                final ActivityRecord r = (ActivityRecord) msg.obj;
2329                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2330                if (needsVrMode) {
2331                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2332                            r.info.getComponentName(), false);
2333                }
2334            } break;
2335            }
2336        }
2337    };
2338
2339    static final int COLLECT_PSS_BG_MSG = 1;
2340
2341    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2342        @Override
2343        public void handleMessage(Message msg) {
2344            switch (msg.what) {
2345            case COLLECT_PSS_BG_MSG: {
2346                long start = SystemClock.uptimeMillis();
2347                MemInfoReader memInfo = null;
2348                synchronized (ActivityManagerService.this) {
2349                    if (mFullPssPending) {
2350                        mFullPssPending = false;
2351                        memInfo = new MemInfoReader();
2352                    }
2353                }
2354                if (memInfo != null) {
2355                    updateCpuStatsNow();
2356                    long nativeTotalPss = 0;
2357                    synchronized (mProcessCpuTracker) {
2358                        final int N = mProcessCpuTracker.countStats();
2359                        for (int j=0; j<N; j++) {
2360                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2361                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2362                                // This is definitely an application process; skip it.
2363                                continue;
2364                            }
2365                            synchronized (mPidsSelfLocked) {
2366                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2367                                    // This is one of our own processes; skip it.
2368                                    continue;
2369                                }
2370                            }
2371                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2372                        }
2373                    }
2374                    memInfo.readMemInfo();
2375                    synchronized (ActivityManagerService.this) {
2376                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2377                                + (SystemClock.uptimeMillis()-start) + "ms");
2378                        final long cachedKb = memInfo.getCachedSizeKb();
2379                        final long freeKb = memInfo.getFreeSizeKb();
2380                        final long zramKb = memInfo.getZramTotalSizeKb();
2381                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2382                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2383                                kernelKb*1024, nativeTotalPss*1024);
2384                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2385                                nativeTotalPss);
2386                    }
2387                }
2388
2389                int num = 0;
2390                long[] tmp = new long[2];
2391                do {
2392                    ProcessRecord proc;
2393                    int procState;
2394                    int pid;
2395                    long lastPssTime;
2396                    synchronized (ActivityManagerService.this) {
2397                        if (mPendingPssProcesses.size() <= 0) {
2398                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2399                                    "Collected PSS of " + num + " processes in "
2400                                    + (SystemClock.uptimeMillis() - start) + "ms");
2401                            mPendingPssProcesses.clear();
2402                            return;
2403                        }
2404                        proc = mPendingPssProcesses.remove(0);
2405                        procState = proc.pssProcState;
2406                        lastPssTime = proc.lastPssTime;
2407                        if (proc.thread != null && procState == proc.setProcState
2408                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2409                                        < SystemClock.uptimeMillis()) {
2410                            pid = proc.pid;
2411                        } else {
2412                            proc = null;
2413                            pid = 0;
2414                        }
2415                    }
2416                    if (proc != null) {
2417                        long pss = Debug.getPss(pid, tmp, null);
2418                        synchronized (ActivityManagerService.this) {
2419                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2420                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2421                                num++;
2422                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2423                                        SystemClock.uptimeMillis());
2424                            }
2425                        }
2426                    }
2427                } while (true);
2428            }
2429            }
2430        }
2431    };
2432
2433    public void setSystemProcess() {
2434        try {
2435            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2436            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2437            ServiceManager.addService("meminfo", new MemBinder(this));
2438            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2439            ServiceManager.addService("dbinfo", new DbBinder(this));
2440            if (MONITOR_CPU_USAGE) {
2441                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2442            }
2443            ServiceManager.addService("permission", new PermissionController(this));
2444            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2445
2446            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2447                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2448            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2449
2450            synchronized (this) {
2451                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2452                app.persistent = true;
2453                app.pid = MY_PID;
2454                app.maxAdj = ProcessList.SYSTEM_ADJ;
2455                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2456                synchronized (mPidsSelfLocked) {
2457                    mPidsSelfLocked.put(app.pid, app);
2458                }
2459                updateLruProcessLocked(app, false, null);
2460                updateOomAdjLocked();
2461            }
2462        } catch (PackageManager.NameNotFoundException e) {
2463            throw new RuntimeException(
2464                    "Unable to find android system package", e);
2465        }
2466    }
2467
2468    public void setWindowManager(WindowManagerService wm) {
2469        mWindowManager = wm;
2470        mStackSupervisor.setWindowManager(wm);
2471        mActivityStarter.setWindowManager(wm);
2472    }
2473
2474    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2475        mUsageStatsService = usageStatsManager;
2476    }
2477
2478    public void startObservingNativeCrashes() {
2479        final NativeCrashListener ncl = new NativeCrashListener(this);
2480        ncl.start();
2481    }
2482
2483    public IAppOpsService getAppOpsService() {
2484        return mAppOpsService;
2485    }
2486
2487    static class MemBinder extends Binder {
2488        ActivityManagerService mActivityManagerService;
2489        MemBinder(ActivityManagerService activityManagerService) {
2490            mActivityManagerService = activityManagerService;
2491        }
2492
2493        @Override
2494        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2495            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2496                    != PackageManager.PERMISSION_GRANTED) {
2497                pw.println("Permission Denial: can't dump meminfo from from pid="
2498                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2499                        + " without permission " + android.Manifest.permission.DUMP);
2500                return;
2501            }
2502
2503            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2504        }
2505    }
2506
2507    static class GraphicsBinder extends Binder {
2508        ActivityManagerService mActivityManagerService;
2509        GraphicsBinder(ActivityManagerService activityManagerService) {
2510            mActivityManagerService = activityManagerService;
2511        }
2512
2513        @Override
2514        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2515            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2516                    != PackageManager.PERMISSION_GRANTED) {
2517                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2518                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2519                        + " without permission " + android.Manifest.permission.DUMP);
2520                return;
2521            }
2522
2523            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2524        }
2525    }
2526
2527    static class DbBinder extends Binder {
2528        ActivityManagerService mActivityManagerService;
2529        DbBinder(ActivityManagerService activityManagerService) {
2530            mActivityManagerService = activityManagerService;
2531        }
2532
2533        @Override
2534        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2535            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2536                    != PackageManager.PERMISSION_GRANTED) {
2537                pw.println("Permission Denial: can't dump dbinfo from from pid="
2538                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2539                        + " without permission " + android.Manifest.permission.DUMP);
2540                return;
2541            }
2542
2543            mActivityManagerService.dumpDbInfo(fd, pw, args);
2544        }
2545    }
2546
2547    static class CpuBinder extends Binder {
2548        ActivityManagerService mActivityManagerService;
2549        CpuBinder(ActivityManagerService activityManagerService) {
2550            mActivityManagerService = activityManagerService;
2551        }
2552
2553        @Override
2554        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2555            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2556                    != PackageManager.PERMISSION_GRANTED) {
2557                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2558                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2559                        + " without permission " + android.Manifest.permission.DUMP);
2560                return;
2561            }
2562
2563            synchronized (mActivityManagerService.mProcessCpuTracker) {
2564                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2565                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2566                        SystemClock.uptimeMillis()));
2567            }
2568        }
2569    }
2570
2571    public static final class Lifecycle extends SystemService {
2572        private final ActivityManagerService mService;
2573
2574        public Lifecycle(Context context) {
2575            super(context);
2576            mService = new ActivityManagerService(context);
2577        }
2578
2579        @Override
2580        public void onStart() {
2581            mService.start();
2582        }
2583
2584        public ActivityManagerService getService() {
2585            return mService;
2586        }
2587    }
2588
2589    // Note: This method is invoked on the main thread but may need to attach various
2590    // handlers to other threads.  So take care to be explicit about the looper.
2591    public ActivityManagerService(Context systemContext) {
2592        mContext = systemContext;
2593        mFactoryTest = FactoryTest.getMode();
2594        mSystemThread = ActivityThread.currentActivityThread();
2595
2596        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2597
2598        mHandlerThread = new ServiceThread(TAG,
2599                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2600        mHandlerThread.start();
2601        mHandler = new MainHandler(mHandlerThread.getLooper());
2602        mUiHandler = new UiHandler();
2603
2604        /* static; one-time init here */
2605        if (sKillHandler == null) {
2606            sKillThread = new ServiceThread(TAG + ":kill",
2607                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2608            sKillThread.start();
2609            sKillHandler = new KillHandler(sKillThread.getLooper());
2610        }
2611
2612        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2613                "foreground", BROADCAST_FG_TIMEOUT, false);
2614        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2615                "background", BROADCAST_BG_TIMEOUT, true);
2616        mBroadcastQueues[0] = mFgBroadcastQueue;
2617        mBroadcastQueues[1] = mBgBroadcastQueue;
2618
2619        mServices = new ActiveServices(this);
2620        mProviderMap = new ProviderMap(this);
2621        mAppErrors = new AppErrors(mContext, this);
2622
2623        // TODO: Move creation of battery stats service outside of activity manager service.
2624        File dataDir = Environment.getDataDirectory();
2625        File systemDir = new File(dataDir, "system");
2626        systemDir.mkdirs();
2627        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2628        mBatteryStatsService.getActiveStatistics().readLocked();
2629        mBatteryStatsService.scheduleWriteToDisk();
2630        mOnBattery = DEBUG_POWER ? true
2631                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2632        mBatteryStatsService.getActiveStatistics().setCallback(this);
2633
2634        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2635
2636        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2637        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2638                new IAppOpsCallback.Stub() {
2639                    @Override public void opChanged(int op, int uid, String packageName) {
2640                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2641                            if (mAppOpsService.checkOperation(op, uid, packageName)
2642                                    != AppOpsManager.MODE_ALLOWED) {
2643                                runInBackgroundDisabled(uid);
2644                            }
2645                        }
2646                    }
2647                });
2648
2649        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2650
2651        mUserController = new UserController(this);
2652
2653        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2654            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2655
2656        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2657
2658        mConfiguration.setToDefaults();
2659        mConfiguration.setLocales(LocaleList.getDefault());
2660
2661        mConfigurationSeq = mConfiguration.seq = 1;
2662        mProcessCpuTracker.init();
2663
2664        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2665        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2666        mStackSupervisor = new ActivityStackSupervisor(this);
2667        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2668        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2669
2670        mProcessCpuThread = new Thread("CpuTracker") {
2671            @Override
2672            public void run() {
2673                while (true) {
2674                    try {
2675                        try {
2676                            synchronized(this) {
2677                                final long now = SystemClock.uptimeMillis();
2678                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2679                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2680                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2681                                //        + ", write delay=" + nextWriteDelay);
2682                                if (nextWriteDelay < nextCpuDelay) {
2683                                    nextCpuDelay = nextWriteDelay;
2684                                }
2685                                if (nextCpuDelay > 0) {
2686                                    mProcessCpuMutexFree.set(true);
2687                                    this.wait(nextCpuDelay);
2688                                }
2689                            }
2690                        } catch (InterruptedException e) {
2691                        }
2692                        updateCpuStatsNow();
2693                    } catch (Exception e) {
2694                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2695                    }
2696                }
2697            }
2698        };
2699
2700        Watchdog.getInstance().addMonitor(this);
2701        Watchdog.getInstance().addThread(mHandler);
2702    }
2703
2704    public void setSystemServiceManager(SystemServiceManager mgr) {
2705        mSystemServiceManager = mgr;
2706    }
2707
2708    public void setInstaller(Installer installer) {
2709        mInstaller = installer;
2710    }
2711
2712    private void start() {
2713        Process.removeAllProcessGroups();
2714        mProcessCpuThread.start();
2715
2716        mBatteryStatsService.publish(mContext);
2717        mAppOpsService.publish(mContext);
2718        Slog.d("AppOps", "AppOpsService published");
2719        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2720    }
2721
2722    void onUserStoppedLocked(int userId) {
2723        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2724    }
2725
2726    public void initPowerManagement() {
2727        mStackSupervisor.initPowerManagement();
2728        mBatteryStatsService.initPowerManagement();
2729        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2730        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2731        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2732        mVoiceWakeLock.setReferenceCounted(false);
2733    }
2734
2735    @Override
2736    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2737            throws RemoteException {
2738        if (code == SYSPROPS_TRANSACTION) {
2739            // We need to tell all apps about the system property change.
2740            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2741            synchronized(this) {
2742                final int NP = mProcessNames.getMap().size();
2743                for (int ip=0; ip<NP; ip++) {
2744                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2745                    final int NA = apps.size();
2746                    for (int ia=0; ia<NA; ia++) {
2747                        ProcessRecord app = apps.valueAt(ia);
2748                        if (app.thread != null) {
2749                            procs.add(app.thread.asBinder());
2750                        }
2751                    }
2752                }
2753            }
2754
2755            int N = procs.size();
2756            for (int i=0; i<N; i++) {
2757                Parcel data2 = Parcel.obtain();
2758                try {
2759                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2760                } catch (RemoteException e) {
2761                }
2762                data2.recycle();
2763            }
2764        }
2765        try {
2766            return super.onTransact(code, data, reply, flags);
2767        } catch (RuntimeException e) {
2768            // The activity manager only throws security exceptions, so let's
2769            // log all others.
2770            if (!(e instanceof SecurityException)) {
2771                Slog.wtf(TAG, "Activity Manager Crash", e);
2772            }
2773            throw e;
2774        }
2775    }
2776
2777    void updateCpuStats() {
2778        final long now = SystemClock.uptimeMillis();
2779        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2780            return;
2781        }
2782        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2783            synchronized (mProcessCpuThread) {
2784                mProcessCpuThread.notify();
2785            }
2786        }
2787    }
2788
2789    void updateCpuStatsNow() {
2790        synchronized (mProcessCpuTracker) {
2791            mProcessCpuMutexFree.set(false);
2792            final long now = SystemClock.uptimeMillis();
2793            boolean haveNewCpuStats = false;
2794
2795            if (MONITOR_CPU_USAGE &&
2796                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2797                mLastCpuTime.set(now);
2798                mProcessCpuTracker.update();
2799                if (mProcessCpuTracker.hasGoodLastStats()) {
2800                    haveNewCpuStats = true;
2801                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2802                    //Slog.i(TAG, "Total CPU usage: "
2803                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2804
2805                    // Slog the cpu usage if the property is set.
2806                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2807                        int user = mProcessCpuTracker.getLastUserTime();
2808                        int system = mProcessCpuTracker.getLastSystemTime();
2809                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2810                        int irq = mProcessCpuTracker.getLastIrqTime();
2811                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2812                        int idle = mProcessCpuTracker.getLastIdleTime();
2813
2814                        int total = user + system + iowait + irq + softIrq + idle;
2815                        if (total == 0) total = 1;
2816
2817                        EventLog.writeEvent(EventLogTags.CPU,
2818                                ((user+system+iowait+irq+softIrq) * 100) / total,
2819                                (user * 100) / total,
2820                                (system * 100) / total,
2821                                (iowait * 100) / total,
2822                                (irq * 100) / total,
2823                                (softIrq * 100) / total);
2824                    }
2825                }
2826            }
2827
2828            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2829            synchronized(bstats) {
2830                synchronized(mPidsSelfLocked) {
2831                    if (haveNewCpuStats) {
2832                        if (bstats.startAddingCpuLocked()) {
2833                            int totalUTime = 0;
2834                            int totalSTime = 0;
2835                            final int N = mProcessCpuTracker.countStats();
2836                            for (int i=0; i<N; i++) {
2837                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2838                                if (!st.working) {
2839                                    continue;
2840                                }
2841                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2842                                totalUTime += st.rel_utime;
2843                                totalSTime += st.rel_stime;
2844                                if (pr != null) {
2845                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2846                                    if (ps == null || !ps.isActive()) {
2847                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2848                                                pr.info.uid, pr.processName);
2849                                    }
2850                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2851                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2852                                } else {
2853                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2854                                    if (ps == null || !ps.isActive()) {
2855                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2856                                                bstats.mapUid(st.uid), st.name);
2857                                    }
2858                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2859                                }
2860                            }
2861                            final int userTime = mProcessCpuTracker.getLastUserTime();
2862                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2863                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2864                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2865                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2866                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2867                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2868                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2869                        }
2870                    }
2871                }
2872
2873                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2874                    mLastWriteTime = now;
2875                    mBatteryStatsService.scheduleWriteToDisk();
2876                }
2877            }
2878        }
2879    }
2880
2881    @Override
2882    public void batteryNeedsCpuUpdate() {
2883        updateCpuStatsNow();
2884    }
2885
2886    @Override
2887    public void batteryPowerChanged(boolean onBattery) {
2888        // When plugging in, update the CPU stats first before changing
2889        // the plug state.
2890        updateCpuStatsNow();
2891        synchronized (this) {
2892            synchronized(mPidsSelfLocked) {
2893                mOnBattery = DEBUG_POWER ? true : onBattery;
2894            }
2895        }
2896    }
2897
2898    @Override
2899    public void batterySendBroadcast(Intent intent) {
2900        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2901                AppOpsManager.OP_NONE, null, false, false,
2902                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2903    }
2904
2905    /**
2906     * Initialize the application bind args. These are passed to each
2907     * process when the bindApplication() IPC is sent to the process. They're
2908     * lazily setup to make sure the services are running when they're asked for.
2909     */
2910    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2911        if (mAppBindArgs == null) {
2912            mAppBindArgs = new HashMap<>();
2913
2914            // Isolated processes won't get this optimization, so that we don't
2915            // violate the rules about which services they have access to.
2916            if (!isolated) {
2917                // Setup the application init args
2918                mAppBindArgs.put("package", ServiceManager.getService("package"));
2919                mAppBindArgs.put("window", ServiceManager.getService("window"));
2920                mAppBindArgs.put(Context.ALARM_SERVICE,
2921                        ServiceManager.getService(Context.ALARM_SERVICE));
2922            }
2923        }
2924        return mAppBindArgs;
2925    }
2926
2927    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2928        if (r == null || mFocusedActivity == r) {
2929            return false;
2930        }
2931
2932        if (!r.isFocusable()) {
2933            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2934            return false;
2935        }
2936
2937        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2938
2939        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2940        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2941                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2942        mDoingSetFocusedActivity = true;
2943
2944        final ActivityRecord last = mFocusedActivity;
2945        mFocusedActivity = r;
2946        if (r.task.isApplicationTask()) {
2947            if (mCurAppTimeTracker != r.appTimeTracker) {
2948                // We are switching app tracking.  Complete the current one.
2949                if (mCurAppTimeTracker != null) {
2950                    mCurAppTimeTracker.stop();
2951                    mHandler.obtainMessage(
2952                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2953                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2954                    mCurAppTimeTracker = null;
2955                }
2956                if (r.appTimeTracker != null) {
2957                    mCurAppTimeTracker = r.appTimeTracker;
2958                    startTimeTrackingFocusedActivityLocked();
2959                }
2960            } else {
2961                startTimeTrackingFocusedActivityLocked();
2962            }
2963        } else {
2964            r.appTimeTracker = null;
2965        }
2966        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2967        // TODO: Probably not, because we don't want to resume voice on switching
2968        // back to this activity
2969        if (r.task.voiceInteractor != null) {
2970            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2971        } else {
2972            finishRunningVoiceLocked();
2973            IVoiceInteractionSession session;
2974            if (last != null && ((session = last.task.voiceSession) != null
2975                    || (session = last.voiceSession) != null)) {
2976                // We had been in a voice interaction session, but now focused has
2977                // move to something different.  Just finish the session, we can't
2978                // return to it and retain the proper state and synchronization with
2979                // the voice interaction service.
2980                finishVoiceTask(session);
2981            }
2982        }
2983        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2984            mWindowManager.setFocusedApp(r.appToken, true);
2985        }
2986        applyUpdateLockStateLocked(r);
2987        applyUpdateVrModeLocked(r);
2988        if (mFocusedActivity.userId != mLastFocusedUserId) {
2989            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2990            mHandler.obtainMessage(
2991                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2992            mLastFocusedUserId = mFocusedActivity.userId;
2993        }
2994
2995        // Log a warning if the focused app is changed during the process. This could
2996        // indicate a problem of the focus setting logic!
2997        if (mFocusedActivity != r) Slog.w(TAG,
2998                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2999        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3000
3001        EventLogTags.writeAmFocusedActivity(
3002                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3003                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3004                reason);
3005        return true;
3006    }
3007
3008    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3009        if (mFocusedActivity != goingAway) {
3010            return;
3011        }
3012
3013        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3014        if (focusedStack != null) {
3015            final ActivityRecord top = focusedStack.topActivity();
3016            if (top != null && top.userId != mLastFocusedUserId) {
3017                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3018                mHandler.sendMessage(
3019                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3020                mLastFocusedUserId = top.userId;
3021            }
3022        }
3023
3024        // Try to move focus to another activity if possible.
3025        if (setFocusedActivityLocked(
3026                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3027            return;
3028        }
3029
3030        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3031                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3032        mFocusedActivity = null;
3033        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3034    }
3035
3036    @Override
3037    public void setFocusedStack(int stackId) {
3038        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3039        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3040        final long callingId = Binder.clearCallingIdentity();
3041        try {
3042            synchronized (this) {
3043                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3044                if (stack == null) {
3045                    return;
3046                }
3047                final ActivityRecord r = stack.topRunningActivityLocked();
3048                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3049                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3050                }
3051            }
3052        } finally {
3053            Binder.restoreCallingIdentity(callingId);
3054        }
3055    }
3056
3057    @Override
3058    public void setFocusedTask(int taskId) {
3059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3060        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3061        final long callingId = Binder.clearCallingIdentity();
3062        try {
3063            synchronized (this) {
3064                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3065                if (task == null) {
3066                    return;
3067                }
3068                final ActivityRecord r = task.topRunningActivityLocked();
3069                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3070                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3071                }
3072            }
3073        } finally {
3074            Binder.restoreCallingIdentity(callingId);
3075        }
3076    }
3077
3078    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3079    @Override
3080    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3082        synchronized (this) {
3083            if (listener != null) {
3084                mTaskStackListeners.register(listener);
3085            }
3086        }
3087    }
3088
3089    @Override
3090    public void notifyActivityDrawn(IBinder token) {
3091        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3092        synchronized (this) {
3093            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3094            if (r != null) {
3095                r.task.stack.notifyActivityDrawnLocked(r);
3096            }
3097        }
3098    }
3099
3100    final void applyUpdateLockStateLocked(ActivityRecord r) {
3101        // Modifications to the UpdateLock state are done on our handler, outside
3102        // the activity manager's locks.  The new state is determined based on the
3103        // state *now* of the relevant activity record.  The object is passed to
3104        // the handler solely for logging detail, not to be consulted/modified.
3105        final boolean nextState = r != null && r.immersive;
3106        mHandler.sendMessage(
3107                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3108    }
3109
3110    final void applyUpdateVrModeLocked(ActivityRecord r) {
3111        mHandler.sendMessage(
3112                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3113    }
3114
3115    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3116        mHandler.sendMessage(
3117                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3118    }
3119
3120    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3121            ComponentName callingPackage, boolean immediate) {
3122        VrManagerInternal vrService =
3123                LocalServices.getService(VrManagerInternal.class);
3124        if (immediate) {
3125            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3126        } else {
3127            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3128        }
3129    }
3130
3131    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3132        Message msg = Message.obtain();
3133        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3134        msg.obj = r.task.askedCompatMode ? null : r;
3135        mUiHandler.sendMessage(msg);
3136    }
3137
3138    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3139        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3140                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3141            final Message msg = Message.obtain();
3142            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3143            msg.obj = r;
3144            mUiHandler.sendMessage(msg);
3145        }
3146    }
3147
3148    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3149            String what, Object obj, ProcessRecord srcApp) {
3150        app.lastActivityTime = now;
3151
3152        if (app.activities.size() > 0) {
3153            // Don't want to touch dependent processes that are hosting activities.
3154            return index;
3155        }
3156
3157        int lrui = mLruProcesses.lastIndexOf(app);
3158        if (lrui < 0) {
3159            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3160                    + what + " " + obj + " from " + srcApp);
3161            return index;
3162        }
3163
3164        if (lrui >= index) {
3165            // Don't want to cause this to move dependent processes *back* in the
3166            // list as if they were less frequently used.
3167            return index;
3168        }
3169
3170        if (lrui >= mLruProcessActivityStart) {
3171            // Don't want to touch dependent processes that are hosting activities.
3172            return index;
3173        }
3174
3175        mLruProcesses.remove(lrui);
3176        if (index > 0) {
3177            index--;
3178        }
3179        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3180                + " in LRU list: " + app);
3181        mLruProcesses.add(index, app);
3182        return index;
3183    }
3184
3185    static void killProcessGroup(int uid, int pid) {
3186        if (sKillHandler != null) {
3187            sKillHandler.sendMessage(
3188                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3189        } else {
3190            Slog.w(TAG, "Asked to kill process group before system bringup!");
3191            Process.killProcessGroup(uid, pid);
3192        }
3193    }
3194
3195    final void removeLruProcessLocked(ProcessRecord app) {
3196        int lrui = mLruProcesses.lastIndexOf(app);
3197        if (lrui >= 0) {
3198            if (!app.killed) {
3199                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3200                Process.killProcessQuiet(app.pid);
3201                killProcessGroup(app.uid, app.pid);
3202            }
3203            if (lrui <= mLruProcessActivityStart) {
3204                mLruProcessActivityStart--;
3205            }
3206            if (lrui <= mLruProcessServiceStart) {
3207                mLruProcessServiceStart--;
3208            }
3209            mLruProcesses.remove(lrui);
3210        }
3211    }
3212
3213    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3214            ProcessRecord client) {
3215        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3216                || app.treatLikeActivity;
3217        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3218        if (!activityChange && hasActivity) {
3219            // The process has activities, so we are only allowing activity-based adjustments
3220            // to move it.  It should be kept in the front of the list with other
3221            // processes that have activities, and we don't want those to change their
3222            // order except due to activity operations.
3223            return;
3224        }
3225
3226        mLruSeq++;
3227        final long now = SystemClock.uptimeMillis();
3228        app.lastActivityTime = now;
3229
3230        // First a quick reject: if the app is already at the position we will
3231        // put it, then there is nothing to do.
3232        if (hasActivity) {
3233            final int N = mLruProcesses.size();
3234            if (N > 0 && mLruProcesses.get(N-1) == app) {
3235                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3236                return;
3237            }
3238        } else {
3239            if (mLruProcessServiceStart > 0
3240                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3241                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3242                return;
3243            }
3244        }
3245
3246        int lrui = mLruProcesses.lastIndexOf(app);
3247
3248        if (app.persistent && lrui >= 0) {
3249            // We don't care about the position of persistent processes, as long as
3250            // they are in the list.
3251            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3252            return;
3253        }
3254
3255        /* In progress: compute new position first, so we can avoid doing work
3256           if the process is not actually going to move.  Not yet working.
3257        int addIndex;
3258        int nextIndex;
3259        boolean inActivity = false, inService = false;
3260        if (hasActivity) {
3261            // Process has activities, put it at the very tipsy-top.
3262            addIndex = mLruProcesses.size();
3263            nextIndex = mLruProcessServiceStart;
3264            inActivity = true;
3265        } else if (hasService) {
3266            // Process has services, put it at the top of the service list.
3267            addIndex = mLruProcessActivityStart;
3268            nextIndex = mLruProcessServiceStart;
3269            inActivity = true;
3270            inService = true;
3271        } else  {
3272            // Process not otherwise of interest, it goes to the top of the non-service area.
3273            addIndex = mLruProcessServiceStart;
3274            if (client != null) {
3275                int clientIndex = mLruProcesses.lastIndexOf(client);
3276                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3277                        + app);
3278                if (clientIndex >= 0 && addIndex > clientIndex) {
3279                    addIndex = clientIndex;
3280                }
3281            }
3282            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3283        }
3284
3285        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3286                + mLruProcessActivityStart + "): " + app);
3287        */
3288
3289        if (lrui >= 0) {
3290            if (lrui < mLruProcessActivityStart) {
3291                mLruProcessActivityStart--;
3292            }
3293            if (lrui < mLruProcessServiceStart) {
3294                mLruProcessServiceStart--;
3295            }
3296            /*
3297            if (addIndex > lrui) {
3298                addIndex--;
3299            }
3300            if (nextIndex > lrui) {
3301                nextIndex--;
3302            }
3303            */
3304            mLruProcesses.remove(lrui);
3305        }
3306
3307        /*
3308        mLruProcesses.add(addIndex, app);
3309        if (inActivity) {
3310            mLruProcessActivityStart++;
3311        }
3312        if (inService) {
3313            mLruProcessActivityStart++;
3314        }
3315        */
3316
3317        int nextIndex;
3318        if (hasActivity) {
3319            final int N = mLruProcesses.size();
3320            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3321                // Process doesn't have activities, but has clients with
3322                // activities...  move it up, but one below the top (the top
3323                // should always have a real activity).
3324                if (DEBUG_LRU) Slog.d(TAG_LRU,
3325                        "Adding to second-top of LRU activity list: " + app);
3326                mLruProcesses.add(N - 1, app);
3327                // To keep it from spamming the LRU list (by making a bunch of clients),
3328                // we will push down any other entries owned by the app.
3329                final int uid = app.info.uid;
3330                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3331                    ProcessRecord subProc = mLruProcesses.get(i);
3332                    if (subProc.info.uid == uid) {
3333                        // We want to push this one down the list.  If the process after
3334                        // it is for the same uid, however, don't do so, because we don't
3335                        // want them internally to be re-ordered.
3336                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3337                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3338                                    "Pushing uid " + uid + " swapping at " + i + ": "
3339                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3340                            ProcessRecord tmp = mLruProcesses.get(i);
3341                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3342                            mLruProcesses.set(i - 1, tmp);
3343                            i--;
3344                        }
3345                    } else {
3346                        // A gap, we can stop here.
3347                        break;
3348                    }
3349                }
3350            } else {
3351                // Process has activities, put it at the very tipsy-top.
3352                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3353                mLruProcesses.add(app);
3354            }
3355            nextIndex = mLruProcessServiceStart;
3356        } else if (hasService) {
3357            // Process has services, put it at the top of the service list.
3358            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3359            mLruProcesses.add(mLruProcessActivityStart, app);
3360            nextIndex = mLruProcessServiceStart;
3361            mLruProcessActivityStart++;
3362        } else  {
3363            // Process not otherwise of interest, it goes to the top of the non-service area.
3364            int index = mLruProcessServiceStart;
3365            if (client != null) {
3366                // If there is a client, don't allow the process to be moved up higher
3367                // in the list than that client.
3368                int clientIndex = mLruProcesses.lastIndexOf(client);
3369                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3370                        + " when updating " + app);
3371                if (clientIndex <= lrui) {
3372                    // Don't allow the client index restriction to push it down farther in the
3373                    // list than it already is.
3374                    clientIndex = lrui;
3375                }
3376                if (clientIndex >= 0 && index > clientIndex) {
3377                    index = clientIndex;
3378                }
3379            }
3380            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3381            mLruProcesses.add(index, app);
3382            nextIndex = index-1;
3383            mLruProcessActivityStart++;
3384            mLruProcessServiceStart++;
3385        }
3386
3387        // If the app is currently using a content provider or service,
3388        // bump those processes as well.
3389        for (int j=app.connections.size()-1; j>=0; j--) {
3390            ConnectionRecord cr = app.connections.valueAt(j);
3391            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3392                    && cr.binding.service.app != null
3393                    && cr.binding.service.app.lruSeq != mLruSeq
3394                    && !cr.binding.service.app.persistent) {
3395                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3396                        "service connection", cr, app);
3397            }
3398        }
3399        for (int j=app.conProviders.size()-1; j>=0; j--) {
3400            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3401            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3402                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3403                        "provider reference", cpr, app);
3404            }
3405        }
3406    }
3407
3408    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3409        if (uid == Process.SYSTEM_UID) {
3410            // The system gets to run in any process.  If there are multiple
3411            // processes with the same uid, just pick the first (this
3412            // should never happen).
3413            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3414            if (procs == null) return null;
3415            final int procCount = procs.size();
3416            for (int i = 0; i < procCount; i++) {
3417                final int procUid = procs.keyAt(i);
3418                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3419                    // Don't use an app process or different user process for system component.
3420                    continue;
3421                }
3422                return procs.valueAt(i);
3423            }
3424        }
3425        ProcessRecord proc = mProcessNames.get(processName, uid);
3426        if (false && proc != null && !keepIfLarge
3427                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3428                && proc.lastCachedPss >= 4000) {
3429            // Turn this condition on to cause killing to happen regularly, for testing.
3430            if (proc.baseProcessTracker != null) {
3431                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3432            }
3433            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3434        } else if (proc != null && !keepIfLarge
3435                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3436                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3437            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3438            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3439                if (proc.baseProcessTracker != null) {
3440                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3441                }
3442                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3443            }
3444        }
3445        return proc;
3446    }
3447
3448    void notifyPackageUse(String packageName, int reason) {
3449        IPackageManager pm = AppGlobals.getPackageManager();
3450        try {
3451            pm.notifyPackageUse(packageName, reason);
3452        } catch (RemoteException e) {
3453        }
3454    }
3455
3456    boolean isNextTransitionForward() {
3457        int transit = mWindowManager.getPendingAppTransition();
3458        return transit == TRANSIT_ACTIVITY_OPEN
3459                || transit == TRANSIT_TASK_OPEN
3460                || transit == TRANSIT_TASK_TO_FRONT;
3461    }
3462
3463    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3464            String processName, String abiOverride, int uid, Runnable crashHandler) {
3465        synchronized(this) {
3466            ApplicationInfo info = new ApplicationInfo();
3467            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3468            // For isolated processes, the former contains the parent's uid and the latter the
3469            // actual uid of the isolated process.
3470            // In the special case introduced by this method (which is, starting an isolated
3471            // process directly from the SystemServer without an actual parent app process) the
3472            // closest thing to a parent's uid is SYSTEM_UID.
3473            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3474            // the |isolated| logic in the ProcessRecord constructor.
3475            info.uid = Process.SYSTEM_UID;
3476            info.processName = processName;
3477            info.className = entryPoint;
3478            info.packageName = "android";
3479            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3480                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3481                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3482                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3483                    crashHandler);
3484            return proc != null ? proc.pid : 0;
3485        }
3486    }
3487
3488    final ProcessRecord startProcessLocked(String processName,
3489            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3490            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3491            boolean isolated, boolean keepIfLarge) {
3492        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3493                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3494                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3495                null /* crashHandler */);
3496    }
3497
3498    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3499            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3500            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3501            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3502        long startTime = SystemClock.elapsedRealtime();
3503        ProcessRecord app;
3504        if (!isolated) {
3505            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3506            checkTime(startTime, "startProcess: after getProcessRecord");
3507
3508            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3509                // If we are in the background, then check to see if this process
3510                // is bad.  If so, we will just silently fail.
3511                if (mAppErrors.isBadProcessLocked(info)) {
3512                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3513                            + "/" + info.processName);
3514                    return null;
3515                }
3516            } else {
3517                // When the user is explicitly starting a process, then clear its
3518                // crash count so that we won't make it bad until they see at
3519                // least one crash dialog again, and make the process good again
3520                // if it had been bad.
3521                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3522                        + "/" + info.processName);
3523                mAppErrors.resetProcessCrashTimeLocked(info);
3524                if (mAppErrors.isBadProcessLocked(info)) {
3525                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3526                            UserHandle.getUserId(info.uid), info.uid,
3527                            info.processName);
3528                    mAppErrors.clearBadProcessLocked(info);
3529                    if (app != null) {
3530                        app.bad = false;
3531                    }
3532                }
3533            }
3534        } else {
3535            // If this is an isolated process, it can't re-use an existing process.
3536            app = null;
3537        }
3538
3539        // app launch boost for big.little configurations
3540        // use cpusets to migrate freshly launched tasks to big cores
3541        nativeMigrateToBoost();
3542        mIsBoosted = true;
3543        mBoostStartTime = SystemClock.uptimeMillis();
3544        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3545        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3546
3547        // We don't have to do anything more if:
3548        // (1) There is an existing application record; and
3549        // (2) The caller doesn't think it is dead, OR there is no thread
3550        //     object attached to it so we know it couldn't have crashed; and
3551        // (3) There is a pid assigned to it, so it is either starting or
3552        //     already running.
3553        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3554                + " app=" + app + " knownToBeDead=" + knownToBeDead
3555                + " thread=" + (app != null ? app.thread : null)
3556                + " pid=" + (app != null ? app.pid : -1));
3557        if (app != null && app.pid > 0) {
3558            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3559                // We already have the app running, or are waiting for it to
3560                // come up (we have a pid but not yet its thread), so keep it.
3561                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3562                // If this is a new package in the process, add the package to the list
3563                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3564                checkTime(startTime, "startProcess: done, added package to proc");
3565                return app;
3566            }
3567
3568            // An application record is attached to a previous process,
3569            // clean it up now.
3570            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3571            checkTime(startTime, "startProcess: bad proc running, killing");
3572            killProcessGroup(app.uid, app.pid);
3573            handleAppDiedLocked(app, true, true);
3574            checkTime(startTime, "startProcess: done killing old proc");
3575        }
3576
3577        String hostingNameStr = hostingName != null
3578                ? hostingName.flattenToShortString() : null;
3579
3580        if (app == null) {
3581            checkTime(startTime, "startProcess: creating new process record");
3582            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3583            if (app == null) {
3584                Slog.w(TAG, "Failed making new process record for "
3585                        + processName + "/" + info.uid + " isolated=" + isolated);
3586                return null;
3587            }
3588            app.crashHandler = crashHandler;
3589            checkTime(startTime, "startProcess: done creating new process record");
3590        } else {
3591            // If this is a new package in the process, add the package to the list
3592            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3593            checkTime(startTime, "startProcess: added package to existing proc");
3594        }
3595
3596        // If the system is not ready yet, then hold off on starting this
3597        // process until it is.
3598        if (!mProcessesReady
3599                && !isAllowedWhileBooting(info)
3600                && !allowWhileBooting) {
3601            if (!mProcessesOnHold.contains(app)) {
3602                mProcessesOnHold.add(app);
3603            }
3604            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3605                    "System not ready, putting on hold: " + app);
3606            checkTime(startTime, "startProcess: returning with proc on hold");
3607            return app;
3608        }
3609
3610        checkTime(startTime, "startProcess: stepping in to startProcess");
3611        startProcessLocked(
3612                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3613        checkTime(startTime, "startProcess: done starting proc!");
3614        return (app.pid != 0) ? app : null;
3615    }
3616
3617    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3618        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3619    }
3620
3621    private final void startProcessLocked(ProcessRecord app,
3622            String hostingType, String hostingNameStr) {
3623        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3624                null /* entryPoint */, null /* entryPointArgs */);
3625    }
3626
3627    private final void startProcessLocked(ProcessRecord app, String hostingType,
3628            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3629        long startTime = SystemClock.elapsedRealtime();
3630        if (app.pid > 0 && app.pid != MY_PID) {
3631            checkTime(startTime, "startProcess: removing from pids map");
3632            synchronized (mPidsSelfLocked) {
3633                mPidsSelfLocked.remove(app.pid);
3634                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3635            }
3636            checkTime(startTime, "startProcess: done removing from pids map");
3637            app.setPid(0);
3638        }
3639
3640        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3641                "startProcessLocked removing on hold: " + app);
3642        mProcessesOnHold.remove(app);
3643
3644        checkTime(startTime, "startProcess: starting to update cpu stats");
3645        updateCpuStats();
3646        checkTime(startTime, "startProcess: done updating cpu stats");
3647
3648        try {
3649            try {
3650                final int userId = UserHandle.getUserId(app.uid);
3651                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3652            } catch (RemoteException e) {
3653                throw e.rethrowAsRuntimeException();
3654            }
3655
3656            int uid = app.uid;
3657            int[] gids = null;
3658            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3659            if (!app.isolated) {
3660                int[] permGids = null;
3661                try {
3662                    checkTime(startTime, "startProcess: getting gids from package manager");
3663                    final IPackageManager pm = AppGlobals.getPackageManager();
3664                    permGids = pm.getPackageGids(app.info.packageName,
3665                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3666                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3667                            MountServiceInternal.class);
3668                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3669                            app.info.packageName);
3670                } catch (RemoteException e) {
3671                    throw e.rethrowAsRuntimeException();
3672                }
3673
3674                /*
3675                 * Add shared application and profile GIDs so applications can share some
3676                 * resources like shared libraries and access user-wide resources
3677                 */
3678                if (ArrayUtils.isEmpty(permGids)) {
3679                    gids = new int[2];
3680                } else {
3681                    gids = new int[permGids.length + 2];
3682                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3683                }
3684                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3685                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3686            }
3687            checkTime(startTime, "startProcess: building args");
3688            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3689                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3690                        && mTopComponent != null
3691                        && app.processName.equals(mTopComponent.getPackageName())) {
3692                    uid = 0;
3693                }
3694                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3695                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3696                    uid = 0;
3697                }
3698            }
3699            int debugFlags = 0;
3700            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3701                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3702                // Also turn on CheckJNI for debuggable apps. It's quite
3703                // awkward to turn on otherwise.
3704                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3705            }
3706            // Run the app in safe mode if its manifest requests so or the
3707            // system is booted in safe mode.
3708            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3709                mSafeMode == true) {
3710                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3711            }
3712            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3713                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3714            }
3715            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3716            if ("true".equals(genDebugInfoProperty)) {
3717                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3718            }
3719            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3720                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3721            }
3722            if ("1".equals(SystemProperties.get("debug.assert"))) {
3723                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3724            }
3725            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3726                // Enable all debug flags required by the native debugger.
3727                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3728                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3729                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3730                mNativeDebuggingApp = null;
3731            }
3732
3733            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3734            if (requiredAbi == null) {
3735                requiredAbi = Build.SUPPORTED_ABIS[0];
3736            }
3737
3738            String instructionSet = null;
3739            if (app.info.primaryCpuAbi != null) {
3740                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3741            }
3742
3743            app.gids = gids;
3744            app.requiredAbi = requiredAbi;
3745            app.instructionSet = instructionSet;
3746
3747            // Start the process.  It will either succeed and return a result containing
3748            // the PID of the new process, or else throw a RuntimeException.
3749            boolean isActivityProcess = (entryPoint == null);
3750            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3751            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3752                    app.processName);
3753            checkTime(startTime, "startProcess: asking zygote to start proc");
3754            Process.ProcessStartResult startResult = Process.start(entryPoint,
3755                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3756                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3757                    app.info.dataDir, entryPointArgs);
3758            checkTime(startTime, "startProcess: returned from zygote!");
3759            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3760
3761            if (app.isolated) {
3762                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3763            }
3764            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3765            checkTime(startTime, "startProcess: done updating battery stats");
3766
3767            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3768                    UserHandle.getUserId(uid), startResult.pid, uid,
3769                    app.processName, hostingType,
3770                    hostingNameStr != null ? hostingNameStr : "");
3771
3772            try {
3773                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3774                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3775            } catch (RemoteException ex) {
3776                // Ignore
3777            }
3778
3779            if (app.persistent) {
3780                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3781            }
3782
3783            checkTime(startTime, "startProcess: building log message");
3784            StringBuilder buf = mStringBuilder;
3785            buf.setLength(0);
3786            buf.append("Start proc ");
3787            buf.append(startResult.pid);
3788            buf.append(':');
3789            buf.append(app.processName);
3790            buf.append('/');
3791            UserHandle.formatUid(buf, uid);
3792            if (!isActivityProcess) {
3793                buf.append(" [");
3794                buf.append(entryPoint);
3795                buf.append("]");
3796            }
3797            buf.append(" for ");
3798            buf.append(hostingType);
3799            if (hostingNameStr != null) {
3800                buf.append(" ");
3801                buf.append(hostingNameStr);
3802            }
3803            Slog.i(TAG, buf.toString());
3804            app.setPid(startResult.pid);
3805            app.usingWrapper = startResult.usingWrapper;
3806            app.removed = false;
3807            app.killed = false;
3808            app.killedByAm = false;
3809            checkTime(startTime, "startProcess: starting to update pids map");
3810            synchronized (mPidsSelfLocked) {
3811                ProcessRecord oldApp;
3812                // If there is already an app occupying that pid that hasn't been cleaned up
3813                if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
3814                    // Clean up anything relating to this pid first
3815                    Slog.w(TAG, "Reusing pid " + startResult.pid
3816                            + " while app is still mapped to it");
3817                    cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3818                            true /*replacingPid*/);
3819                }
3820                this.mPidsSelfLocked.put(startResult.pid, app);
3821                if (isActivityProcess) {
3822                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3823                    msg.obj = app;
3824                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3825                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3826                }
3827            }
3828            checkTime(startTime, "startProcess: done updating pids map");
3829        } catch (RuntimeException e) {
3830            Slog.e(TAG, "Failure starting process " + app.processName, e);
3831
3832            // Something went very wrong while trying to start this process; one
3833            // common case is when the package is frozen due to an active
3834            // upgrade. To recover, clean up any active bookkeeping related to
3835            // starting this process. (We already invoked this method once when
3836            // the package was initially frozen through KILL_APPLICATION_MSG, so
3837            // it doesn't hurt to use it again.)
3838            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3839                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3840        }
3841    }
3842
3843    void updateUsageStats(ActivityRecord component, boolean resumed) {
3844        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3845                "updateUsageStats: comp=" + component + "res=" + resumed);
3846        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3847        if (resumed) {
3848            if (mUsageStatsService != null) {
3849                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3850                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3851            }
3852            synchronized (stats) {
3853                stats.noteActivityResumedLocked(component.app.uid);
3854            }
3855        } else {
3856            if (mUsageStatsService != null) {
3857                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3858                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3859            }
3860            synchronized (stats) {
3861                stats.noteActivityPausedLocked(component.app.uid);
3862            }
3863        }
3864    }
3865
3866    Intent getHomeIntent() {
3867        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3868        intent.setComponent(mTopComponent);
3869        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3870        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3871            intent.addCategory(Intent.CATEGORY_HOME);
3872        }
3873        return intent;
3874    }
3875
3876    boolean startHomeActivityLocked(int userId, String reason) {
3877        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3878                && mTopAction == null) {
3879            // We are running in factory test mode, but unable to find
3880            // the factory test app, so just sit around displaying the
3881            // error message and don't try to start anything.
3882            return false;
3883        }
3884        Intent intent = getHomeIntent();
3885        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3886        if (aInfo != null) {
3887            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3888            // Don't do this if the home app is currently being
3889            // instrumented.
3890            aInfo = new ActivityInfo(aInfo);
3891            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3892            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3893                    aInfo.applicationInfo.uid, true);
3894            if (app == null || app.instrumentationClass == null) {
3895                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3896                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3897            }
3898        } else {
3899            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3900        }
3901
3902        return true;
3903    }
3904
3905    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3906        ActivityInfo ai = null;
3907        ComponentName comp = intent.getComponent();
3908        try {
3909            if (comp != null) {
3910                // Factory test.
3911                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3912            } else {
3913                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3914                        intent,
3915                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3916                        flags, userId);
3917
3918                if (info != null) {
3919                    ai = info.activityInfo;
3920                }
3921            }
3922        } catch (RemoteException e) {
3923            // ignore
3924        }
3925
3926        return ai;
3927    }
3928
3929    /**
3930     * Starts the "new version setup screen" if appropriate.
3931     */
3932    void startSetupActivityLocked() {
3933        // Only do this once per boot.
3934        if (mCheckedForSetup) {
3935            return;
3936        }
3937
3938        // We will show this screen if the current one is a different
3939        // version than the last one shown, and we are not running in
3940        // low-level factory test mode.
3941        final ContentResolver resolver = mContext.getContentResolver();
3942        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3943                Settings.Global.getInt(resolver,
3944                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3945            mCheckedForSetup = true;
3946
3947            // See if we should be showing the platform update setup UI.
3948            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3949            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3950                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3951            if (!ris.isEmpty()) {
3952                final ResolveInfo ri = ris.get(0);
3953                String vers = ri.activityInfo.metaData != null
3954                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3955                        : null;
3956                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3957                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3958                            Intent.METADATA_SETUP_VERSION);
3959                }
3960                String lastVers = Settings.Secure.getString(
3961                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3962                if (vers != null && !vers.equals(lastVers)) {
3963                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3964                    intent.setComponent(new ComponentName(
3965                            ri.activityInfo.packageName, ri.activityInfo.name));
3966                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3967                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3968                            null, 0, 0, 0, null, false, false, null, null, null);
3969                }
3970            }
3971        }
3972    }
3973
3974    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3975        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3976    }
3977
3978    void enforceNotIsolatedCaller(String caller) {
3979        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3980            throw new SecurityException("Isolated process not allowed to call " + caller);
3981        }
3982    }
3983
3984    void enforceShellRestriction(String restriction, int userHandle) {
3985        if (Binder.getCallingUid() == Process.SHELL_UID) {
3986            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3987                throw new SecurityException("Shell does not have permission to access user "
3988                        + userHandle);
3989            }
3990        }
3991    }
3992
3993    @Override
3994    public int getFrontActivityScreenCompatMode() {
3995        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3996        synchronized (this) {
3997            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3998        }
3999    }
4000
4001    @Override
4002    public void setFrontActivityScreenCompatMode(int mode) {
4003        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4004                "setFrontActivityScreenCompatMode");
4005        synchronized (this) {
4006            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4007        }
4008    }
4009
4010    @Override
4011    public int getPackageScreenCompatMode(String packageName) {
4012        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4013        synchronized (this) {
4014            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4015        }
4016    }
4017
4018    @Override
4019    public void setPackageScreenCompatMode(String packageName, int mode) {
4020        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4021                "setPackageScreenCompatMode");
4022        synchronized (this) {
4023            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4024        }
4025    }
4026
4027    @Override
4028    public boolean getPackageAskScreenCompat(String packageName) {
4029        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4030        synchronized (this) {
4031            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4032        }
4033    }
4034
4035    @Override
4036    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4037        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4038                "setPackageAskScreenCompat");
4039        synchronized (this) {
4040            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4041        }
4042    }
4043
4044    private boolean hasUsageStatsPermission(String callingPackage) {
4045        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4046                Binder.getCallingUid(), callingPackage);
4047        if (mode == AppOpsManager.MODE_DEFAULT) {
4048            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4049                    == PackageManager.PERMISSION_GRANTED;
4050        }
4051        return mode == AppOpsManager.MODE_ALLOWED;
4052    }
4053
4054    @Override
4055    public int getPackageProcessState(String packageName, String callingPackage) {
4056        if (!hasUsageStatsPermission(callingPackage)) {
4057            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4058                    "getPackageProcessState");
4059        }
4060
4061        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4062        synchronized (this) {
4063            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4064                final ProcessRecord proc = mLruProcesses.get(i);
4065                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4066                        || procState > proc.setProcState) {
4067                    boolean found = false;
4068                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4069                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4070                            procState = proc.setProcState;
4071                            found = true;
4072                        }
4073                    }
4074                    if (proc.pkgDeps != null && !found) {
4075                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4076                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4077                                procState = proc.setProcState;
4078                                break;
4079                            }
4080                        }
4081                    }
4082                }
4083            }
4084        }
4085        return procState;
4086    }
4087
4088    @Override
4089    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4090        synchronized (this) {
4091            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4092            if (app == null) {
4093                return false;
4094            }
4095            if (app.trimMemoryLevel < level && app.thread != null &&
4096                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4097                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4098                try {
4099                    app.thread.scheduleTrimMemory(level);
4100                    app.trimMemoryLevel = level;
4101                    return true;
4102                } catch (RemoteException e) {
4103                    // Fallthrough to failure case.
4104                }
4105            }
4106        }
4107        return false;
4108    }
4109
4110    private void dispatchProcessesChanged() {
4111        int N;
4112        synchronized (this) {
4113            N = mPendingProcessChanges.size();
4114            if (mActiveProcessChanges.length < N) {
4115                mActiveProcessChanges = new ProcessChangeItem[N];
4116            }
4117            mPendingProcessChanges.toArray(mActiveProcessChanges);
4118            mPendingProcessChanges.clear();
4119            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4120                    "*** Delivering " + N + " process changes");
4121        }
4122
4123        int i = mProcessObservers.beginBroadcast();
4124        while (i > 0) {
4125            i--;
4126            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4127            if (observer != null) {
4128                try {
4129                    for (int j=0; j<N; j++) {
4130                        ProcessChangeItem item = mActiveProcessChanges[j];
4131                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4132                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4133                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4134                                    + item.uid + ": " + item.foregroundActivities);
4135                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4136                                    item.foregroundActivities);
4137                        }
4138                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4139                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4140                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4141                                    + ": " + item.processState);
4142                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4143                        }
4144                    }
4145                } catch (RemoteException e) {
4146                }
4147            }
4148        }
4149        mProcessObservers.finishBroadcast();
4150
4151        synchronized (this) {
4152            for (int j=0; j<N; j++) {
4153                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4154            }
4155        }
4156    }
4157
4158    private void dispatchProcessDied(int pid, int uid) {
4159        int i = mProcessObservers.beginBroadcast();
4160        while (i > 0) {
4161            i--;
4162            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4163            if (observer != null) {
4164                try {
4165                    observer.onProcessDied(pid, uid);
4166                } catch (RemoteException e) {
4167                }
4168            }
4169        }
4170        mProcessObservers.finishBroadcast();
4171    }
4172
4173    private void dispatchUidsChanged() {
4174        int N;
4175        synchronized (this) {
4176            N = mPendingUidChanges.size();
4177            if (mActiveUidChanges.length < N) {
4178                mActiveUidChanges = new UidRecord.ChangeItem[N];
4179            }
4180            for (int i=0; i<N; i++) {
4181                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4182                mActiveUidChanges[i] = change;
4183                if (change.uidRecord != null) {
4184                    change.uidRecord.pendingChange = null;
4185                    change.uidRecord = null;
4186                }
4187            }
4188            mPendingUidChanges.clear();
4189            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4190                    "*** Delivering " + N + " uid changes");
4191        }
4192
4193        if (mLocalPowerManager != null) {
4194            for (int j=0; j<N; j++) {
4195                UidRecord.ChangeItem item = mActiveUidChanges[j];
4196                if (item.change == UidRecord.CHANGE_GONE
4197                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4198                    mLocalPowerManager.uidGone(item.uid);
4199                } else {
4200                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4201                }
4202            }
4203        }
4204
4205        int i = mUidObservers.beginBroadcast();
4206        while (i > 0) {
4207            i--;
4208            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4209            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4210            if (observer != null) {
4211                try {
4212                    for (int j=0; j<N; j++) {
4213                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4214                        final int change = item.change;
4215                        UidRecord validateUid = null;
4216                        if (VALIDATE_UID_STATES && i == 0) {
4217                            validateUid = mValidateUids.get(item.uid);
4218                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4219                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4220                                validateUid = new UidRecord(item.uid);
4221                                mValidateUids.put(item.uid, validateUid);
4222                            }
4223                        }
4224                        if (change == UidRecord.CHANGE_IDLE
4225                                || change == UidRecord.CHANGE_GONE_IDLE) {
4226                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4227                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4228                                        "UID idle uid=" + item.uid);
4229                                observer.onUidIdle(item.uid);
4230                            }
4231                            if (VALIDATE_UID_STATES && i == 0) {
4232                                if (validateUid != null) {
4233                                    validateUid.idle = true;
4234                                }
4235                            }
4236                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4237                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4238                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4239                                        "UID active uid=" + item.uid);
4240                                observer.onUidActive(item.uid);
4241                            }
4242                            if (VALIDATE_UID_STATES && i == 0) {
4243                                validateUid.idle = false;
4244                            }
4245                        }
4246                        if (change == UidRecord.CHANGE_GONE
4247                                || change == UidRecord.CHANGE_GONE_IDLE) {
4248                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4249                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4250                                        "UID gone uid=" + item.uid);
4251                                observer.onUidGone(item.uid);
4252                            }
4253                            if (VALIDATE_UID_STATES && i == 0) {
4254                                if (validateUid != null) {
4255                                    mValidateUids.remove(item.uid);
4256                                }
4257                            }
4258                        } else {
4259                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4260                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4261                                        "UID CHANGED uid=" + item.uid
4262                                                + ": " + item.processState);
4263                                observer.onUidStateChanged(item.uid, item.processState);
4264                            }
4265                            if (VALIDATE_UID_STATES && i == 0) {
4266                                validateUid.curProcState = validateUid.setProcState
4267                                        = item.processState;
4268                            }
4269                        }
4270                    }
4271                } catch (RemoteException e) {
4272                }
4273            }
4274        }
4275        mUidObservers.finishBroadcast();
4276
4277        synchronized (this) {
4278            for (int j=0; j<N; j++) {
4279                mAvailUidChanges.add(mActiveUidChanges[j]);
4280            }
4281        }
4282    }
4283
4284    @Override
4285    public final int startActivity(IApplicationThread caller, String callingPackage,
4286            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4287            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4288        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4289                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4290                UserHandle.getCallingUserId());
4291    }
4292
4293    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4294        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4295        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4296                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4297                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4298
4299        // TODO: Switch to user app stacks here.
4300        String mimeType = intent.getType();
4301        final Uri data = intent.getData();
4302        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4303            mimeType = getProviderMimeType(data, userId);
4304        }
4305        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4306
4307        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4308        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4309                null, 0, 0, null, null, null, null, false, userId, container, null);
4310    }
4311
4312    @Override
4313    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4314            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4315            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4316        enforceNotIsolatedCaller("startActivity");
4317        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4318                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4319        // TODO: Switch to user app stacks here.
4320        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4321                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4322                profilerInfo, null, null, bOptions, false, userId, null, null);
4323    }
4324
4325    @Override
4326    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4327            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4328            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4329            int userId) {
4330
4331        // This is very dangerous -- it allows you to perform a start activity (including
4332        // permission grants) as any app that may launch one of your own activities.  So
4333        // we will only allow this to be done from activities that are part of the core framework,
4334        // and then only when they are running as the system.
4335        final ActivityRecord sourceRecord;
4336        final int targetUid;
4337        final String targetPackage;
4338        synchronized (this) {
4339            if (resultTo == null) {
4340                throw new SecurityException("Must be called from an activity");
4341            }
4342            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4343            if (sourceRecord == null) {
4344                throw new SecurityException("Called with bad activity token: " + resultTo);
4345            }
4346            if (!sourceRecord.info.packageName.equals("android")) {
4347                throw new SecurityException(
4348                        "Must be called from an activity that is declared in the android package");
4349            }
4350            if (sourceRecord.app == null) {
4351                throw new SecurityException("Called without a process attached to activity");
4352            }
4353            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4354                // This is still okay, as long as this activity is running under the
4355                // uid of the original calling activity.
4356                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4357                    throw new SecurityException(
4358                            "Calling activity in uid " + sourceRecord.app.uid
4359                                    + " must be system uid or original calling uid "
4360                                    + sourceRecord.launchedFromUid);
4361                }
4362            }
4363            if (ignoreTargetSecurity) {
4364                if (intent.getComponent() == null) {
4365                    throw new SecurityException(
4366                            "Component must be specified with ignoreTargetSecurity");
4367                }
4368                if (intent.getSelector() != null) {
4369                    throw new SecurityException(
4370                            "Selector not allowed with ignoreTargetSecurity");
4371                }
4372            }
4373            targetUid = sourceRecord.launchedFromUid;
4374            targetPackage = sourceRecord.launchedFromPackage;
4375        }
4376
4377        if (userId == UserHandle.USER_NULL) {
4378            userId = UserHandle.getUserId(sourceRecord.app.uid);
4379        }
4380
4381        // TODO: Switch to user app stacks here.
4382        try {
4383            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4384                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4385                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4386            return ret;
4387        } catch (SecurityException e) {
4388            // XXX need to figure out how to propagate to original app.
4389            // A SecurityException here is generally actually a fault of the original
4390            // calling activity (such as a fairly granting permissions), so propagate it
4391            // back to them.
4392            /*
4393            StringBuilder msg = new StringBuilder();
4394            msg.append("While launching");
4395            msg.append(intent.toString());
4396            msg.append(": ");
4397            msg.append(e.getMessage());
4398            */
4399            throw e;
4400        }
4401    }
4402
4403    @Override
4404    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4405            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4406            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4407        enforceNotIsolatedCaller("startActivityAndWait");
4408        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4409                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4410        WaitResult res = new WaitResult();
4411        // TODO: Switch to user app stacks here.
4412        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4413                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4414                bOptions, false, userId, null, null);
4415        return res;
4416    }
4417
4418    @Override
4419    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4420            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4421            int startFlags, Configuration config, Bundle bOptions, int userId) {
4422        enforceNotIsolatedCaller("startActivityWithConfig");
4423        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4424                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4425        // TODO: Switch to user app stacks here.
4426        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4427                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4428                null, null, config, bOptions, false, userId, null, null);
4429        return ret;
4430    }
4431
4432    @Override
4433    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4434            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4435            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4436            throws TransactionTooLargeException {
4437        enforceNotIsolatedCaller("startActivityIntentSender");
4438        // Refuse possible leaked file descriptors
4439        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4440            throw new IllegalArgumentException("File descriptors passed in Intent");
4441        }
4442
4443        IIntentSender sender = intent.getTarget();
4444        if (!(sender instanceof PendingIntentRecord)) {
4445            throw new IllegalArgumentException("Bad PendingIntent object");
4446        }
4447
4448        PendingIntentRecord pir = (PendingIntentRecord)sender;
4449
4450        synchronized (this) {
4451            // If this is coming from the currently resumed activity, it is
4452            // effectively saying that app switches are allowed at this point.
4453            final ActivityStack stack = getFocusedStack();
4454            if (stack.mResumedActivity != null &&
4455                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4456                mAppSwitchesAllowedTime = 0;
4457            }
4458        }
4459        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4460                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4461        return ret;
4462    }
4463
4464    @Override
4465    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4466            Intent intent, String resolvedType, IVoiceInteractionSession session,
4467            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4468            Bundle bOptions, int userId) {
4469        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4470                != PackageManager.PERMISSION_GRANTED) {
4471            String msg = "Permission Denial: startVoiceActivity() from pid="
4472                    + Binder.getCallingPid()
4473                    + ", uid=" + Binder.getCallingUid()
4474                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4475            Slog.w(TAG, msg);
4476            throw new SecurityException(msg);
4477        }
4478        if (session == null || interactor == null) {
4479            throw new NullPointerException("null session or interactor");
4480        }
4481        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4482                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4483        // TODO: Switch to user app stacks here.
4484        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4485                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4486                null, bOptions, false, userId, null, null);
4487    }
4488
4489    @Override
4490    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4491            throws RemoteException {
4492        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4493        synchronized (this) {
4494            ActivityRecord activity = getFocusedStack().topActivity();
4495            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4496                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4497            }
4498            if (mRunningVoice != null || activity.task.voiceSession != null
4499                    || activity.voiceSession != null) {
4500                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4501                return;
4502            }
4503            if (activity.pendingVoiceInteractionStart) {
4504                Slog.w(TAG, "Pending start of voice interaction already.");
4505                return;
4506            }
4507            activity.pendingVoiceInteractionStart = true;
4508        }
4509        LocalServices.getService(VoiceInteractionManagerInternal.class)
4510                .startLocalVoiceInteraction(callingActivity, options);
4511    }
4512
4513    @Override
4514    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4515        LocalServices.getService(VoiceInteractionManagerInternal.class)
4516                .stopLocalVoiceInteraction(callingActivity);
4517    }
4518
4519    @Override
4520    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4521        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4522                .supportsLocalVoiceInteraction();
4523    }
4524
4525    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4526            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4527        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4528        if (activityToCallback == null) return;
4529        activityToCallback.setVoiceSessionLocked(voiceSession);
4530
4531        // Inform the activity
4532        try {
4533            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4534                    voiceInteractor);
4535            long token = Binder.clearCallingIdentity();
4536            try {
4537                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4538            } finally {
4539                Binder.restoreCallingIdentity(token);
4540            }
4541            // TODO: VI Should we cache the activity so that it's easier to find later
4542            // rather than scan through all the stacks and activities?
4543        } catch (RemoteException re) {
4544            activityToCallback.clearVoiceSessionLocked();
4545            // TODO: VI Should this terminate the voice session?
4546        }
4547    }
4548
4549    @Override
4550    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4551        synchronized (this) {
4552            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4553                if (keepAwake) {
4554                    mVoiceWakeLock.acquire();
4555                } else {
4556                    mVoiceWakeLock.release();
4557                }
4558            }
4559        }
4560    }
4561
4562    @Override
4563    public boolean startNextMatchingActivity(IBinder callingActivity,
4564            Intent intent, Bundle bOptions) {
4565        // Refuse possible leaked file descriptors
4566        if (intent != null && intent.hasFileDescriptors() == true) {
4567            throw new IllegalArgumentException("File descriptors passed in Intent");
4568        }
4569        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4570
4571        synchronized (this) {
4572            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4573            if (r == null) {
4574                ActivityOptions.abort(options);
4575                return false;
4576            }
4577            if (r.app == null || r.app.thread == null) {
4578                // The caller is not running...  d'oh!
4579                ActivityOptions.abort(options);
4580                return false;
4581            }
4582            intent = new Intent(intent);
4583            // The caller is not allowed to change the data.
4584            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4585            // And we are resetting to find the next component...
4586            intent.setComponent(null);
4587
4588            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4589
4590            ActivityInfo aInfo = null;
4591            try {
4592                List<ResolveInfo> resolves =
4593                    AppGlobals.getPackageManager().queryIntentActivities(
4594                            intent, r.resolvedType,
4595                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4596                            UserHandle.getCallingUserId()).getList();
4597
4598                // Look for the original activity in the list...
4599                final int N = resolves != null ? resolves.size() : 0;
4600                for (int i=0; i<N; i++) {
4601                    ResolveInfo rInfo = resolves.get(i);
4602                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4603                            && rInfo.activityInfo.name.equals(r.info.name)) {
4604                        // We found the current one...  the next matching is
4605                        // after it.
4606                        i++;
4607                        if (i<N) {
4608                            aInfo = resolves.get(i).activityInfo;
4609                        }
4610                        if (debug) {
4611                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4612                                    + "/" + r.info.name);
4613                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4614                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4615                        }
4616                        break;
4617                    }
4618                }
4619            } catch (RemoteException e) {
4620            }
4621
4622            if (aInfo == null) {
4623                // Nobody who is next!
4624                ActivityOptions.abort(options);
4625                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4626                return false;
4627            }
4628
4629            intent.setComponent(new ComponentName(
4630                    aInfo.applicationInfo.packageName, aInfo.name));
4631            intent.setFlags(intent.getFlags()&~(
4632                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4633                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4634                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4635                    Intent.FLAG_ACTIVITY_NEW_TASK));
4636
4637            // Okay now we need to start the new activity, replacing the
4638            // currently running activity.  This is a little tricky because
4639            // we want to start the new one as if the current one is finished,
4640            // but not finish the current one first so that there is no flicker.
4641            // And thus...
4642            final boolean wasFinishing = r.finishing;
4643            r.finishing = true;
4644
4645            // Propagate reply information over to the new activity.
4646            final ActivityRecord resultTo = r.resultTo;
4647            final String resultWho = r.resultWho;
4648            final int requestCode = r.requestCode;
4649            r.resultTo = null;
4650            if (resultTo != null) {
4651                resultTo.removeResultsLocked(r, resultWho, requestCode);
4652            }
4653
4654            final long origId = Binder.clearCallingIdentity();
4655            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4656                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4657                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4658                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4659                    false, false, null, null, null);
4660            Binder.restoreCallingIdentity(origId);
4661
4662            r.finishing = wasFinishing;
4663            if (res != ActivityManager.START_SUCCESS) {
4664                return false;
4665            }
4666            return true;
4667        }
4668    }
4669
4670    @Override
4671    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4672        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4673            String msg = "Permission Denial: startActivityFromRecents called without " +
4674                    START_TASKS_FROM_RECENTS;
4675            Slog.w(TAG, msg);
4676            throw new SecurityException(msg);
4677        }
4678        final long origId = Binder.clearCallingIdentity();
4679        try {
4680            synchronized (this) {
4681                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4682            }
4683        } finally {
4684            Binder.restoreCallingIdentity(origId);
4685        }
4686    }
4687
4688    final int startActivityInPackage(int uid, String callingPackage,
4689            Intent intent, String resolvedType, IBinder resultTo,
4690            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4691            IActivityContainer container, TaskRecord inTask) {
4692
4693        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4694                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4695
4696        // TODO: Switch to user app stacks here.
4697        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4698                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4699                null, null, null, bOptions, false, userId, container, inTask);
4700        return ret;
4701    }
4702
4703    @Override
4704    public final int startActivities(IApplicationThread caller, String callingPackage,
4705            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4706            int userId) {
4707        enforceNotIsolatedCaller("startActivities");
4708        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4709                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4710        // TODO: Switch to user app stacks here.
4711        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4712                resolvedTypes, resultTo, bOptions, userId);
4713        return ret;
4714    }
4715
4716    final int startActivitiesInPackage(int uid, String callingPackage,
4717            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4718            Bundle bOptions, int userId) {
4719
4720        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4721                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4722        // TODO: Switch to user app stacks here.
4723        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4724                resultTo, bOptions, userId);
4725        return ret;
4726    }
4727
4728    @Override
4729    public void reportActivityFullyDrawn(IBinder token) {
4730        synchronized (this) {
4731            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4732            if (r == null) {
4733                return;
4734            }
4735            r.reportFullyDrawnLocked();
4736        }
4737    }
4738
4739    @Override
4740    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4741        synchronized (this) {
4742            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4743            if (r == null) {
4744                return;
4745            }
4746            TaskRecord task = r.task;
4747            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4748                // Fixed screen orientation isn't supported when activities aren't in full screen
4749                // mode.
4750                return;
4751            }
4752            final long origId = Binder.clearCallingIdentity();
4753            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4754            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4755                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4756            if (config != null) {
4757                r.frozenBeforeDestroy = true;
4758                if (!updateConfigurationLocked(config, r, false)) {
4759                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4760                }
4761            }
4762            Binder.restoreCallingIdentity(origId);
4763        }
4764    }
4765
4766    @Override
4767    public int getRequestedOrientation(IBinder token) {
4768        synchronized (this) {
4769            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4770            if (r == null) {
4771                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4772            }
4773            return mWindowManager.getAppOrientation(r.appToken);
4774        }
4775    }
4776
4777    /**
4778     * This is the internal entry point for handling Activity.finish().
4779     *
4780     * @param token The Binder token referencing the Activity we want to finish.
4781     * @param resultCode Result code, if any, from this Activity.
4782     * @param resultData Result data (Intent), if any, from this Activity.
4783     * @param finishTask Whether to finish the task associated with this Activity.
4784     *
4785     * @return Returns true if the activity successfully finished, or false if it is still running.
4786     */
4787    @Override
4788    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4789            int finishTask) {
4790        // Refuse possible leaked file descriptors
4791        if (resultData != null && resultData.hasFileDescriptors() == true) {
4792            throw new IllegalArgumentException("File descriptors passed in Intent");
4793        }
4794
4795        synchronized(this) {
4796            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4797            if (r == null) {
4798                return true;
4799            }
4800            // Keep track of the root activity of the task before we finish it
4801            TaskRecord tr = r.task;
4802            ActivityRecord rootR = tr.getRootActivity();
4803            if (rootR == null) {
4804                Slog.w(TAG, "Finishing task with all activities already finished");
4805            }
4806            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4807            // finish.
4808            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4809                    mStackSupervisor.isLastLockedTask(tr)) {
4810                Slog.i(TAG, "Not finishing task in lock task mode");
4811                mStackSupervisor.showLockTaskToast();
4812                return false;
4813            }
4814            if (mController != null) {
4815                // Find the first activity that is not finishing.
4816                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4817                if (next != null) {
4818                    // ask watcher if this is allowed
4819                    boolean resumeOK = true;
4820                    try {
4821                        resumeOK = mController.activityResuming(next.packageName);
4822                    } catch (RemoteException e) {
4823                        mController = null;
4824                        Watchdog.getInstance().setActivityController(null);
4825                    }
4826
4827                    if (!resumeOK) {
4828                        Slog.i(TAG, "Not finishing activity because controller resumed");
4829                        return false;
4830                    }
4831                }
4832            }
4833            final long origId = Binder.clearCallingIdentity();
4834            try {
4835                boolean res;
4836                final boolean finishWithRootActivity =
4837                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4838                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4839                        || (finishWithRootActivity && r == rootR)) {
4840                    // If requested, remove the task that is associated to this activity only if it
4841                    // was the root activity in the task. The result code and data is ignored
4842                    // because we don't support returning them across task boundaries. Also, to
4843                    // keep backwards compatibility we remove the task from recents when finishing
4844                    // task with root activity.
4845                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4846                    if (!res) {
4847                        Slog.i(TAG, "Removing task failed to finish activity");
4848                    }
4849                } else {
4850                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4851                            resultData, "app-request", true);
4852                    if (!res) {
4853                        Slog.i(TAG, "Failed to finish by app-request");
4854                    }
4855                }
4856                return res;
4857            } finally {
4858                Binder.restoreCallingIdentity(origId);
4859            }
4860        }
4861    }
4862
4863    @Override
4864    public final void finishHeavyWeightApp() {
4865        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4866                != PackageManager.PERMISSION_GRANTED) {
4867            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4868                    + Binder.getCallingPid()
4869                    + ", uid=" + Binder.getCallingUid()
4870                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4871            Slog.w(TAG, msg);
4872            throw new SecurityException(msg);
4873        }
4874
4875        synchronized(this) {
4876            if (mHeavyWeightProcess == null) {
4877                return;
4878            }
4879
4880            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4881            for (int i = 0; i < activities.size(); i++) {
4882                ActivityRecord r = activities.get(i);
4883                if (!r.finishing && r.isInStackLocked()) {
4884                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4885                            null, "finish-heavy", true);
4886                }
4887            }
4888
4889            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4890                    mHeavyWeightProcess.userId, 0));
4891            mHeavyWeightProcess = null;
4892        }
4893    }
4894
4895    @Override
4896    public void crashApplication(int uid, int initialPid, String packageName,
4897            String message) {
4898        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4899                != PackageManager.PERMISSION_GRANTED) {
4900            String msg = "Permission Denial: crashApplication() from pid="
4901                    + Binder.getCallingPid()
4902                    + ", uid=" + Binder.getCallingUid()
4903                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4904            Slog.w(TAG, msg);
4905            throw new SecurityException(msg);
4906        }
4907
4908        synchronized(this) {
4909            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4910        }
4911    }
4912
4913    @Override
4914    public final void finishSubActivity(IBinder token, String resultWho,
4915            int requestCode) {
4916        synchronized(this) {
4917            final long origId = Binder.clearCallingIdentity();
4918            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919            if (r != null) {
4920                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4921            }
4922            Binder.restoreCallingIdentity(origId);
4923        }
4924    }
4925
4926    @Override
4927    public boolean finishActivityAffinity(IBinder token) {
4928        synchronized(this) {
4929            final long origId = Binder.clearCallingIdentity();
4930            try {
4931                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4932                if (r == null) {
4933                    return false;
4934                }
4935
4936                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4937                // can finish.
4938                final TaskRecord task = r.task;
4939                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4940                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4941                    mStackSupervisor.showLockTaskToast();
4942                    return false;
4943                }
4944                return task.stack.finishActivityAffinityLocked(r);
4945            } finally {
4946                Binder.restoreCallingIdentity(origId);
4947            }
4948        }
4949    }
4950
4951    @Override
4952    public void finishVoiceTask(IVoiceInteractionSession session) {
4953        synchronized (this) {
4954            final long origId = Binder.clearCallingIdentity();
4955            try {
4956                // TODO: VI Consider treating local voice interactions and voice tasks
4957                // differently here
4958                mStackSupervisor.finishVoiceTask(session);
4959            } finally {
4960                Binder.restoreCallingIdentity(origId);
4961            }
4962        }
4963
4964    }
4965
4966    @Override
4967    public boolean releaseActivityInstance(IBinder token) {
4968        synchronized(this) {
4969            final long origId = Binder.clearCallingIdentity();
4970            try {
4971                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972                if (r == null) {
4973                    return false;
4974                }
4975                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4976            } finally {
4977                Binder.restoreCallingIdentity(origId);
4978            }
4979        }
4980    }
4981
4982    @Override
4983    public void releaseSomeActivities(IApplicationThread appInt) {
4984        synchronized(this) {
4985            final long origId = Binder.clearCallingIdentity();
4986            try {
4987                ProcessRecord app = getRecordForAppLocked(appInt);
4988                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4989            } finally {
4990                Binder.restoreCallingIdentity(origId);
4991            }
4992        }
4993    }
4994
4995    @Override
4996    public boolean willActivityBeVisible(IBinder token) {
4997        synchronized(this) {
4998            ActivityStack stack = ActivityRecord.getStackLocked(token);
4999            if (stack != null) {
5000                return stack.willActivityBeVisibleLocked(token);
5001            }
5002            return false;
5003        }
5004    }
5005
5006    @Override
5007    public void overridePendingTransition(IBinder token, String packageName,
5008            int enterAnim, int exitAnim) {
5009        synchronized(this) {
5010            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5011            if (self == null) {
5012                return;
5013            }
5014
5015            final long origId = Binder.clearCallingIdentity();
5016
5017            if (self.state == ActivityState.RESUMED
5018                    || self.state == ActivityState.PAUSING) {
5019                mWindowManager.overridePendingAppTransition(packageName,
5020                        enterAnim, exitAnim, null);
5021            }
5022
5023            Binder.restoreCallingIdentity(origId);
5024        }
5025    }
5026
5027    /**
5028     * Main function for removing an existing process from the activity manager
5029     * as a result of that process going away.  Clears out all connections
5030     * to the process.
5031     */
5032    private final void handleAppDiedLocked(ProcessRecord app,
5033            boolean restarting, boolean allowRestart) {
5034        int pid = app.pid;
5035        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5036                false /*replacingPid*/);
5037        if (!kept && !restarting) {
5038            removeLruProcessLocked(app);
5039            if (pid > 0) {
5040                ProcessList.remove(pid);
5041            }
5042        }
5043
5044        if (mProfileProc == app) {
5045            clearProfilerLocked();
5046        }
5047
5048        // Remove this application's activities from active lists.
5049        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5050
5051        app.activities.clear();
5052
5053        if (app.instrumentationClass != null) {
5054            Slog.w(TAG, "Crash of app " + app.processName
5055                  + " running instrumentation " + app.instrumentationClass);
5056            Bundle info = new Bundle();
5057            info.putString("shortMsg", "Process crashed.");
5058            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5059        }
5060
5061        if (!restarting && hasVisibleActivities
5062                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5063            // If there was nothing to resume, and we are not already restarting this process, but
5064            // there is a visible activity that is hosted by the process...  then make sure all
5065            // visible activities are running, taking care of restarting this process.
5066            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5067        }
5068    }
5069
5070    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5071        IBinder threadBinder = thread.asBinder();
5072        // Find the application record.
5073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5074            ProcessRecord rec = mLruProcesses.get(i);
5075            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5076                return i;
5077            }
5078        }
5079        return -1;
5080    }
5081
5082    final ProcessRecord getRecordForAppLocked(
5083            IApplicationThread thread) {
5084        if (thread == null) {
5085            return null;
5086        }
5087
5088        int appIndex = getLRURecordIndexForAppLocked(thread);
5089        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5090    }
5091
5092    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5093        // If there are no longer any background processes running,
5094        // and the app that died was not running instrumentation,
5095        // then tell everyone we are now low on memory.
5096        boolean haveBg = false;
5097        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5098            ProcessRecord rec = mLruProcesses.get(i);
5099            if (rec.thread != null
5100                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5101                haveBg = true;
5102                break;
5103            }
5104        }
5105
5106        if (!haveBg) {
5107            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5108            if (doReport) {
5109                long now = SystemClock.uptimeMillis();
5110                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5111                    doReport = false;
5112                } else {
5113                    mLastMemUsageReportTime = now;
5114                }
5115            }
5116            final ArrayList<ProcessMemInfo> memInfos
5117                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5118            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5119            long now = SystemClock.uptimeMillis();
5120            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5121                ProcessRecord rec = mLruProcesses.get(i);
5122                if (rec == dyingProc || rec.thread == null) {
5123                    continue;
5124                }
5125                if (doReport) {
5126                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5127                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5128                }
5129                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5130                    // The low memory report is overriding any current
5131                    // state for a GC request.  Make sure to do
5132                    // heavy/important/visible/foreground processes first.
5133                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5134                        rec.lastRequestedGc = 0;
5135                    } else {
5136                        rec.lastRequestedGc = rec.lastLowMemory;
5137                    }
5138                    rec.reportLowMemory = true;
5139                    rec.lastLowMemory = now;
5140                    mProcessesToGc.remove(rec);
5141                    addProcessToGcListLocked(rec);
5142                }
5143            }
5144            if (doReport) {
5145                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5146                mHandler.sendMessage(msg);
5147            }
5148            scheduleAppGcsLocked();
5149        }
5150    }
5151
5152    final void appDiedLocked(ProcessRecord app) {
5153       appDiedLocked(app, app.pid, app.thread, false);
5154    }
5155
5156    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5157            boolean fromBinderDied) {
5158        // First check if this ProcessRecord is actually active for the pid.
5159        synchronized (mPidsSelfLocked) {
5160            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5161            if (curProc != app) {
5162                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5163                return;
5164            }
5165        }
5166
5167        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5168        synchronized (stats) {
5169            stats.noteProcessDiedLocked(app.info.uid, pid);
5170        }
5171
5172        if (!app.killed) {
5173            if (!fromBinderDied) {
5174                Process.killProcessQuiet(pid);
5175            }
5176            killProcessGroup(app.uid, pid);
5177            app.killed = true;
5178        }
5179
5180        // Clean up already done if the process has been re-started.
5181        if (app.pid == pid && app.thread != null &&
5182                app.thread.asBinder() == thread.asBinder()) {
5183            boolean doLowMem = app.instrumentationClass == null;
5184            boolean doOomAdj = doLowMem;
5185            if (!app.killedByAm) {
5186                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5187                        + ") has died");
5188                mAllowLowerMemLevel = true;
5189            } else {
5190                // Note that we always want to do oom adj to update our state with the
5191                // new number of procs.
5192                mAllowLowerMemLevel = false;
5193                doLowMem = false;
5194            }
5195            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5196            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5197                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5198            handleAppDiedLocked(app, false, true);
5199
5200            if (doOomAdj) {
5201                updateOomAdjLocked();
5202            }
5203            if (doLowMem) {
5204                doLowMemReportIfNeededLocked(app);
5205            }
5206        } else if (app.pid != pid) {
5207            // A new process has already been started.
5208            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5209                    + ") has died and restarted (pid " + app.pid + ").");
5210            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5211        } else if (DEBUG_PROCESSES) {
5212            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5213                    + thread.asBinder());
5214        }
5215    }
5216
5217    /**
5218     * If a stack trace dump file is configured, dump process stack traces.
5219     * @param clearTraces causes the dump file to be erased prior to the new
5220     *    traces being written, if true; when false, the new traces will be
5221     *    appended to any existing file content.
5222     * @param firstPids of dalvik VM processes to dump stack traces for first
5223     * @param lastPids of dalvik VM processes to dump stack traces for last
5224     * @param nativeProcs optional list of native process names to dump stack crawls
5225     * @return file containing stack traces, or null if no dump file is configured
5226     */
5227    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5228            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5229        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5230        if (tracesPath == null || tracesPath.length() == 0) {
5231            return null;
5232        }
5233
5234        File tracesFile = new File(tracesPath);
5235        try {
5236            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5237            tracesFile.createNewFile();
5238            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5239        } catch (IOException e) {
5240            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5241            return null;
5242        }
5243
5244        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5245        return tracesFile;
5246    }
5247
5248    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5249            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5250        // Use a FileObserver to detect when traces finish writing.
5251        // The order of traces is considered important to maintain for legibility.
5252        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5253            @Override
5254            public synchronized void onEvent(int event, String path) { notify(); }
5255        };
5256
5257        try {
5258            observer.startWatching();
5259
5260            // First collect all of the stacks of the most important pids.
5261            if (firstPids != null) {
5262                try {
5263                    int num = firstPids.size();
5264                    for (int i = 0; i < num; i++) {
5265                        synchronized (observer) {
5266                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5267                                    + firstPids.get(i));
5268                            final long sime = SystemClock.elapsedRealtime();
5269                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5270                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5271                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5272                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5273                        }
5274                    }
5275                } catch (InterruptedException e) {
5276                    Slog.wtf(TAG, e);
5277                }
5278            }
5279
5280            // Next collect the stacks of the native pids
5281            if (nativeProcs != null) {
5282                int[] pids = Process.getPidsForCommands(nativeProcs);
5283                if (pids != null) {
5284                    for (int pid : pids) {
5285                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5286                        final long sime = SystemClock.elapsedRealtime();
5287                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5288                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5289                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5290                    }
5291                }
5292            }
5293
5294            // Lastly, measure CPU usage.
5295            if (processCpuTracker != null) {
5296                processCpuTracker.init();
5297                System.gc();
5298                processCpuTracker.update();
5299                try {
5300                    synchronized (processCpuTracker) {
5301                        processCpuTracker.wait(500); // measure over 1/2 second.
5302                    }
5303                } catch (InterruptedException e) {
5304                }
5305                processCpuTracker.update();
5306
5307                // We'll take the stack crawls of just the top apps using CPU.
5308                final int N = processCpuTracker.countWorkingStats();
5309                int numProcs = 0;
5310                for (int i=0; i<N && numProcs<5; i++) {
5311                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5312                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5313                        numProcs++;
5314                        try {
5315                            synchronized (observer) {
5316                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5317                                        + stats.pid);
5318                                final long stime = SystemClock.elapsedRealtime();
5319                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5320                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5321                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5322                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5323                            }
5324                        } catch (InterruptedException e) {
5325                            Slog.wtf(TAG, e);
5326                        }
5327                    } else if (DEBUG_ANR) {
5328                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5329                                + stats.pid);
5330                    }
5331                }
5332            }
5333        } finally {
5334            observer.stopWatching();
5335        }
5336    }
5337
5338    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5339        if (true || IS_USER_BUILD) {
5340            return;
5341        }
5342        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5343        if (tracesPath == null || tracesPath.length() == 0) {
5344            return;
5345        }
5346
5347        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5348        StrictMode.allowThreadDiskWrites();
5349        try {
5350            final File tracesFile = new File(tracesPath);
5351            final File tracesDir = tracesFile.getParentFile();
5352            final File tracesTmp = new File(tracesDir, "__tmp__");
5353            try {
5354                if (tracesFile.exists()) {
5355                    tracesTmp.delete();
5356                    tracesFile.renameTo(tracesTmp);
5357                }
5358                StringBuilder sb = new StringBuilder();
5359                Time tobj = new Time();
5360                tobj.set(System.currentTimeMillis());
5361                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5362                sb.append(": ");
5363                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5364                sb.append(" since ");
5365                sb.append(msg);
5366                FileOutputStream fos = new FileOutputStream(tracesFile);
5367                fos.write(sb.toString().getBytes());
5368                if (app == null) {
5369                    fos.write("\n*** No application process!".getBytes());
5370                }
5371                fos.close();
5372                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5373            } catch (IOException e) {
5374                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5375                return;
5376            }
5377
5378            if (app != null) {
5379                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5380                firstPids.add(app.pid);
5381                dumpStackTraces(tracesPath, firstPids, null, null, null);
5382            }
5383
5384            File lastTracesFile = null;
5385            File curTracesFile = null;
5386            for (int i=9; i>=0; i--) {
5387                String name = String.format(Locale.US, "slow%02d.txt", i);
5388                curTracesFile = new File(tracesDir, name);
5389                if (curTracesFile.exists()) {
5390                    if (lastTracesFile != null) {
5391                        curTracesFile.renameTo(lastTracesFile);
5392                    } else {
5393                        curTracesFile.delete();
5394                    }
5395                }
5396                lastTracesFile = curTracesFile;
5397            }
5398            tracesFile.renameTo(curTracesFile);
5399            if (tracesTmp.exists()) {
5400                tracesTmp.renameTo(tracesFile);
5401            }
5402        } finally {
5403            StrictMode.setThreadPolicy(oldPolicy);
5404        }
5405    }
5406
5407    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5408        if (!mLaunchWarningShown) {
5409            mLaunchWarningShown = true;
5410            mUiHandler.post(new Runnable() {
5411                @Override
5412                public void run() {
5413                    synchronized (ActivityManagerService.this) {
5414                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5415                        d.show();
5416                        mUiHandler.postDelayed(new Runnable() {
5417                            @Override
5418                            public void run() {
5419                                synchronized (ActivityManagerService.this) {
5420                                    d.dismiss();
5421                                    mLaunchWarningShown = false;
5422                                }
5423                            }
5424                        }, 4000);
5425                    }
5426                }
5427            });
5428        }
5429    }
5430
5431    @Override
5432    public boolean clearApplicationUserData(final String packageName,
5433            final IPackageDataObserver observer, int userId) {
5434        enforceNotIsolatedCaller("clearApplicationUserData");
5435        int uid = Binder.getCallingUid();
5436        int pid = Binder.getCallingPid();
5437        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5438                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5439
5440
5441        long callingId = Binder.clearCallingIdentity();
5442        try {
5443            IPackageManager pm = AppGlobals.getPackageManager();
5444            int pkgUid = -1;
5445            synchronized(this) {
5446                if (getPackageManagerInternalLocked().canPackageBeWiped(
5447                        userId, packageName)) {
5448                    throw new SecurityException(
5449                            "Cannot clear data for a device owner or a profile owner");
5450                }
5451
5452                try {
5453                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5454                } catch (RemoteException e) {
5455                }
5456                if (pkgUid == -1) {
5457                    Slog.w(TAG, "Invalid packageName: " + packageName);
5458                    if (observer != null) {
5459                        try {
5460                            observer.onRemoveCompleted(packageName, false);
5461                        } catch (RemoteException e) {
5462                            Slog.i(TAG, "Observer no longer exists.");
5463                        }
5464                    }
5465                    return false;
5466                }
5467                if (uid == pkgUid || checkComponentPermission(
5468                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5469                        pid, uid, -1, true)
5470                        == PackageManager.PERMISSION_GRANTED) {
5471                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5472                } else {
5473                    throw new SecurityException("PID " + pid + " does not have permission "
5474                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5475                                    + " of package " + packageName);
5476                }
5477
5478                // Remove all tasks match the cleared application package and user
5479                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5480                    final TaskRecord tr = mRecentTasks.get(i);
5481                    final String taskPackageName =
5482                            tr.getBaseIntent().getComponent().getPackageName();
5483                    if (tr.userId != userId) continue;
5484                    if (!taskPackageName.equals(packageName)) continue;
5485                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5486                }
5487            }
5488
5489            final int pkgUidF = pkgUid;
5490            final int userIdF = userId;
5491            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5492                @Override
5493                public void onRemoveCompleted(String packageName, boolean succeeded)
5494                        throws RemoteException {
5495                    synchronized (ActivityManagerService.this) {
5496                        finishForceStopPackageLocked(packageName, pkgUidF);
5497                    }
5498
5499                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5500                            Uri.fromParts("package", packageName, null));
5501                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5502                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5503                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5504                            null, null, 0, null, null, null, null, false, false, userIdF);
5505
5506                    if (observer != null) {
5507                        observer.onRemoveCompleted(packageName, succeeded);
5508                    }
5509                }
5510            };
5511
5512            try {
5513                // Clear application user data
5514                pm.clearApplicationUserData(packageName, localObserver, userId);
5515
5516                synchronized(this) {
5517                    // Remove all permissions granted from/to this package
5518                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5519                }
5520
5521                // Remove all zen rules created by this package; revoke it's zen access.
5522                INotificationManager inm = NotificationManager.getService();
5523                inm.removeAutomaticZenRules(packageName);
5524                inm.setNotificationPolicyAccessGranted(packageName, false);
5525
5526            } catch (RemoteException e) {
5527            }
5528        } finally {
5529            Binder.restoreCallingIdentity(callingId);
5530        }
5531        return true;
5532    }
5533
5534    @Override
5535    public void killBackgroundProcesses(final String packageName, int userId) {
5536        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5537                != PackageManager.PERMISSION_GRANTED &&
5538                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5539                        != PackageManager.PERMISSION_GRANTED) {
5540            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5541                    + Binder.getCallingPid()
5542                    + ", uid=" + Binder.getCallingUid()
5543                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5544            Slog.w(TAG, msg);
5545            throw new SecurityException(msg);
5546        }
5547
5548        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5549                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5550        long callingId = Binder.clearCallingIdentity();
5551        try {
5552            IPackageManager pm = AppGlobals.getPackageManager();
5553            synchronized(this) {
5554                int appId = -1;
5555                try {
5556                    appId = UserHandle.getAppId(
5557                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5558                } catch (RemoteException e) {
5559                }
5560                if (appId == -1) {
5561                    Slog.w(TAG, "Invalid packageName: " + packageName);
5562                    return;
5563                }
5564                killPackageProcessesLocked(packageName, appId, userId,
5565                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5566            }
5567        } finally {
5568            Binder.restoreCallingIdentity(callingId);
5569        }
5570    }
5571
5572    @Override
5573    public void killAllBackgroundProcesses() {
5574        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5575                != PackageManager.PERMISSION_GRANTED) {
5576            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5577                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5578                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5579            Slog.w(TAG, msg);
5580            throw new SecurityException(msg);
5581        }
5582
5583        final long callingId = Binder.clearCallingIdentity();
5584        try {
5585            synchronized (this) {
5586                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5587                final int NP = mProcessNames.getMap().size();
5588                for (int ip = 0; ip < NP; ip++) {
5589                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5590                    final int NA = apps.size();
5591                    for (int ia = 0; ia < NA; ia++) {
5592                        final ProcessRecord app = apps.valueAt(ia);
5593                        if (app.persistent) {
5594                            // We don't kill persistent processes.
5595                            continue;
5596                        }
5597                        if (app.removed) {
5598                            procs.add(app);
5599                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5600                            app.removed = true;
5601                            procs.add(app);
5602                        }
5603                    }
5604                }
5605
5606                final int N = procs.size();
5607                for (int i = 0; i < N; i++) {
5608                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5609                }
5610
5611                mAllowLowerMemLevel = true;
5612
5613                updateOomAdjLocked();
5614                doLowMemReportIfNeededLocked(null);
5615            }
5616        } finally {
5617            Binder.restoreCallingIdentity(callingId);
5618        }
5619    }
5620
5621    /**
5622     * Kills all background processes, except those matching any of the
5623     * specified properties.
5624     *
5625     * @param minTargetSdk the target SDK version at or above which to preserve
5626     *                     processes, or {@code -1} to ignore the target SDK
5627     * @param maxProcState the process state at or below which to preserve
5628     *                     processes, or {@code -1} to ignore the process state
5629     */
5630    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5631        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5632                != PackageManager.PERMISSION_GRANTED) {
5633            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5634                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5635                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5636            Slog.w(TAG, msg);
5637            throw new SecurityException(msg);
5638        }
5639
5640        final long callingId = Binder.clearCallingIdentity();
5641        try {
5642            synchronized (this) {
5643                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5644                final int NP = mProcessNames.getMap().size();
5645                for (int ip = 0; ip < NP; ip++) {
5646                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5647                    final int NA = apps.size();
5648                    for (int ia = 0; ia < NA; ia++) {
5649                        final ProcessRecord app = apps.valueAt(ia);
5650                        if (app.removed) {
5651                            procs.add(app);
5652                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5653                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5654                            app.removed = true;
5655                            procs.add(app);
5656                        }
5657                    }
5658                }
5659
5660                final int N = procs.size();
5661                for (int i = 0; i < N; i++) {
5662                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5663                }
5664            }
5665        } finally {
5666            Binder.restoreCallingIdentity(callingId);
5667        }
5668    }
5669
5670    @Override
5671    public void forceStopPackage(final String packageName, int userId) {
5672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5673                != PackageManager.PERMISSION_GRANTED) {
5674            String msg = "Permission Denial: forceStopPackage() from pid="
5675                    + Binder.getCallingPid()
5676                    + ", uid=" + Binder.getCallingUid()
5677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5678            Slog.w(TAG, msg);
5679            throw new SecurityException(msg);
5680        }
5681        final int callingPid = Binder.getCallingPid();
5682        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5683                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5684        long callingId = Binder.clearCallingIdentity();
5685        try {
5686            IPackageManager pm = AppGlobals.getPackageManager();
5687            synchronized(this) {
5688                int[] users = userId == UserHandle.USER_ALL
5689                        ? mUserController.getUsers() : new int[] { userId };
5690                for (int user : users) {
5691                    int pkgUid = -1;
5692                    try {
5693                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5694                                user);
5695                    } catch (RemoteException e) {
5696                    }
5697                    if (pkgUid == -1) {
5698                        Slog.w(TAG, "Invalid packageName: " + packageName);
5699                        continue;
5700                    }
5701                    try {
5702                        pm.setPackageStoppedState(packageName, true, user);
5703                    } catch (RemoteException e) {
5704                    } catch (IllegalArgumentException e) {
5705                        Slog.w(TAG, "Failed trying to unstop package "
5706                                + packageName + ": " + e);
5707                    }
5708                    if (mUserController.isUserRunningLocked(user, 0)) {
5709                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5710                        finishForceStopPackageLocked(packageName, pkgUid);
5711                    }
5712                }
5713            }
5714        } finally {
5715            Binder.restoreCallingIdentity(callingId);
5716        }
5717    }
5718
5719    @Override
5720    public void addPackageDependency(String packageName) {
5721        synchronized (this) {
5722            int callingPid = Binder.getCallingPid();
5723            if (callingPid == Process.myPid()) {
5724                //  Yeah, um, no.
5725                return;
5726            }
5727            ProcessRecord proc;
5728            synchronized (mPidsSelfLocked) {
5729                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5730            }
5731            if (proc != null) {
5732                if (proc.pkgDeps == null) {
5733                    proc.pkgDeps = new ArraySet<String>(1);
5734                }
5735                proc.pkgDeps.add(packageName);
5736            }
5737        }
5738    }
5739
5740    /*
5741     * The pkg name and app id have to be specified.
5742     */
5743    @Override
5744    public void killApplication(String pkg, int appId, int userId, String reason) {
5745        if (pkg == null) {
5746            return;
5747        }
5748        // Make sure the uid is valid.
5749        if (appId < 0) {
5750            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5751            return;
5752        }
5753        int callerUid = Binder.getCallingUid();
5754        // Only the system server can kill an application
5755        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5756            // Post an aysnc message to kill the application
5757            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5758            msg.arg1 = appId;
5759            msg.arg2 = userId;
5760            Bundle bundle = new Bundle();
5761            bundle.putString("pkg", pkg);
5762            bundle.putString("reason", reason);
5763            msg.obj = bundle;
5764            mHandler.sendMessage(msg);
5765        } else {
5766            throw new SecurityException(callerUid + " cannot kill pkg: " +
5767                    pkg);
5768        }
5769    }
5770
5771    @Override
5772    public void closeSystemDialogs(String reason) {
5773        enforceNotIsolatedCaller("closeSystemDialogs");
5774
5775        final int pid = Binder.getCallingPid();
5776        final int uid = Binder.getCallingUid();
5777        final long origId = Binder.clearCallingIdentity();
5778        try {
5779            synchronized (this) {
5780                // Only allow this from foreground processes, so that background
5781                // applications can't abuse it to prevent system UI from being shown.
5782                if (uid >= Process.FIRST_APPLICATION_UID) {
5783                    ProcessRecord proc;
5784                    synchronized (mPidsSelfLocked) {
5785                        proc = mPidsSelfLocked.get(pid);
5786                    }
5787                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5788                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5789                                + " from background process " + proc);
5790                        return;
5791                    }
5792                }
5793                closeSystemDialogsLocked(reason);
5794            }
5795        } finally {
5796            Binder.restoreCallingIdentity(origId);
5797        }
5798    }
5799
5800    void closeSystemDialogsLocked(String reason) {
5801        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5802        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5803                | Intent.FLAG_RECEIVER_FOREGROUND);
5804        if (reason != null) {
5805            intent.putExtra("reason", reason);
5806        }
5807        mWindowManager.closeSystemDialogs(reason);
5808
5809        mStackSupervisor.closeSystemDialogsLocked();
5810
5811        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5812                AppOpsManager.OP_NONE, null, false, false,
5813                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5814    }
5815
5816    @Override
5817    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5818        enforceNotIsolatedCaller("getProcessMemoryInfo");
5819        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[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            infos[i] = new Debug.MemoryInfo();
5830            Debug.getMemoryInfo(pids[i], infos[i]);
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(infos[i].getTotalPss(),
5836                                infos[i].getTotalUss(), false, proc.pkgList);
5837                    }
5838                }
5839            }
5840        }
5841        return infos;
5842    }
5843
5844    @Override
5845    public long[] getProcessPss(int[] pids) {
5846        enforceNotIsolatedCaller("getProcessPss");
5847        long[] pss = new long[pids.length];
5848        for (int i=pids.length-1; i>=0; i--) {
5849            ProcessRecord proc;
5850            int oomAdj;
5851            synchronized (this) {
5852                synchronized (mPidsSelfLocked) {
5853                    proc = mPidsSelfLocked.get(pids[i]);
5854                    oomAdj = proc != null ? proc.setAdj : 0;
5855                }
5856            }
5857            long[] tmpUss = new long[1];
5858            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5859            if (proc != null) {
5860                synchronized (this) {
5861                    if (proc.thread != null && proc.setAdj == oomAdj) {
5862                        // Record this for posterity if the process has been stable.
5863                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5864                    }
5865                }
5866            }
5867        }
5868        return pss;
5869    }
5870
5871    @Override
5872    public void killApplicationProcess(String processName, int uid) {
5873        if (processName == null) {
5874            return;
5875        }
5876
5877        int callerUid = Binder.getCallingUid();
5878        // Only the system server can kill an application
5879        if (callerUid == Process.SYSTEM_UID) {
5880            synchronized (this) {
5881                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5882                if (app != null && app.thread != null) {
5883                    try {
5884                        app.thread.scheduleSuicide();
5885                    } catch (RemoteException e) {
5886                        // If the other end already died, then our work here is done.
5887                    }
5888                } else {
5889                    Slog.w(TAG, "Process/uid not found attempting kill of "
5890                            + processName + " / " + uid);
5891                }
5892            }
5893        } else {
5894            throw new SecurityException(callerUid + " cannot kill app process: " +
5895                    processName);
5896        }
5897    }
5898
5899    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5900        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5901                false, true, false, false, UserHandle.getUserId(uid), reason);
5902    }
5903
5904    private void finishForceStopPackageLocked(final String packageName, int uid) {
5905        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5906                Uri.fromParts("package", packageName, null));
5907        if (!mProcessesReady) {
5908            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5909                    | Intent.FLAG_RECEIVER_FOREGROUND);
5910        }
5911        intent.putExtra(Intent.EXTRA_UID, uid);
5912        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5913        broadcastIntentLocked(null, null, intent,
5914                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5915                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5916    }
5917
5918
5919    private final boolean killPackageProcessesLocked(String packageName, int appId,
5920            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5921            boolean doit, boolean evenPersistent, String reason) {
5922        ArrayList<ProcessRecord> procs = new ArrayList<>();
5923
5924        // Remove all processes this package may have touched: all with the
5925        // same UID (except for the system or root user), and all whose name
5926        // matches the package name.
5927        final int NP = mProcessNames.getMap().size();
5928        for (int ip=0; ip<NP; ip++) {
5929            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5930            final int NA = apps.size();
5931            for (int ia=0; ia<NA; ia++) {
5932                ProcessRecord app = apps.valueAt(ia);
5933                if (app.persistent && !evenPersistent) {
5934                    // we don't kill persistent processes
5935                    continue;
5936                }
5937                if (app.removed) {
5938                    if (doit) {
5939                        procs.add(app);
5940                    }
5941                    continue;
5942                }
5943
5944                // Skip process if it doesn't meet our oom adj requirement.
5945                if (app.setAdj < minOomAdj) {
5946                    continue;
5947                }
5948
5949                // If no package is specified, we call all processes under the
5950                // give user id.
5951                if (packageName == null) {
5952                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5953                        continue;
5954                    }
5955                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5956                        continue;
5957                    }
5958                // Package has been specified, we want to hit all processes
5959                // that match it.  We need to qualify this by the processes
5960                // that are running under the specified app and user ID.
5961                } else {
5962                    final boolean isDep = app.pkgDeps != null
5963                            && app.pkgDeps.contains(packageName);
5964                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5965                        continue;
5966                    }
5967                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5968                        continue;
5969                    }
5970                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5971                        continue;
5972                    }
5973                }
5974
5975                // Process has passed all conditions, kill it!
5976                if (!doit) {
5977                    return true;
5978                }
5979                app.removed = true;
5980                procs.add(app);
5981            }
5982        }
5983
5984        int N = procs.size();
5985        for (int i=0; i<N; i++) {
5986            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5987        }
5988        updateOomAdjLocked();
5989        return N > 0;
5990    }
5991
5992    private void cleanupDisabledPackageComponentsLocked(
5993            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5994
5995        Set<String> disabledClasses = null;
5996        boolean packageDisabled = false;
5997        IPackageManager pm = AppGlobals.getPackageManager();
5998
5999        if (changedClasses == null) {
6000            // Nothing changed...
6001            return;
6002        }
6003
6004        // Determine enable/disable state of the package and its components.
6005        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6006        for (int i = changedClasses.length - 1; i >= 0; i--) {
6007            final String changedClass = changedClasses[i];
6008
6009            if (changedClass.equals(packageName)) {
6010                try {
6011                    // Entire package setting changed
6012                    enabled = pm.getApplicationEnabledSetting(packageName,
6013                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6014                } catch (Exception e) {
6015                    // No such package/component; probably racing with uninstall.  In any
6016                    // event it means we have nothing further to do here.
6017                    return;
6018                }
6019                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6020                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6021                if (packageDisabled) {
6022                    // Entire package is disabled.
6023                    // No need to continue to check component states.
6024                    disabledClasses = null;
6025                    break;
6026                }
6027            } else {
6028                try {
6029                    enabled = pm.getComponentEnabledSetting(
6030                            new ComponentName(packageName, changedClass),
6031                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6032                } catch (Exception e) {
6033                    // As above, probably racing with uninstall.
6034                    return;
6035                }
6036                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6037                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6038                    if (disabledClasses == null) {
6039                        disabledClasses = new ArraySet<>(changedClasses.length);
6040                    }
6041                    disabledClasses.add(changedClass);
6042                }
6043            }
6044        }
6045
6046        if (!packageDisabled && disabledClasses == null) {
6047            // Nothing to do here...
6048            return;
6049        }
6050
6051        // Clean-up disabled activities.
6052        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6053                packageName, disabledClasses, true, false, userId) && mBooted) {
6054            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6055            mStackSupervisor.scheduleIdleLocked();
6056        }
6057
6058        // Clean-up disabled tasks
6059        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6060
6061        // Clean-up disabled services.
6062        mServices.bringDownDisabledPackageServicesLocked(
6063                packageName, disabledClasses, userId, false, killProcess, true);
6064
6065        // Clean-up disabled providers.
6066        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6067        mProviderMap.collectPackageProvidersLocked(
6068                packageName, disabledClasses, true, false, userId, providers);
6069        for (int i = providers.size() - 1; i >= 0; i--) {
6070            removeDyingProviderLocked(null, providers.get(i), true);
6071        }
6072
6073        // Clean-up disabled broadcast receivers.
6074        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6075            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6076                    packageName, disabledClasses, userId, true);
6077        }
6078
6079    }
6080
6081    final boolean clearBroadcastQueueForUserLocked(int userId) {
6082        boolean didSomething = false;
6083        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6084            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6085                    null, null, userId, true);
6086        }
6087        return didSomething;
6088    }
6089
6090    final boolean forceStopPackageLocked(String packageName, int appId,
6091            boolean callerWillRestart, boolean purgeCache, boolean doit,
6092            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6093        int i;
6094
6095        if (userId == UserHandle.USER_ALL && packageName == null) {
6096            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6097        }
6098
6099        if (appId < 0 && packageName != null) {
6100            try {
6101                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6102                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6103            } catch (RemoteException e) {
6104            }
6105        }
6106
6107        if (doit) {
6108            if (packageName != null) {
6109                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6110                        + " user=" + userId + ": " + reason);
6111            } else {
6112                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6113            }
6114
6115            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6116        }
6117
6118        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6119                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6120                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6121
6122        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6123                packageName, null, doit, evenPersistent, userId)) {
6124            if (!doit) {
6125                return true;
6126            }
6127            didSomething = true;
6128        }
6129
6130        if (mServices.bringDownDisabledPackageServicesLocked(
6131                packageName, null, userId, evenPersistent, true, doit)) {
6132            if (!doit) {
6133                return true;
6134            }
6135            didSomething = true;
6136        }
6137
6138        if (packageName == null) {
6139            // Remove all sticky broadcasts from this user.
6140            mStickyBroadcasts.remove(userId);
6141        }
6142
6143        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6144        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6145                userId, providers)) {
6146            if (!doit) {
6147                return true;
6148            }
6149            didSomething = true;
6150        }
6151        for (i = providers.size() - 1; i >= 0; i--) {
6152            removeDyingProviderLocked(null, providers.get(i), true);
6153        }
6154
6155        // Remove transient permissions granted from/to this package/user
6156        removeUriPermissionsForPackageLocked(packageName, userId, false);
6157
6158        if (doit) {
6159            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6160                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6161                        packageName, null, userId, doit);
6162            }
6163        }
6164
6165        if (packageName == null || uninstalling) {
6166            // Remove pending intents.  For now we only do this when force
6167            // stopping users, because we have some problems when doing this
6168            // for packages -- app widgets are not currently cleaned up for
6169            // such packages, so they can be left with bad pending intents.
6170            if (mIntentSenderRecords.size() > 0) {
6171                Iterator<WeakReference<PendingIntentRecord>> it
6172                        = mIntentSenderRecords.values().iterator();
6173                while (it.hasNext()) {
6174                    WeakReference<PendingIntentRecord> wpir = it.next();
6175                    if (wpir == null) {
6176                        it.remove();
6177                        continue;
6178                    }
6179                    PendingIntentRecord pir = wpir.get();
6180                    if (pir == null) {
6181                        it.remove();
6182                        continue;
6183                    }
6184                    if (packageName == null) {
6185                        // Stopping user, remove all objects for the user.
6186                        if (pir.key.userId != userId) {
6187                            // Not the same user, skip it.
6188                            continue;
6189                        }
6190                    } else {
6191                        if (UserHandle.getAppId(pir.uid) != appId) {
6192                            // Different app id, skip it.
6193                            continue;
6194                        }
6195                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6196                            // Different user, skip it.
6197                            continue;
6198                        }
6199                        if (!pir.key.packageName.equals(packageName)) {
6200                            // Different package, skip it.
6201                            continue;
6202                        }
6203                    }
6204                    if (!doit) {
6205                        return true;
6206                    }
6207                    didSomething = true;
6208                    it.remove();
6209                    pir.canceled = true;
6210                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6211                        pir.key.activity.pendingResults.remove(pir.ref);
6212                    }
6213                }
6214            }
6215        }
6216
6217        if (doit) {
6218            if (purgeCache && packageName != null) {
6219                AttributeCache ac = AttributeCache.instance();
6220                if (ac != null) {
6221                    ac.removePackage(packageName);
6222                }
6223            }
6224            if (mBooted) {
6225                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6226                mStackSupervisor.scheduleIdleLocked();
6227            }
6228        }
6229
6230        return didSomething;
6231    }
6232
6233    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6234        ProcessRecord old = mProcessNames.remove(name, uid);
6235        if (old != null) {
6236            old.uidRecord.numProcs--;
6237            if (old.uidRecord.numProcs == 0) {
6238                // No more processes using this uid, tell clients it is gone.
6239                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6240                        "No more processes in " + old.uidRecord);
6241                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6242                mActiveUids.remove(uid);
6243                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6244            }
6245            old.uidRecord = null;
6246        }
6247        mIsolatedProcesses.remove(uid);
6248        return old;
6249    }
6250
6251    private final void addProcessNameLocked(ProcessRecord proc) {
6252        // We shouldn't already have a process under this name, but just in case we
6253        // need to clean up whatever may be there now.
6254        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6255        if (old == proc && proc.persistent) {
6256            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6257            Slog.w(TAG, "Re-adding persistent process " + proc);
6258        } else if (old != null) {
6259            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6260        }
6261        UidRecord uidRec = mActiveUids.get(proc.uid);
6262        if (uidRec == null) {
6263            uidRec = new UidRecord(proc.uid);
6264            // This is the first appearance of the uid, report it now!
6265            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6266                    "Creating new process uid: " + uidRec);
6267            mActiveUids.put(proc.uid, uidRec);
6268            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6269            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6270        }
6271        proc.uidRecord = uidRec;
6272        uidRec.numProcs++;
6273        mProcessNames.put(proc.processName, proc.uid, proc);
6274        if (proc.isolated) {
6275            mIsolatedProcesses.put(proc.uid, proc);
6276        }
6277    }
6278
6279    boolean removeProcessLocked(ProcessRecord app,
6280            boolean callerWillRestart, boolean allowRestart, String reason) {
6281        final String name = app.processName;
6282        final int uid = app.uid;
6283        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6284            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6285
6286        ProcessRecord old = mProcessNames.get(name, uid);
6287        if (old != app) {
6288            // This process is no longer active, so nothing to do.
6289            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6290            return false;
6291        }
6292        removeProcessNameLocked(name, uid);
6293        if (mHeavyWeightProcess == app) {
6294            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6295                    mHeavyWeightProcess.userId, 0));
6296            mHeavyWeightProcess = null;
6297        }
6298        boolean needRestart = false;
6299        if (app.pid > 0 && app.pid != MY_PID) {
6300            int pid = app.pid;
6301            synchronized (mPidsSelfLocked) {
6302                mPidsSelfLocked.remove(pid);
6303                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6304            }
6305            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6306            if (app.isolated) {
6307                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6308            }
6309            boolean willRestart = false;
6310            if (app.persistent && !app.isolated) {
6311                if (!callerWillRestart) {
6312                    willRestart = true;
6313                } else {
6314                    needRestart = true;
6315                }
6316            }
6317            app.kill(reason, true);
6318            handleAppDiedLocked(app, willRestart, allowRestart);
6319            if (willRestart) {
6320                removeLruProcessLocked(app);
6321                addAppLocked(app.info, false, null /* ABI override */);
6322            }
6323        } else {
6324            mRemovedProcesses.add(app);
6325        }
6326
6327        return needRestart;
6328    }
6329
6330    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6331        cleanupAppInLaunchingProvidersLocked(app, true);
6332        removeProcessLocked(app, false, true, "timeout publishing content providers");
6333    }
6334
6335    private final void processStartTimedOutLocked(ProcessRecord app) {
6336        final int pid = app.pid;
6337        boolean gone = false;
6338        synchronized (mPidsSelfLocked) {
6339            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6340            if (knownApp != null && knownApp.thread == null) {
6341                mPidsSelfLocked.remove(pid);
6342                gone = true;
6343            }
6344        }
6345
6346        if (gone) {
6347            Slog.w(TAG, "Process " + app + " failed to attach");
6348            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6349                    pid, app.uid, app.processName);
6350            removeProcessNameLocked(app.processName, app.uid);
6351            if (mHeavyWeightProcess == app) {
6352                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6353                        mHeavyWeightProcess.userId, 0));
6354                mHeavyWeightProcess = null;
6355            }
6356            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6357            if (app.isolated) {
6358                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6359            }
6360            // Take care of any launching providers waiting for this process.
6361            cleanupAppInLaunchingProvidersLocked(app, true);
6362            // Take care of any services that are waiting for the process.
6363            mServices.processStartTimedOutLocked(app);
6364            app.kill("start timeout", true);
6365            removeLruProcessLocked(app);
6366            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6367                Slog.w(TAG, "Unattached app died before backup, skipping");
6368                try {
6369                    IBackupManager bm = IBackupManager.Stub.asInterface(
6370                            ServiceManager.getService(Context.BACKUP_SERVICE));
6371                    bm.agentDisconnected(app.info.packageName);
6372                } catch (RemoteException e) {
6373                    // Can't happen; the backup manager is local
6374                }
6375            }
6376            if (isPendingBroadcastProcessLocked(pid)) {
6377                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6378                skipPendingBroadcastLocked(pid);
6379            }
6380        } else {
6381            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6382        }
6383    }
6384
6385    private final boolean attachApplicationLocked(IApplicationThread thread,
6386            int pid) {
6387
6388        // Find the application record that is being attached...  either via
6389        // the pid if we are running in multiple processes, or just pull the
6390        // next app record if we are emulating process with anonymous threads.
6391        ProcessRecord app;
6392        if (pid != MY_PID && pid >= 0) {
6393            synchronized (mPidsSelfLocked) {
6394                app = mPidsSelfLocked.get(pid);
6395            }
6396        } else {
6397            app = null;
6398        }
6399
6400        if (app == null) {
6401            Slog.w(TAG, "No pending application record for pid " + pid
6402                    + " (IApplicationThread " + thread + "); dropping process");
6403            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6404            if (pid > 0 && pid != MY_PID) {
6405                Process.killProcessQuiet(pid);
6406                //TODO: killProcessGroup(app.info.uid, pid);
6407            } else {
6408                try {
6409                    thread.scheduleExit();
6410                } catch (Exception e) {
6411                    // Ignore exceptions.
6412                }
6413            }
6414            return false;
6415        }
6416
6417        // If this application record is still attached to a previous
6418        // process, clean it up now.
6419        if (app.thread != null) {
6420            handleAppDiedLocked(app, true, true);
6421        }
6422
6423        // Tell the process all about itself.
6424
6425        if (DEBUG_ALL) Slog.v(
6426                TAG, "Binding process pid " + pid + " to record " + app);
6427
6428        final String processName = app.processName;
6429        try {
6430            AppDeathRecipient adr = new AppDeathRecipient(
6431                    app, pid, thread);
6432            thread.asBinder().linkToDeath(adr, 0);
6433            app.deathRecipient = adr;
6434        } catch (RemoteException e) {
6435            app.resetPackageList(mProcessStats);
6436            startProcessLocked(app, "link fail", processName);
6437            return false;
6438        }
6439
6440        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6441
6442        app.makeActive(thread, mProcessStats);
6443        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6444        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6445        app.forcingToForeground = null;
6446        updateProcessForegroundLocked(app, false, false);
6447        app.hasShownUi = false;
6448        app.debugging = false;
6449        app.cached = false;
6450        app.killedByAm = false;
6451
6452        // We carefully use the same state that PackageManager uses for
6453        // filtering, since we use this flag to decide if we need to install
6454        // providers when user is unlocked later
6455        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6456
6457        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6458
6459        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6460        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6461
6462        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6463            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6464            msg.obj = app;
6465            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6466        }
6467
6468        if (!normalMode) {
6469            Slog.i(TAG, "Launching preboot mode app: " + app);
6470        }
6471
6472        if (DEBUG_ALL) Slog.v(
6473            TAG, "New app record " + app
6474            + " thread=" + thread.asBinder() + " pid=" + pid);
6475        try {
6476            int testMode = IApplicationThread.DEBUG_OFF;
6477            if (mDebugApp != null && mDebugApp.equals(processName)) {
6478                testMode = mWaitForDebugger
6479                    ? IApplicationThread.DEBUG_WAIT
6480                    : IApplicationThread.DEBUG_ON;
6481                app.debugging = true;
6482                if (mDebugTransient) {
6483                    mDebugApp = mOrigDebugApp;
6484                    mWaitForDebugger = mOrigWaitForDebugger;
6485                }
6486            }
6487            String profileFile = app.instrumentationProfileFile;
6488            ParcelFileDescriptor profileFd = null;
6489            int samplingInterval = 0;
6490            boolean profileAutoStop = false;
6491            if (mProfileApp != null && mProfileApp.equals(processName)) {
6492                mProfileProc = app;
6493                profileFile = mProfileFile;
6494                profileFd = mProfileFd;
6495                samplingInterval = mSamplingInterval;
6496                profileAutoStop = mAutoStopProfiler;
6497            }
6498            boolean enableTrackAllocation = false;
6499            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6500                enableTrackAllocation = true;
6501                mTrackAllocationApp = null;
6502            }
6503
6504            // If the app is being launched for restore or full backup, set it up specially
6505            boolean isRestrictedBackupMode = false;
6506            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6507                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6508                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6509                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6510                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6511            }
6512
6513            if (app.instrumentationClass != null) {
6514                notifyPackageUse(app.instrumentationClass.getPackageName(),
6515                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6516            }
6517            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6518                    + processName + " with config " + mConfiguration);
6519            ApplicationInfo appInfo = app.instrumentationInfo != null
6520                    ? app.instrumentationInfo : app.info;
6521            app.compat = compatibilityInfoForPackageLocked(appInfo);
6522            if (profileFd != null) {
6523                profileFd = profileFd.dup();
6524            }
6525            ProfilerInfo profilerInfo = profileFile == null ? null
6526                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6527            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6528                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6529                    app.instrumentationUiAutomationConnection, testMode,
6530                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6531                    isRestrictedBackupMode || !normalMode, app.persistent,
6532                    new Configuration(mConfiguration), app.compat,
6533                    getCommonServicesLocked(app.isolated),
6534                    mCoreSettingsObserver.getCoreSettingsLocked());
6535            updateLruProcessLocked(app, false, null);
6536            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6537        } catch (Exception e) {
6538            // todo: Yikes!  What should we do?  For now we will try to
6539            // start another process, but that could easily get us in
6540            // an infinite loop of restarting processes...
6541            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6542
6543            app.resetPackageList(mProcessStats);
6544            app.unlinkDeathRecipient();
6545            startProcessLocked(app, "bind fail", processName);
6546            return false;
6547        }
6548
6549        // Remove this record from the list of starting applications.
6550        mPersistentStartingProcesses.remove(app);
6551        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6552                "Attach application locked removing on hold: " + app);
6553        mProcessesOnHold.remove(app);
6554
6555        boolean badApp = false;
6556        boolean didSomething = false;
6557
6558        // See if the top visible activity is waiting to run in this process...
6559        if (normalMode) {
6560            try {
6561                if (mStackSupervisor.attachApplicationLocked(app)) {
6562                    didSomething = true;
6563                }
6564            } catch (Exception e) {
6565                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6566                badApp = true;
6567            }
6568        }
6569
6570        // Find any services that should be running in this process...
6571        if (!badApp) {
6572            try {
6573                didSomething |= mServices.attachApplicationLocked(app, processName);
6574            } catch (Exception e) {
6575                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6576                badApp = true;
6577            }
6578        }
6579
6580        // Check if a next-broadcast receiver is in this process...
6581        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6582            try {
6583                didSomething |= sendPendingBroadcastsLocked(app);
6584            } catch (Exception e) {
6585                // If the app died trying to launch the receiver we declare it 'bad'
6586                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6587                badApp = true;
6588            }
6589        }
6590
6591        // Check whether the next backup agent is in this process...
6592        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6593            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6594                    "New app is backup target, launching agent for " + app);
6595            notifyPackageUse(mBackupTarget.appInfo.packageName,
6596                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6597            try {
6598                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6599                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6600                        mBackupTarget.backupMode);
6601            } catch (Exception e) {
6602                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6603                badApp = true;
6604            }
6605        }
6606
6607        if (badApp) {
6608            app.kill("error during init", true);
6609            handleAppDiedLocked(app, false, true);
6610            return false;
6611        }
6612
6613        if (!didSomething) {
6614            updateOomAdjLocked();
6615        }
6616
6617        return true;
6618    }
6619
6620    @Override
6621    public final void attachApplication(IApplicationThread thread) {
6622        synchronized (this) {
6623            int callingPid = Binder.getCallingPid();
6624            final long origId = Binder.clearCallingIdentity();
6625            attachApplicationLocked(thread, callingPid);
6626            Binder.restoreCallingIdentity(origId);
6627        }
6628    }
6629
6630    @Override
6631    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6632        final long origId = Binder.clearCallingIdentity();
6633        synchronized (this) {
6634            ActivityStack stack = ActivityRecord.getStackLocked(token);
6635            if (stack != null) {
6636                ActivityRecord r =
6637                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6638                if (stopProfiling) {
6639                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6640                        try {
6641                            mProfileFd.close();
6642                        } catch (IOException e) {
6643                        }
6644                        clearProfilerLocked();
6645                    }
6646                }
6647            }
6648        }
6649        Binder.restoreCallingIdentity(origId);
6650    }
6651
6652    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6653        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6654                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6655    }
6656
6657    void enableScreenAfterBoot() {
6658        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6659                SystemClock.uptimeMillis());
6660        mWindowManager.enableScreenAfterBoot();
6661
6662        synchronized (this) {
6663            updateEventDispatchingLocked();
6664        }
6665    }
6666
6667    @Override
6668    public void showBootMessage(final CharSequence msg, final boolean always) {
6669        if (Binder.getCallingUid() != Process.myUid()) {
6670            // These days only the core system can call this, so apps can't get in
6671            // the way of what we show about running them.
6672        }
6673        mWindowManager.showBootMessage(msg, always);
6674    }
6675
6676    @Override
6677    public void keyguardWaitingForActivityDrawn() {
6678        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6679        final long token = Binder.clearCallingIdentity();
6680        try {
6681            synchronized (this) {
6682                if (DEBUG_LOCKSCREEN) logLockScreen("");
6683                mWindowManager.keyguardWaitingForActivityDrawn();
6684                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6685                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6686                    updateSleepIfNeededLocked();
6687                }
6688            }
6689        } finally {
6690            Binder.restoreCallingIdentity(token);
6691        }
6692    }
6693
6694    @Override
6695    public void keyguardGoingAway(int flags) {
6696        enforceNotIsolatedCaller("keyguardGoingAway");
6697        final long token = Binder.clearCallingIdentity();
6698        try {
6699            synchronized (this) {
6700                if (DEBUG_LOCKSCREEN) logLockScreen("");
6701                mWindowManager.keyguardGoingAway(flags);
6702                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6703                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6704                    updateSleepIfNeededLocked();
6705
6706                    // Some stack visibility might change (e.g. docked stack)
6707                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6708                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6709                }
6710            }
6711        } finally {
6712            Binder.restoreCallingIdentity(token);
6713        }
6714    }
6715
6716    final void finishBooting() {
6717        synchronized (this) {
6718            if (!mBootAnimationComplete) {
6719                mCallFinishBooting = true;
6720                return;
6721            }
6722            mCallFinishBooting = false;
6723        }
6724
6725        ArraySet<String> completedIsas = new ArraySet<String>();
6726        for (String abi : Build.SUPPORTED_ABIS) {
6727            Process.establishZygoteConnectionForAbi(abi);
6728            final String instructionSet = VMRuntime.getInstructionSet(abi);
6729            if (!completedIsas.contains(instructionSet)) {
6730                try {
6731                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6732                } catch (InstallerException e) {
6733                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6734                            e.getMessage() +")");
6735                }
6736                completedIsas.add(instructionSet);
6737            }
6738        }
6739
6740        IntentFilter pkgFilter = new IntentFilter();
6741        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6742        pkgFilter.addDataScheme("package");
6743        mContext.registerReceiver(new BroadcastReceiver() {
6744            @Override
6745            public void onReceive(Context context, Intent intent) {
6746                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6747                if (pkgs != null) {
6748                    for (String pkg : pkgs) {
6749                        synchronized (ActivityManagerService.this) {
6750                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6751                                    0, "query restart")) {
6752                                setResultCode(Activity.RESULT_OK);
6753                                return;
6754                            }
6755                        }
6756                    }
6757                }
6758            }
6759        }, pkgFilter);
6760
6761        IntentFilter dumpheapFilter = new IntentFilter();
6762        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6763        mContext.registerReceiver(new BroadcastReceiver() {
6764            @Override
6765            public void onReceive(Context context, Intent intent) {
6766                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6767                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6768                } else {
6769                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6770                }
6771            }
6772        }, dumpheapFilter);
6773
6774        // Let system services know.
6775        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6776
6777        synchronized (this) {
6778            // Ensure that any processes we had put on hold are now started
6779            // up.
6780            final int NP = mProcessesOnHold.size();
6781            if (NP > 0) {
6782                ArrayList<ProcessRecord> procs =
6783                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6784                for (int ip=0; ip<NP; ip++) {
6785                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6786                            + procs.get(ip));
6787                    startProcessLocked(procs.get(ip), "on-hold", null);
6788                }
6789            }
6790
6791            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6792                // Start looking for apps that are abusing wake locks.
6793                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6794                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6795                // Tell anyone interested that we are done booting!
6796                SystemProperties.set("sys.boot_completed", "1");
6797
6798                // And trigger dev.bootcomplete if we are not showing encryption progress
6799                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6800                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6801                    SystemProperties.set("dev.bootcomplete", "1");
6802                }
6803                mUserController.sendBootCompletedLocked(
6804                        new IIntentReceiver.Stub() {
6805                            @Override
6806                            public void performReceive(Intent intent, int resultCode,
6807                                    String data, Bundle extras, boolean ordered,
6808                                    boolean sticky, int sendingUser) {
6809                                synchronized (ActivityManagerService.this) {
6810                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6811                                            true, false);
6812                                }
6813                            }
6814                        });
6815                scheduleStartProfilesLocked();
6816            }
6817        }
6818    }
6819
6820    @Override
6821    public void bootAnimationComplete() {
6822        final boolean callFinishBooting;
6823        synchronized (this) {
6824            callFinishBooting = mCallFinishBooting;
6825            mBootAnimationComplete = true;
6826        }
6827        if (callFinishBooting) {
6828            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6829            finishBooting();
6830            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6831        }
6832    }
6833
6834    final void ensureBootCompleted() {
6835        boolean booting;
6836        boolean enableScreen;
6837        synchronized (this) {
6838            booting = mBooting;
6839            mBooting = false;
6840            enableScreen = !mBooted;
6841            mBooted = true;
6842        }
6843
6844        if (booting) {
6845            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6846            finishBooting();
6847            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6848        }
6849
6850        if (enableScreen) {
6851            enableScreenAfterBoot();
6852        }
6853    }
6854
6855    @Override
6856    public final void activityResumed(IBinder token) {
6857        final long origId = Binder.clearCallingIdentity();
6858        synchronized(this) {
6859            ActivityStack stack = ActivityRecord.getStackLocked(token);
6860            if (stack != null) {
6861                stack.activityResumedLocked(token);
6862            }
6863        }
6864        Binder.restoreCallingIdentity(origId);
6865    }
6866
6867    @Override
6868    public final void activityPaused(IBinder token) {
6869        final long origId = Binder.clearCallingIdentity();
6870        synchronized(this) {
6871            ActivityStack stack = ActivityRecord.getStackLocked(token);
6872            if (stack != null) {
6873                stack.activityPausedLocked(token, false);
6874            }
6875        }
6876        Binder.restoreCallingIdentity(origId);
6877    }
6878
6879    @Override
6880    public final void activityStopped(IBinder token, Bundle icicle,
6881            PersistableBundle persistentState, CharSequence description) {
6882        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6883
6884        // Refuse possible leaked file descriptors
6885        if (icicle != null && icicle.hasFileDescriptors()) {
6886            throw new IllegalArgumentException("File descriptors passed in Bundle");
6887        }
6888
6889        final long origId = Binder.clearCallingIdentity();
6890
6891        synchronized (this) {
6892            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6893            if (r != null) {
6894                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6895            }
6896        }
6897
6898        trimApplications();
6899
6900        Binder.restoreCallingIdentity(origId);
6901    }
6902
6903    @Override
6904    public final void activityDestroyed(IBinder token) {
6905        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6906        synchronized (this) {
6907            ActivityStack stack = ActivityRecord.getStackLocked(token);
6908            if (stack != null) {
6909                stack.activityDestroyedLocked(token, "activityDestroyed");
6910            }
6911        }
6912    }
6913
6914    @Override
6915    public final void activityRelaunched(IBinder token) {
6916        final long origId = Binder.clearCallingIdentity();
6917        synchronized (this) {
6918            mStackSupervisor.activityRelaunchedLocked(token);
6919        }
6920        Binder.restoreCallingIdentity(origId);
6921    }
6922
6923    @Override
6924    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6925            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6926        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6927                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6928        synchronized (this) {
6929            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6930            if (record == null) {
6931                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6932                        + "found for: " + token);
6933            }
6934            record.setSizeConfigurations(horizontalSizeConfiguration,
6935                    verticalSizeConfigurations, smallestSizeConfigurations);
6936        }
6937    }
6938
6939    @Override
6940    public final void backgroundResourcesReleased(IBinder token) {
6941        final long origId = Binder.clearCallingIdentity();
6942        try {
6943            synchronized (this) {
6944                ActivityStack stack = ActivityRecord.getStackLocked(token);
6945                if (stack != null) {
6946                    stack.backgroundResourcesReleased();
6947                }
6948            }
6949        } finally {
6950            Binder.restoreCallingIdentity(origId);
6951        }
6952    }
6953
6954    @Override
6955    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6956        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6957    }
6958
6959    @Override
6960    public final void notifyEnterAnimationComplete(IBinder token) {
6961        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6962    }
6963
6964    @Override
6965    public String getCallingPackage(IBinder token) {
6966        synchronized (this) {
6967            ActivityRecord r = getCallingRecordLocked(token);
6968            return r != null ? r.info.packageName : null;
6969        }
6970    }
6971
6972    @Override
6973    public ComponentName getCallingActivity(IBinder token) {
6974        synchronized (this) {
6975            ActivityRecord r = getCallingRecordLocked(token);
6976            return r != null ? r.intent.getComponent() : null;
6977        }
6978    }
6979
6980    private ActivityRecord getCallingRecordLocked(IBinder token) {
6981        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6982        if (r == null) {
6983            return null;
6984        }
6985        return r.resultTo;
6986    }
6987
6988    @Override
6989    public ComponentName getActivityClassForToken(IBinder token) {
6990        synchronized(this) {
6991            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6992            if (r == null) {
6993                return null;
6994            }
6995            return r.intent.getComponent();
6996        }
6997    }
6998
6999    @Override
7000    public String getPackageForToken(IBinder token) {
7001        synchronized(this) {
7002            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7003            if (r == null) {
7004                return null;
7005            }
7006            return r.packageName;
7007        }
7008    }
7009
7010    @Override
7011    public boolean isRootVoiceInteraction(IBinder token) {
7012        synchronized(this) {
7013            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7014            if (r == null) {
7015                return false;
7016            }
7017            return r.rootVoiceInteraction;
7018        }
7019    }
7020
7021    @Override
7022    public IIntentSender getIntentSender(int type,
7023            String packageName, IBinder token, String resultWho,
7024            int requestCode, Intent[] intents, String[] resolvedTypes,
7025            int flags, Bundle bOptions, int userId) {
7026        enforceNotIsolatedCaller("getIntentSender");
7027        // Refuse possible leaked file descriptors
7028        if (intents != null) {
7029            if (intents.length < 1) {
7030                throw new IllegalArgumentException("Intents array length must be >= 1");
7031            }
7032            for (int i=0; i<intents.length; i++) {
7033                Intent intent = intents[i];
7034                if (intent != null) {
7035                    if (intent.hasFileDescriptors()) {
7036                        throw new IllegalArgumentException("File descriptors passed in Intent");
7037                    }
7038                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7039                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7040                        throw new IllegalArgumentException(
7041                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7042                    }
7043                    intents[i] = new Intent(intent);
7044                }
7045            }
7046            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7047                throw new IllegalArgumentException(
7048                        "Intent array length does not match resolvedTypes length");
7049            }
7050        }
7051        if (bOptions != null) {
7052            if (bOptions.hasFileDescriptors()) {
7053                throw new IllegalArgumentException("File descriptors passed in options");
7054            }
7055        }
7056
7057        synchronized(this) {
7058            int callingUid = Binder.getCallingUid();
7059            int origUserId = userId;
7060            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7061                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7062                    ALLOW_NON_FULL, "getIntentSender", null);
7063            if (origUserId == UserHandle.USER_CURRENT) {
7064                // We don't want to evaluate this until the pending intent is
7065                // actually executed.  However, we do want to always do the
7066                // security checking for it above.
7067                userId = UserHandle.USER_CURRENT;
7068            }
7069            try {
7070                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7071                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7072                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7073                    if (!UserHandle.isSameApp(callingUid, uid)) {
7074                        String msg = "Permission Denial: getIntentSender() from pid="
7075                            + Binder.getCallingPid()
7076                            + ", uid=" + Binder.getCallingUid()
7077                            + ", (need uid=" + uid + ")"
7078                            + " is not allowed to send as package " + packageName;
7079                        Slog.w(TAG, msg);
7080                        throw new SecurityException(msg);
7081                    }
7082                }
7083
7084                return getIntentSenderLocked(type, packageName, callingUid, userId,
7085                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7086
7087            } catch (RemoteException e) {
7088                throw new SecurityException(e);
7089            }
7090        }
7091    }
7092
7093    IIntentSender getIntentSenderLocked(int type, String packageName,
7094            int callingUid, int userId, IBinder token, String resultWho,
7095            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7096            Bundle bOptions) {
7097        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7098        ActivityRecord activity = null;
7099        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7100            activity = ActivityRecord.isInStackLocked(token);
7101            if (activity == null) {
7102                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7103                return null;
7104            }
7105            if (activity.finishing) {
7106                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7107                return null;
7108            }
7109        }
7110
7111        // We're going to be splicing together extras before sending, so we're
7112        // okay poking into any contained extras.
7113        if (intents != null) {
7114            for (int i = 0; i < intents.length; i++) {
7115                intents[i].setDefusable(true);
7116            }
7117        }
7118        Bundle.setDefusable(bOptions, true);
7119
7120        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7121        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7122        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7123        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7124                |PendingIntent.FLAG_UPDATE_CURRENT);
7125
7126        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7127                type, packageName, activity, resultWho,
7128                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7129        WeakReference<PendingIntentRecord> ref;
7130        ref = mIntentSenderRecords.get(key);
7131        PendingIntentRecord rec = ref != null ? ref.get() : null;
7132        if (rec != null) {
7133            if (!cancelCurrent) {
7134                if (updateCurrent) {
7135                    if (rec.key.requestIntent != null) {
7136                        rec.key.requestIntent.replaceExtras(intents != null ?
7137                                intents[intents.length - 1] : null);
7138                    }
7139                    if (intents != null) {
7140                        intents[intents.length-1] = rec.key.requestIntent;
7141                        rec.key.allIntents = intents;
7142                        rec.key.allResolvedTypes = resolvedTypes;
7143                    } else {
7144                        rec.key.allIntents = null;
7145                        rec.key.allResolvedTypes = null;
7146                    }
7147                }
7148                return rec;
7149            }
7150            rec.canceled = true;
7151            mIntentSenderRecords.remove(key);
7152        }
7153        if (noCreate) {
7154            return rec;
7155        }
7156        rec = new PendingIntentRecord(this, key, callingUid);
7157        mIntentSenderRecords.put(key, rec.ref);
7158        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7159            if (activity.pendingResults == null) {
7160                activity.pendingResults
7161                        = new HashSet<WeakReference<PendingIntentRecord>>();
7162            }
7163            activity.pendingResults.add(rec.ref);
7164        }
7165        return rec;
7166    }
7167
7168    @Override
7169    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7170            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7171        if (target instanceof PendingIntentRecord) {
7172            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7173                    finishedReceiver, requiredPermission, options);
7174        } else {
7175            if (intent == null) {
7176                // Weird case: someone has given us their own custom IIntentSender, and now
7177                // they have someone else trying to send to it but of course this isn't
7178                // really a PendingIntent, so there is no base Intent, and the caller isn't
7179                // supplying an Intent... but we never want to dispatch a null Intent to
7180                // a receiver, so um...  let's make something up.
7181                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7182                intent = new Intent(Intent.ACTION_MAIN);
7183            }
7184            try {
7185                target.send(code, intent, resolvedType, null, requiredPermission, options);
7186            } catch (RemoteException e) {
7187            }
7188            // Platform code can rely on getting a result back when the send is done, but if
7189            // this intent sender is from outside of the system we can't rely on it doing that.
7190            // So instead we don't give it the result receiver, and instead just directly
7191            // report the finish immediately.
7192            if (finishedReceiver != null) {
7193                try {
7194                    finishedReceiver.performReceive(intent, 0,
7195                            null, null, false, false, UserHandle.getCallingUserId());
7196                } catch (RemoteException e) {
7197                }
7198            }
7199            return 0;
7200        }
7201    }
7202
7203    /**
7204     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7205     *
7206     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7207     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7208     */
7209    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7210        if (DEBUG_WHITELISTS) {
7211            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7212                    + targetUid + ", " + duration + ")");
7213        }
7214        synchronized (mPidsSelfLocked) {
7215            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7216            if (pr == null) {
7217                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7218                return;
7219            }
7220            if (!pr.whitelistManager) {
7221                if (DEBUG_WHITELISTS) {
7222                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7223                            + callerPid + " is not allowed");
7224                }
7225                return;
7226            }
7227        }
7228
7229        final long token = Binder.clearCallingIdentity();
7230        try {
7231            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7232                    true, "pe from uid:" + callerUid);
7233        } finally {
7234            Binder.restoreCallingIdentity(token);
7235        }
7236    }
7237
7238    @Override
7239    public void cancelIntentSender(IIntentSender sender) {
7240        if (!(sender instanceof PendingIntentRecord)) {
7241            return;
7242        }
7243        synchronized(this) {
7244            PendingIntentRecord rec = (PendingIntentRecord)sender;
7245            try {
7246                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7247                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7248                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7249                    String msg = "Permission Denial: cancelIntentSender() from pid="
7250                        + Binder.getCallingPid()
7251                        + ", uid=" + Binder.getCallingUid()
7252                        + " is not allowed to cancel packges "
7253                        + rec.key.packageName;
7254                    Slog.w(TAG, msg);
7255                    throw new SecurityException(msg);
7256                }
7257            } catch (RemoteException e) {
7258                throw new SecurityException(e);
7259            }
7260            cancelIntentSenderLocked(rec, true);
7261        }
7262    }
7263
7264    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7265        rec.canceled = true;
7266        mIntentSenderRecords.remove(rec.key);
7267        if (cleanActivity && rec.key.activity != null) {
7268            rec.key.activity.pendingResults.remove(rec.ref);
7269        }
7270    }
7271
7272    @Override
7273    public String getPackageForIntentSender(IIntentSender pendingResult) {
7274        if (!(pendingResult instanceof PendingIntentRecord)) {
7275            return null;
7276        }
7277        try {
7278            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7279            return res.key.packageName;
7280        } catch (ClassCastException e) {
7281        }
7282        return null;
7283    }
7284
7285    @Override
7286    public int getUidForIntentSender(IIntentSender sender) {
7287        if (sender instanceof PendingIntentRecord) {
7288            try {
7289                PendingIntentRecord res = (PendingIntentRecord)sender;
7290                return res.uid;
7291            } catch (ClassCastException e) {
7292            }
7293        }
7294        return -1;
7295    }
7296
7297    @Override
7298    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7299        if (!(pendingResult instanceof PendingIntentRecord)) {
7300            return false;
7301        }
7302        try {
7303            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7304            if (res.key.allIntents == null) {
7305                return false;
7306            }
7307            for (int i=0; i<res.key.allIntents.length; i++) {
7308                Intent intent = res.key.allIntents[i];
7309                if (intent.getPackage() != null && intent.getComponent() != null) {
7310                    return false;
7311                }
7312            }
7313            return true;
7314        } catch (ClassCastException e) {
7315        }
7316        return false;
7317    }
7318
7319    @Override
7320    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7321        if (!(pendingResult instanceof PendingIntentRecord)) {
7322            return false;
7323        }
7324        try {
7325            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7326            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7327                return true;
7328            }
7329            return false;
7330        } catch (ClassCastException e) {
7331        }
7332        return false;
7333    }
7334
7335    @Override
7336    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7337        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7338                "getIntentForIntentSender()");
7339        if (!(pendingResult instanceof PendingIntentRecord)) {
7340            return null;
7341        }
7342        try {
7343            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7345        } catch (ClassCastException e) {
7346        }
7347        return null;
7348    }
7349
7350    @Override
7351    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7352        if (!(pendingResult instanceof PendingIntentRecord)) {
7353            return null;
7354        }
7355        try {
7356            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7357            synchronized (this) {
7358                return getTagForIntentSenderLocked(res, prefix);
7359            }
7360        } catch (ClassCastException e) {
7361        }
7362        return null;
7363    }
7364
7365    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7366        final Intent intent = res.key.requestIntent;
7367        if (intent != null) {
7368            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7369                    || res.lastTagPrefix.equals(prefix))) {
7370                return res.lastTag;
7371            }
7372            res.lastTagPrefix = prefix;
7373            final StringBuilder sb = new StringBuilder(128);
7374            if (prefix != null) {
7375                sb.append(prefix);
7376            }
7377            if (intent.getAction() != null) {
7378                sb.append(intent.getAction());
7379            } else if (intent.getComponent() != null) {
7380                intent.getComponent().appendShortString(sb);
7381            } else {
7382                sb.append("?");
7383            }
7384            return res.lastTag = sb.toString();
7385        }
7386        return null;
7387    }
7388
7389    @Override
7390    public void setProcessLimit(int max) {
7391        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7392                "setProcessLimit()");
7393        synchronized (this) {
7394            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7395            mProcessLimitOverride = max;
7396        }
7397        trimApplications();
7398    }
7399
7400    @Override
7401    public int getProcessLimit() {
7402        synchronized (this) {
7403            return mProcessLimitOverride;
7404        }
7405    }
7406
7407    void foregroundTokenDied(ForegroundToken token) {
7408        synchronized (ActivityManagerService.this) {
7409            synchronized (mPidsSelfLocked) {
7410                ForegroundToken cur
7411                    = mForegroundProcesses.get(token.pid);
7412                if (cur != token) {
7413                    return;
7414                }
7415                mForegroundProcesses.remove(token.pid);
7416                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7417                if (pr == null) {
7418                    return;
7419                }
7420                pr.forcingToForeground = null;
7421                updateProcessForegroundLocked(pr, false, false);
7422            }
7423            updateOomAdjLocked();
7424        }
7425    }
7426
7427    @Override
7428    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7429        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7430                "setProcessForeground()");
7431        synchronized(this) {
7432            boolean changed = false;
7433
7434            synchronized (mPidsSelfLocked) {
7435                ProcessRecord pr = mPidsSelfLocked.get(pid);
7436                if (pr == null && isForeground) {
7437                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7438                    return;
7439                }
7440                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7441                if (oldToken != null) {
7442                    oldToken.token.unlinkToDeath(oldToken, 0);
7443                    mForegroundProcesses.remove(pid);
7444                    if (pr != null) {
7445                        pr.forcingToForeground = null;
7446                    }
7447                    changed = true;
7448                }
7449                if (isForeground && token != null) {
7450                    ForegroundToken newToken = new ForegroundToken() {
7451                        @Override
7452                        public void binderDied() {
7453                            foregroundTokenDied(this);
7454                        }
7455                    };
7456                    newToken.pid = pid;
7457                    newToken.token = token;
7458                    try {
7459                        token.linkToDeath(newToken, 0);
7460                        mForegroundProcesses.put(pid, newToken);
7461                        pr.forcingToForeground = token;
7462                        changed = true;
7463                    } catch (RemoteException e) {
7464                        // If the process died while doing this, we will later
7465                        // do the cleanup with the process death link.
7466                    }
7467                }
7468            }
7469
7470            if (changed) {
7471                updateOomAdjLocked();
7472            }
7473        }
7474    }
7475
7476    @Override
7477    public boolean isAppForeground(int uid) throws RemoteException {
7478        synchronized (this) {
7479            UidRecord uidRec = mActiveUids.get(uid);
7480            if (uidRec == null || uidRec.idle) {
7481                return false;
7482            }
7483            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7484        }
7485    }
7486
7487    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7488    // be guarded by permission checking.
7489    int getUidState(int uid) {
7490        synchronized (this) {
7491            UidRecord uidRec = mActiveUids.get(uid);
7492            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7493        }
7494    }
7495
7496    @Override
7497    public boolean isInMultiWindowMode(IBinder token) {
7498        final long origId = Binder.clearCallingIdentity();
7499        try {
7500            synchronized(this) {
7501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7502                if (r == null) {
7503                    return false;
7504                }
7505                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7506                return !r.task.mFullscreen;
7507            }
7508        } finally {
7509            Binder.restoreCallingIdentity(origId);
7510        }
7511    }
7512
7513    @Override
7514    public boolean isInPictureInPictureMode(IBinder token) {
7515        final long origId = Binder.clearCallingIdentity();
7516        try {
7517            synchronized(this) {
7518                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7519                if (stack == null) {
7520                    return false;
7521                }
7522                return stack.mStackId == PINNED_STACK_ID;
7523            }
7524        } finally {
7525            Binder.restoreCallingIdentity(origId);
7526        }
7527    }
7528
7529    @Override
7530    public void enterPictureInPictureMode(IBinder token) {
7531        final long origId = Binder.clearCallingIdentity();
7532        try {
7533            synchronized(this) {
7534                if (!mSupportsPictureInPicture) {
7535                    throw new IllegalStateException("enterPictureInPictureMode: "
7536                            + "Device doesn't support picture-in-picture mode.");
7537                }
7538
7539                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7540
7541                if (r == null) {
7542                    throw new IllegalStateException("enterPictureInPictureMode: "
7543                            + "Can't find activity for token=" + token);
7544                }
7545
7546                if (!r.supportsPictureInPicture()) {
7547                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7548                            + "Picture-In-Picture not supported for r=" + r);
7549                }
7550
7551                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7552                // current bounds.
7553                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7554                final Rect bounds = (pinnedStack != null)
7555                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7556
7557                mStackSupervisor.moveActivityToPinnedStackLocked(
7558                        r, "enterPictureInPictureMode", bounds);
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(origId);
7562        }
7563    }
7564
7565    // =========================================================
7566    // PROCESS INFO
7567    // =========================================================
7568
7569    static class ProcessInfoService extends IProcessInfoService.Stub {
7570        final ActivityManagerService mActivityManagerService;
7571        ProcessInfoService(ActivityManagerService activityManagerService) {
7572            mActivityManagerService = activityManagerService;
7573        }
7574
7575        @Override
7576        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7577            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7578                    /*in*/ pids, /*out*/ states, null);
7579        }
7580
7581        @Override
7582        public void getProcessStatesAndOomScoresFromPids(
7583                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7584            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7585                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7586        }
7587    }
7588
7589    /**
7590     * For each PID in the given input array, write the current process state
7591     * for that process into the states array, or -1 to indicate that no
7592     * process with the given PID exists. If scores array is provided, write
7593     * the oom score for the process into the scores array, with INVALID_ADJ
7594     * indicating the PID doesn't exist.
7595     */
7596    public void getProcessStatesAndOomScoresForPIDs(
7597            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7598        if (scores != null) {
7599            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7600                    "getProcessStatesAndOomScoresForPIDs()");
7601        }
7602
7603        if (pids == null) {
7604            throw new NullPointerException("pids");
7605        } else if (states == null) {
7606            throw new NullPointerException("states");
7607        } else if (pids.length != states.length) {
7608            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7609        } else if (scores != null && pids.length != scores.length) {
7610            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7611        }
7612
7613        synchronized (mPidsSelfLocked) {
7614            for (int i = 0; i < pids.length; i++) {
7615                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7616                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7617                        pr.curProcState;
7618                if (scores != null) {
7619                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7620                }
7621            }
7622        }
7623    }
7624
7625    // =========================================================
7626    // PERMISSIONS
7627    // =========================================================
7628
7629    static class PermissionController extends IPermissionController.Stub {
7630        ActivityManagerService mActivityManagerService;
7631        PermissionController(ActivityManagerService activityManagerService) {
7632            mActivityManagerService = activityManagerService;
7633        }
7634
7635        @Override
7636        public boolean checkPermission(String permission, int pid, int uid) {
7637            return mActivityManagerService.checkPermission(permission, pid,
7638                    uid) == PackageManager.PERMISSION_GRANTED;
7639        }
7640
7641        @Override
7642        public String[] getPackagesForUid(int uid) {
7643            return mActivityManagerService.mContext.getPackageManager()
7644                    .getPackagesForUid(uid);
7645        }
7646
7647        @Override
7648        public boolean isRuntimePermission(String permission) {
7649            try {
7650                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7651                        .getPermissionInfo(permission, 0);
7652                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7653            } catch (NameNotFoundException nnfe) {
7654                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7655            }
7656            return false;
7657        }
7658    }
7659
7660    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7661        @Override
7662        public int checkComponentPermission(String permission, int pid, int uid,
7663                int owningUid, boolean exported) {
7664            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7665                    owningUid, exported);
7666        }
7667
7668        @Override
7669        public Object getAMSLock() {
7670            return ActivityManagerService.this;
7671        }
7672    }
7673
7674    /**
7675     * This can be called with or without the global lock held.
7676     */
7677    int checkComponentPermission(String permission, int pid, int uid,
7678            int owningUid, boolean exported) {
7679        if (pid == MY_PID) {
7680            return PackageManager.PERMISSION_GRANTED;
7681        }
7682        return ActivityManager.checkComponentPermission(permission, uid,
7683                owningUid, exported);
7684    }
7685
7686    /**
7687     * As the only public entry point for permissions checking, this method
7688     * can enforce the semantic that requesting a check on a null global
7689     * permission is automatically denied.  (Internally a null permission
7690     * string is used when calling {@link #checkComponentPermission} in cases
7691     * when only uid-based security is needed.)
7692     *
7693     * This can be called with or without the global lock held.
7694     */
7695    @Override
7696    public int checkPermission(String permission, int pid, int uid) {
7697        if (permission == null) {
7698            return PackageManager.PERMISSION_DENIED;
7699        }
7700        return checkComponentPermission(permission, pid, uid, -1, true);
7701    }
7702
7703    @Override
7704    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7705        if (permission == null) {
7706            return PackageManager.PERMISSION_DENIED;
7707        }
7708
7709        // We might be performing an operation on behalf of an indirect binder
7710        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7711        // client identity accordingly before proceeding.
7712        Identity tlsIdentity = sCallerIdentity.get();
7713        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7714            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7715                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7716            uid = tlsIdentity.uid;
7717            pid = tlsIdentity.pid;
7718        }
7719
7720        return checkComponentPermission(permission, pid, uid, -1, true);
7721    }
7722
7723    /**
7724     * Binder IPC calls go through the public entry point.
7725     * This can be called with or without the global lock held.
7726     */
7727    int checkCallingPermission(String permission) {
7728        return checkPermission(permission,
7729                Binder.getCallingPid(),
7730                UserHandle.getAppId(Binder.getCallingUid()));
7731    }
7732
7733    /**
7734     * This can be called with or without the global lock held.
7735     */
7736    void enforceCallingPermission(String permission, String func) {
7737        if (checkCallingPermission(permission)
7738                == PackageManager.PERMISSION_GRANTED) {
7739            return;
7740        }
7741
7742        String msg = "Permission Denial: " + func + " from pid="
7743                + Binder.getCallingPid()
7744                + ", uid=" + Binder.getCallingUid()
7745                + " requires " + permission;
7746        Slog.w(TAG, msg);
7747        throw new SecurityException(msg);
7748    }
7749
7750    /**
7751     * Determine if UID is holding permissions required to access {@link Uri} in
7752     * the given {@link ProviderInfo}. Final permission checking is always done
7753     * in {@link ContentProvider}.
7754     */
7755    private final boolean checkHoldingPermissionsLocked(
7756            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7757        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7759        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7760            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7761                    != PERMISSION_GRANTED) {
7762                return false;
7763            }
7764        }
7765        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7766    }
7767
7768    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7769            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7770        if (pi.applicationInfo.uid == uid) {
7771            return true;
7772        } else if (!pi.exported) {
7773            return false;
7774        }
7775
7776        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7777        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7778        try {
7779            // check if target holds top-level <provider> permissions
7780            if (!readMet && pi.readPermission != null && considerUidPermissions
7781                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7782                readMet = true;
7783            }
7784            if (!writeMet && pi.writePermission != null && considerUidPermissions
7785                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7786                writeMet = true;
7787            }
7788
7789            // track if unprotected read/write is allowed; any denied
7790            // <path-permission> below removes this ability
7791            boolean allowDefaultRead = pi.readPermission == null;
7792            boolean allowDefaultWrite = pi.writePermission == null;
7793
7794            // check if target holds any <path-permission> that match uri
7795            final PathPermission[] pps = pi.pathPermissions;
7796            if (pps != null) {
7797                final String path = grantUri.uri.getPath();
7798                int i = pps.length;
7799                while (i > 0 && (!readMet || !writeMet)) {
7800                    i--;
7801                    PathPermission pp = pps[i];
7802                    if (pp.match(path)) {
7803                        if (!readMet) {
7804                            final String pprperm = pp.getReadPermission();
7805                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7807                                    + ": match=" + pp.match(path)
7808                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7809                            if (pprperm != null) {
7810                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7811                                        == PERMISSION_GRANTED) {
7812                                    readMet = true;
7813                                } else {
7814                                    allowDefaultRead = false;
7815                                }
7816                            }
7817                        }
7818                        if (!writeMet) {
7819                            final String ppwperm = pp.getWritePermission();
7820                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7822                                    + ": match=" + pp.match(path)
7823                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7824                            if (ppwperm != null) {
7825                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7826                                        == PERMISSION_GRANTED) {
7827                                    writeMet = true;
7828                                } else {
7829                                    allowDefaultWrite = false;
7830                                }
7831                            }
7832                        }
7833                    }
7834                }
7835            }
7836
7837            // grant unprotected <provider> read/write, if not blocked by
7838            // <path-permission> above
7839            if (allowDefaultRead) readMet = true;
7840            if (allowDefaultWrite) writeMet = true;
7841
7842        } catch (RemoteException e) {
7843            return false;
7844        }
7845
7846        return readMet && writeMet;
7847    }
7848
7849    public int getAppStartMode(int uid, String packageName) {
7850        synchronized (this) {
7851            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7852        }
7853    }
7854
7855    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7856            boolean allowWhenForeground) {
7857        UidRecord uidRec = mActiveUids.get(uid);
7858        if (!mLenientBackgroundCheck) {
7859            if (!allowWhenForeground || uidRec == null
7860                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7861                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7862                        packageName) != AppOpsManager.MODE_ALLOWED) {
7863                    return ActivityManager.APP_START_MODE_DELAYED;
7864                }
7865            }
7866
7867        } else if (uidRec == null || uidRec.idle) {
7868            if (callingPid >= 0) {
7869                ProcessRecord proc;
7870                synchronized (mPidsSelfLocked) {
7871                    proc = mPidsSelfLocked.get(callingPid);
7872                }
7873                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7874                    // Whoever is instigating this is in the foreground, so we will allow it
7875                    // to go through.
7876                    return ActivityManager.APP_START_MODE_NORMAL;
7877                }
7878            }
7879            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7880                    != AppOpsManager.MODE_ALLOWED) {
7881                return ActivityManager.APP_START_MODE_DELAYED;
7882            }
7883        }
7884        return ActivityManager.APP_START_MODE_NORMAL;
7885    }
7886
7887    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7888        ProviderInfo pi = null;
7889        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7890        if (cpr != null) {
7891            pi = cpr.info;
7892        } else {
7893            try {
7894                pi = AppGlobals.getPackageManager().resolveContentProvider(
7895                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7896                        userHandle);
7897            } catch (RemoteException ex) {
7898            }
7899        }
7900        return pi;
7901    }
7902
7903    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7904        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7905        if (targetUris != null) {
7906            return targetUris.get(grantUri);
7907        }
7908        return null;
7909    }
7910
7911    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7912            String targetPkg, int targetUid, GrantUri grantUri) {
7913        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7914        if (targetUris == null) {
7915            targetUris = Maps.newArrayMap();
7916            mGrantedUriPermissions.put(targetUid, targetUris);
7917        }
7918
7919        UriPermission perm = targetUris.get(grantUri);
7920        if (perm == null) {
7921            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7922            targetUris.put(grantUri, perm);
7923        }
7924
7925        return perm;
7926    }
7927
7928    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7929            final int modeFlags) {
7930        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7931        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7932                : UriPermission.STRENGTH_OWNED;
7933
7934        // Root gets to do everything.
7935        if (uid == 0) {
7936            return true;
7937        }
7938
7939        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7940        if (perms == null) return false;
7941
7942        // First look for exact match
7943        final UriPermission exactPerm = perms.get(grantUri);
7944        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7945            return true;
7946        }
7947
7948        // No exact match, look for prefixes
7949        final int N = perms.size();
7950        for (int i = 0; i < N; i++) {
7951            final UriPermission perm = perms.valueAt(i);
7952            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7953                    && perm.getStrength(modeFlags) >= minStrength) {
7954                return true;
7955            }
7956        }
7957
7958        return false;
7959    }
7960
7961    /**
7962     * @param uri This uri must NOT contain an embedded userId.
7963     * @param userId The userId in which the uri is to be resolved.
7964     */
7965    @Override
7966    public int checkUriPermission(Uri uri, int pid, int uid,
7967            final int modeFlags, int userId, IBinder callerToken) {
7968        enforceNotIsolatedCaller("checkUriPermission");
7969
7970        // Another redirected-binder-call permissions check as in
7971        // {@link checkPermissionWithToken}.
7972        Identity tlsIdentity = sCallerIdentity.get();
7973        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7974            uid = tlsIdentity.uid;
7975            pid = tlsIdentity.pid;
7976        }
7977
7978        // Our own process gets to do everything.
7979        if (pid == MY_PID) {
7980            return PackageManager.PERMISSION_GRANTED;
7981        }
7982        synchronized (this) {
7983            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7984                    ? PackageManager.PERMISSION_GRANTED
7985                    : PackageManager.PERMISSION_DENIED;
7986        }
7987    }
7988
7989    /**
7990     * Check if the targetPkg can be granted permission to access uri by
7991     * the callingUid using the given modeFlags.  Throws a security exception
7992     * if callingUid is not allowed to do this.  Returns the uid of the target
7993     * if the URI permission grant should be performed; returns -1 if it is not
7994     * needed (for example targetPkg already has permission to access the URI).
7995     * If you already know the uid of the target, you can supply it in
7996     * lastTargetUid else set that to -1.
7997     */
7998    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7999            final int modeFlags, int lastTargetUid) {
8000        if (!Intent.isAccessUriMode(modeFlags)) {
8001            return -1;
8002        }
8003
8004        if (targetPkg != null) {
8005            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8006                    "Checking grant " + targetPkg + " permission to " + grantUri);
8007        }
8008
8009        final IPackageManager pm = AppGlobals.getPackageManager();
8010
8011        // If this is not a content: uri, we can't do anything with it.
8012        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8013            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                    "Can't grant URI permission for non-content URI: " + grantUri);
8015            return -1;
8016        }
8017
8018        final String authority = grantUri.uri.getAuthority();
8019        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8020                MATCH_DEBUG_TRIAGED_MISSING);
8021        if (pi == null) {
8022            Slog.w(TAG, "No content provider found for permission check: " +
8023                    grantUri.uri.toSafeString());
8024            return -1;
8025        }
8026
8027        int targetUid = lastTargetUid;
8028        if (targetUid < 0 && targetPkg != null) {
8029            try {
8030                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8031                        UserHandle.getUserId(callingUid));
8032                if (targetUid < 0) {
8033                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8034                            "Can't grant URI permission no uid for: " + targetPkg);
8035                    return -1;
8036                }
8037            } catch (RemoteException ex) {
8038                return -1;
8039            }
8040        }
8041
8042        if (targetUid >= 0) {
8043            // First...  does the target actually need this permission?
8044            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8045                // No need to grant the target this permission.
8046                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8047                        "Target " + targetPkg + " already has full permission to " + grantUri);
8048                return -1;
8049            }
8050        } else {
8051            // First...  there is no target package, so can anyone access it?
8052            boolean allowed = pi.exported;
8053            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8054                if (pi.readPermission != null) {
8055                    allowed = false;
8056                }
8057            }
8058            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8059                if (pi.writePermission != null) {
8060                    allowed = false;
8061                }
8062            }
8063            if (allowed) {
8064                return -1;
8065            }
8066        }
8067
8068        /* There is a special cross user grant if:
8069         * - The target is on another user.
8070         * - Apps on the current user can access the uri without any uid permissions.
8071         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8072         * grant uri permissions.
8073         */
8074        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8075                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8076                modeFlags, false /*without considering the uid permissions*/);
8077
8078        // Second...  is the provider allowing granting of URI permissions?
8079        if (!specialCrossUserGrant) {
8080            if (!pi.grantUriPermissions) {
8081                throw new SecurityException("Provider " + pi.packageName
8082                        + "/" + pi.name
8083                        + " does not allow granting of Uri permissions (uri "
8084                        + grantUri + ")");
8085            }
8086            if (pi.uriPermissionPatterns != null) {
8087                final int N = pi.uriPermissionPatterns.length;
8088                boolean allowed = false;
8089                for (int i=0; i<N; i++) {
8090                    if (pi.uriPermissionPatterns[i] != null
8091                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8092                        allowed = true;
8093                        break;
8094                    }
8095                }
8096                if (!allowed) {
8097                    throw new SecurityException("Provider " + pi.packageName
8098                            + "/" + pi.name
8099                            + " does not allow granting of permission to path of Uri "
8100                            + grantUri);
8101                }
8102            }
8103        }
8104
8105        // Third...  does the caller itself have permission to access
8106        // this uri?
8107        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8108            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8109                // Require they hold a strong enough Uri permission
8110                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8111                    throw new SecurityException("Uid " + callingUid
8112                            + " does not have permission to uri " + grantUri);
8113                }
8114            }
8115        }
8116        return targetUid;
8117    }
8118
8119    /**
8120     * @param uri This uri must NOT contain an embedded userId.
8121     * @param userId The userId in which the uri is to be resolved.
8122     */
8123    @Override
8124    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8125            final int modeFlags, int userId) {
8126        enforceNotIsolatedCaller("checkGrantUriPermission");
8127        synchronized(this) {
8128            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8129                    new GrantUri(userId, uri, false), modeFlags, -1);
8130        }
8131    }
8132
8133    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8134            final int modeFlags, UriPermissionOwner owner) {
8135        if (!Intent.isAccessUriMode(modeFlags)) {
8136            return;
8137        }
8138
8139        // So here we are: the caller has the assumed permission
8140        // to the uri, and the target doesn't.  Let's now give this to
8141        // the target.
8142
8143        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8144                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8145
8146        final String authority = grantUri.uri.getAuthority();
8147        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8148                MATCH_DEBUG_TRIAGED_MISSING);
8149        if (pi == null) {
8150            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8151            return;
8152        }
8153
8154        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8155            grantUri.prefix = true;
8156        }
8157        final UriPermission perm = findOrCreateUriPermissionLocked(
8158                pi.packageName, targetPkg, targetUid, grantUri);
8159        perm.grantModes(modeFlags, owner);
8160    }
8161
8162    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8163            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8164        if (targetPkg == null) {
8165            throw new NullPointerException("targetPkg");
8166        }
8167        int targetUid;
8168        final IPackageManager pm = AppGlobals.getPackageManager();
8169        try {
8170            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8171        } catch (RemoteException ex) {
8172            return;
8173        }
8174
8175        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8176                targetUid);
8177        if (targetUid < 0) {
8178            return;
8179        }
8180
8181        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8182                owner);
8183    }
8184
8185    static class NeededUriGrants extends ArrayList<GrantUri> {
8186        final String targetPkg;
8187        final int targetUid;
8188        final int flags;
8189
8190        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8191            this.targetPkg = targetPkg;
8192            this.targetUid = targetUid;
8193            this.flags = flags;
8194        }
8195    }
8196
8197    /**
8198     * Like checkGrantUriPermissionLocked, but takes an Intent.
8199     */
8200    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8201            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8202        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8203                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8204                + " clip=" + (intent != null ? intent.getClipData() : null)
8205                + " from " + intent + "; flags=0x"
8206                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8207
8208        if (targetPkg == null) {
8209            throw new NullPointerException("targetPkg");
8210        }
8211
8212        if (intent == null) {
8213            return null;
8214        }
8215        Uri data = intent.getData();
8216        ClipData clip = intent.getClipData();
8217        if (data == null && clip == null) {
8218            return null;
8219        }
8220        // Default userId for uris in the intent (if they don't specify it themselves)
8221        int contentUserHint = intent.getContentUserHint();
8222        if (contentUserHint == UserHandle.USER_CURRENT) {
8223            contentUserHint = UserHandle.getUserId(callingUid);
8224        }
8225        final IPackageManager pm = AppGlobals.getPackageManager();
8226        int targetUid;
8227        if (needed != null) {
8228            targetUid = needed.targetUid;
8229        } else {
8230            try {
8231                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8232                        targetUserId);
8233            } catch (RemoteException ex) {
8234                return null;
8235            }
8236            if (targetUid < 0) {
8237                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8238                        "Can't grant URI permission no uid for: " + targetPkg
8239                        + " on user " + targetUserId);
8240                return null;
8241            }
8242        }
8243        if (data != null) {
8244            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8245            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8246                    targetUid);
8247            if (targetUid > 0) {
8248                if (needed == null) {
8249                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8250                }
8251                needed.add(grantUri);
8252            }
8253        }
8254        if (clip != null) {
8255            for (int i=0; i<clip.getItemCount(); i++) {
8256                Uri uri = clip.getItemAt(i).getUri();
8257                if (uri != null) {
8258                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8259                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8260                            targetUid);
8261                    if (targetUid > 0) {
8262                        if (needed == null) {
8263                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8264                        }
8265                        needed.add(grantUri);
8266                    }
8267                } else {
8268                    Intent clipIntent = clip.getItemAt(i).getIntent();
8269                    if (clipIntent != null) {
8270                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8271                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8272                        if (newNeeded != null) {
8273                            needed = newNeeded;
8274                        }
8275                    }
8276                }
8277            }
8278        }
8279
8280        return needed;
8281    }
8282
8283    /**
8284     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8285     */
8286    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8287            UriPermissionOwner owner) {
8288        if (needed != null) {
8289            for (int i=0; i<needed.size(); i++) {
8290                GrantUri grantUri = needed.get(i);
8291                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8292                        grantUri, needed.flags, owner);
8293            }
8294        }
8295    }
8296
8297    void grantUriPermissionFromIntentLocked(int callingUid,
8298            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8299        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8300                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8301        if (needed == null) {
8302            return;
8303        }
8304
8305        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8306    }
8307
8308    /**
8309     * @param uri This uri must NOT contain an embedded userId.
8310     * @param userId The userId in which the uri is to be resolved.
8311     */
8312    @Override
8313    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8314            final int modeFlags, int userId) {
8315        enforceNotIsolatedCaller("grantUriPermission");
8316        GrantUri grantUri = new GrantUri(userId, uri, false);
8317        synchronized(this) {
8318            final ProcessRecord r = getRecordForAppLocked(caller);
8319            if (r == null) {
8320                throw new SecurityException("Unable to find app for caller "
8321                        + caller
8322                        + " when granting permission to uri " + grantUri);
8323            }
8324            if (targetPkg == null) {
8325                throw new IllegalArgumentException("null target");
8326            }
8327            if (grantUri == null) {
8328                throw new IllegalArgumentException("null uri");
8329            }
8330
8331            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8332                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8333                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8334                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8335
8336            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8337                    UserHandle.getUserId(r.uid));
8338        }
8339    }
8340
8341    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8342        if (perm.modeFlags == 0) {
8343            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8344                    perm.targetUid);
8345            if (perms != null) {
8346                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8347                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8348
8349                perms.remove(perm.uri);
8350                if (perms.isEmpty()) {
8351                    mGrantedUriPermissions.remove(perm.targetUid);
8352                }
8353            }
8354        }
8355    }
8356
8357    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8358        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8359                "Revoking all granted permissions to " + grantUri);
8360
8361        final IPackageManager pm = AppGlobals.getPackageManager();
8362        final String authority = grantUri.uri.getAuthority();
8363        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8364                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8365        if (pi == null) {
8366            Slog.w(TAG, "No content provider found for permission revoke: "
8367                    + grantUri.toSafeString());
8368            return;
8369        }
8370
8371        // Does the caller have this permission on the URI?
8372        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8373            // If they don't have direct access to the URI, then revoke any
8374            // ownerless URI permissions that have been granted to them.
8375            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8376            if (perms != null) {
8377                boolean persistChanged = false;
8378                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8379                    final UriPermission perm = it.next();
8380                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8381                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8382                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8383                                "Revoking non-owned " + perm.targetUid
8384                                + " permission to " + perm.uri);
8385                        persistChanged |= perm.revokeModes(
8386                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8387                        if (perm.modeFlags == 0) {
8388                            it.remove();
8389                        }
8390                    }
8391                }
8392                if (perms.isEmpty()) {
8393                    mGrantedUriPermissions.remove(callingUid);
8394                }
8395                if (persistChanged) {
8396                    schedulePersistUriGrants();
8397                }
8398            }
8399            return;
8400        }
8401
8402        boolean persistChanged = false;
8403
8404        // Go through all of the permissions and remove any that match.
8405        int N = mGrantedUriPermissions.size();
8406        for (int i = 0; i < N; i++) {
8407            final int targetUid = mGrantedUriPermissions.keyAt(i);
8408            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8409
8410            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8411                final UriPermission perm = it.next();
8412                if (perm.uri.sourceUserId == grantUri.sourceUserId
8413                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8414                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8415                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8416                    persistChanged |= perm.revokeModes(
8417                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8418                    if (perm.modeFlags == 0) {
8419                        it.remove();
8420                    }
8421                }
8422            }
8423
8424            if (perms.isEmpty()) {
8425                mGrantedUriPermissions.remove(targetUid);
8426                N--;
8427                i--;
8428            }
8429        }
8430
8431        if (persistChanged) {
8432            schedulePersistUriGrants();
8433        }
8434    }
8435
8436    /**
8437     * @param uri This uri must NOT contain an embedded userId.
8438     * @param userId The userId in which the uri is to be resolved.
8439     */
8440    @Override
8441    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8442            int userId) {
8443        enforceNotIsolatedCaller("revokeUriPermission");
8444        synchronized(this) {
8445            final ProcessRecord r = getRecordForAppLocked(caller);
8446            if (r == null) {
8447                throw new SecurityException("Unable to find app for caller "
8448                        + caller
8449                        + " when revoking permission to uri " + uri);
8450            }
8451            if (uri == null) {
8452                Slog.w(TAG, "revokeUriPermission: null uri");
8453                return;
8454            }
8455
8456            if (!Intent.isAccessUriMode(modeFlags)) {
8457                return;
8458            }
8459
8460            final String authority = uri.getAuthority();
8461            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8462                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8463            if (pi == null) {
8464                Slog.w(TAG, "No content provider found for permission revoke: "
8465                        + uri.toSafeString());
8466                return;
8467            }
8468
8469            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8470        }
8471    }
8472
8473    /**
8474     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8475     * given package.
8476     *
8477     * @param packageName Package name to match, or {@code null} to apply to all
8478     *            packages.
8479     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8480     *            to all users.
8481     * @param persistable If persistable grants should be removed.
8482     */
8483    private void removeUriPermissionsForPackageLocked(
8484            String packageName, int userHandle, boolean persistable) {
8485        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8486            throw new IllegalArgumentException("Must narrow by either package or user");
8487        }
8488
8489        boolean persistChanged = false;
8490
8491        int N = mGrantedUriPermissions.size();
8492        for (int i = 0; i < N; i++) {
8493            final int targetUid = mGrantedUriPermissions.keyAt(i);
8494            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8495
8496            // Only inspect grants matching user
8497            if (userHandle == UserHandle.USER_ALL
8498                    || userHandle == UserHandle.getUserId(targetUid)) {
8499                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8500                    final UriPermission perm = it.next();
8501
8502                    // Only inspect grants matching package
8503                    if (packageName == null || perm.sourcePkg.equals(packageName)
8504                            || perm.targetPkg.equals(packageName)) {
8505                        persistChanged |= perm.revokeModes(persistable
8506                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8507
8508                        // Only remove when no modes remain; any persisted grants
8509                        // will keep this alive.
8510                        if (perm.modeFlags == 0) {
8511                            it.remove();
8512                        }
8513                    }
8514                }
8515
8516                if (perms.isEmpty()) {
8517                    mGrantedUriPermissions.remove(targetUid);
8518                    N--;
8519                    i--;
8520                }
8521            }
8522        }
8523
8524        if (persistChanged) {
8525            schedulePersistUriGrants();
8526        }
8527    }
8528
8529    @Override
8530    public IBinder newUriPermissionOwner(String name) {
8531        enforceNotIsolatedCaller("newUriPermissionOwner");
8532        synchronized(this) {
8533            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8534            return owner.getExternalTokenLocked();
8535        }
8536    }
8537
8538    @Override
8539    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8540        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8541        synchronized(this) {
8542            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8543            if (r == null) {
8544                throw new IllegalArgumentException("Activity does not exist; token="
8545                        + activityToken);
8546            }
8547            return r.getUriPermissionsLocked().getExternalTokenLocked();
8548        }
8549    }
8550    /**
8551     * @param uri This uri must NOT contain an embedded userId.
8552     * @param sourceUserId The userId in which the uri is to be resolved.
8553     * @param targetUserId The userId of the app that receives the grant.
8554     */
8555    @Override
8556    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8557            final int modeFlags, int sourceUserId, int targetUserId) {
8558        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8559                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8560                "grantUriPermissionFromOwner", null);
8561        synchronized(this) {
8562            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8563            if (owner == null) {
8564                throw new IllegalArgumentException("Unknown owner: " + token);
8565            }
8566            if (fromUid != Binder.getCallingUid()) {
8567                if (Binder.getCallingUid() != Process.myUid()) {
8568                    // Only system code can grant URI permissions on behalf
8569                    // of other users.
8570                    throw new SecurityException("nice try");
8571                }
8572            }
8573            if (targetPkg == null) {
8574                throw new IllegalArgumentException("null target");
8575            }
8576            if (uri == null) {
8577                throw new IllegalArgumentException("null uri");
8578            }
8579
8580            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8581                    modeFlags, owner, targetUserId);
8582        }
8583    }
8584
8585    /**
8586     * @param uri This uri must NOT contain an embedded userId.
8587     * @param userId The userId in which the uri is to be resolved.
8588     */
8589    @Override
8590    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8591        synchronized(this) {
8592            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8593            if (owner == null) {
8594                throw new IllegalArgumentException("Unknown owner: " + token);
8595            }
8596
8597            if (uri == null) {
8598                owner.removeUriPermissionsLocked(mode);
8599            } else {
8600                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8601            }
8602        }
8603    }
8604
8605    private void schedulePersistUriGrants() {
8606        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8607            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8608                    10 * DateUtils.SECOND_IN_MILLIS);
8609        }
8610    }
8611
8612    private void writeGrantedUriPermissions() {
8613        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8614
8615        // Snapshot permissions so we can persist without lock
8616        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8617        synchronized (this) {
8618            final int size = mGrantedUriPermissions.size();
8619            for (int i = 0; i < size; i++) {
8620                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8621                for (UriPermission perm : perms.values()) {
8622                    if (perm.persistedModeFlags != 0) {
8623                        persist.add(perm.snapshot());
8624                    }
8625                }
8626            }
8627        }
8628
8629        FileOutputStream fos = null;
8630        try {
8631            fos = mGrantFile.startWrite();
8632
8633            XmlSerializer out = new FastXmlSerializer();
8634            out.setOutput(fos, StandardCharsets.UTF_8.name());
8635            out.startDocument(null, true);
8636            out.startTag(null, TAG_URI_GRANTS);
8637            for (UriPermission.Snapshot perm : persist) {
8638                out.startTag(null, TAG_URI_GRANT);
8639                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8640                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8641                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8642                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8643                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8644                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8645                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8646                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8647                out.endTag(null, TAG_URI_GRANT);
8648            }
8649            out.endTag(null, TAG_URI_GRANTS);
8650            out.endDocument();
8651
8652            mGrantFile.finishWrite(fos);
8653        } catch (IOException e) {
8654            if (fos != null) {
8655                mGrantFile.failWrite(fos);
8656            }
8657        }
8658    }
8659
8660    private void readGrantedUriPermissionsLocked() {
8661        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8662
8663        final long now = System.currentTimeMillis();
8664
8665        FileInputStream fis = null;
8666        try {
8667            fis = mGrantFile.openRead();
8668            final XmlPullParser in = Xml.newPullParser();
8669            in.setInput(fis, StandardCharsets.UTF_8.name());
8670
8671            int type;
8672            while ((type = in.next()) != END_DOCUMENT) {
8673                final String tag = in.getName();
8674                if (type == START_TAG) {
8675                    if (TAG_URI_GRANT.equals(tag)) {
8676                        final int sourceUserId;
8677                        final int targetUserId;
8678                        final int userHandle = readIntAttribute(in,
8679                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8680                        if (userHandle != UserHandle.USER_NULL) {
8681                            // For backwards compatibility.
8682                            sourceUserId = userHandle;
8683                            targetUserId = userHandle;
8684                        } else {
8685                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8686                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8687                        }
8688                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8689                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8690                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8691                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8692                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8693                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8694
8695                        // Sanity check that provider still belongs to source package
8696                        // Both direct boot aware and unaware packages are fine as we
8697                        // will do filtering at query time to avoid multiple parsing.
8698                        final ProviderInfo pi = getProviderInfoLocked(
8699                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8700                                        | MATCH_DIRECT_BOOT_UNAWARE);
8701                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8702                            int targetUid = -1;
8703                            try {
8704                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8705                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8706                            } catch (RemoteException e) {
8707                            }
8708                            if (targetUid != -1) {
8709                                final UriPermission perm = findOrCreateUriPermissionLocked(
8710                                        sourcePkg, targetPkg, targetUid,
8711                                        new GrantUri(sourceUserId, uri, prefix));
8712                                perm.initPersistedModes(modeFlags, createdTime);
8713                            }
8714                        } else {
8715                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8716                                    + " but instead found " + pi);
8717                        }
8718                    }
8719                }
8720            }
8721        } catch (FileNotFoundException e) {
8722            // Missing grants is okay
8723        } catch (IOException e) {
8724            Slog.wtf(TAG, "Failed reading Uri grants", e);
8725        } catch (XmlPullParserException e) {
8726            Slog.wtf(TAG, "Failed reading Uri grants", e);
8727        } finally {
8728            IoUtils.closeQuietly(fis);
8729        }
8730    }
8731
8732    /**
8733     * @param uri This uri must NOT contain an embedded userId.
8734     * @param userId The userId in which the uri is to be resolved.
8735     */
8736    @Override
8737    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8738        enforceNotIsolatedCaller("takePersistableUriPermission");
8739
8740        Preconditions.checkFlagsArgument(modeFlags,
8741                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8742
8743        synchronized (this) {
8744            final int callingUid = Binder.getCallingUid();
8745            boolean persistChanged = false;
8746            GrantUri grantUri = new GrantUri(userId, uri, false);
8747
8748            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8749                    new GrantUri(userId, uri, false));
8750            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8751                    new GrantUri(userId, uri, true));
8752
8753            final boolean exactValid = (exactPerm != null)
8754                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8755            final boolean prefixValid = (prefixPerm != null)
8756                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8757
8758            if (!(exactValid || prefixValid)) {
8759                throw new SecurityException("No persistable permission grants found for UID "
8760                        + callingUid + " and Uri " + grantUri.toSafeString());
8761            }
8762
8763            if (exactValid) {
8764                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8765            }
8766            if (prefixValid) {
8767                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8768            }
8769
8770            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8771
8772            if (persistChanged) {
8773                schedulePersistUriGrants();
8774            }
8775        }
8776    }
8777
8778    /**
8779     * @param uri This uri must NOT contain an embedded userId.
8780     * @param userId The userId in which the uri is to be resolved.
8781     */
8782    @Override
8783    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8784        enforceNotIsolatedCaller("releasePersistableUriPermission");
8785
8786        Preconditions.checkFlagsArgument(modeFlags,
8787                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8788
8789        synchronized (this) {
8790            final int callingUid = Binder.getCallingUid();
8791            boolean persistChanged = false;
8792
8793            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8794                    new GrantUri(userId, uri, false));
8795            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8796                    new GrantUri(userId, uri, true));
8797            if (exactPerm == null && prefixPerm == null) {
8798                throw new SecurityException("No permission grants found for UID " + callingUid
8799                        + " and Uri " + uri.toSafeString());
8800            }
8801
8802            if (exactPerm != null) {
8803                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8804                removeUriPermissionIfNeededLocked(exactPerm);
8805            }
8806            if (prefixPerm != null) {
8807                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8808                removeUriPermissionIfNeededLocked(prefixPerm);
8809            }
8810
8811            if (persistChanged) {
8812                schedulePersistUriGrants();
8813            }
8814        }
8815    }
8816
8817    /**
8818     * Prune any older {@link UriPermission} for the given UID until outstanding
8819     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8820     *
8821     * @return if any mutations occured that require persisting.
8822     */
8823    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8824        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8825        if (perms == null) return false;
8826        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8827
8828        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8829        for (UriPermission perm : perms.values()) {
8830            if (perm.persistedModeFlags != 0) {
8831                persisted.add(perm);
8832            }
8833        }
8834
8835        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8836        if (trimCount <= 0) return false;
8837
8838        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8839        for (int i = 0; i < trimCount; i++) {
8840            final UriPermission perm = persisted.get(i);
8841
8842            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8843                    "Trimming grant created at " + perm.persistedCreateTime);
8844
8845            perm.releasePersistableModes(~0);
8846            removeUriPermissionIfNeededLocked(perm);
8847        }
8848
8849        return true;
8850    }
8851
8852    @Override
8853    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8854            String packageName, boolean incoming) {
8855        enforceNotIsolatedCaller("getPersistedUriPermissions");
8856        Preconditions.checkNotNull(packageName, "packageName");
8857
8858        final int callingUid = Binder.getCallingUid();
8859        final int callingUserId = UserHandle.getUserId(callingUid);
8860        final IPackageManager pm = AppGlobals.getPackageManager();
8861        try {
8862            final int packageUid = pm.getPackageUid(packageName,
8863                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8864            if (packageUid != callingUid) {
8865                throw new SecurityException(
8866                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8867            }
8868        } catch (RemoteException e) {
8869            throw new SecurityException("Failed to verify package name ownership");
8870        }
8871
8872        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8873        synchronized (this) {
8874            if (incoming) {
8875                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8876                        callingUid);
8877                if (perms == null) {
8878                    Slog.w(TAG, "No permission grants found for " + packageName);
8879                } else {
8880                    for (UriPermission perm : perms.values()) {
8881                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8882                            result.add(perm.buildPersistedPublicApiObject());
8883                        }
8884                    }
8885                }
8886            } else {
8887                final int size = mGrantedUriPermissions.size();
8888                for (int i = 0; i < size; i++) {
8889                    final ArrayMap<GrantUri, UriPermission> perms =
8890                            mGrantedUriPermissions.valueAt(i);
8891                    for (UriPermission perm : perms.values()) {
8892                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8893                            result.add(perm.buildPersistedPublicApiObject());
8894                        }
8895                    }
8896                }
8897            }
8898        }
8899        return new ParceledListSlice<android.content.UriPermission>(result);
8900    }
8901
8902    @Override
8903    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8904            String packageName, int userId) {
8905        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8906                "getGrantedUriPermissions");
8907
8908        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8909        synchronized (this) {
8910            final int size = mGrantedUriPermissions.size();
8911            for (int i = 0; i < size; i++) {
8912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8913                for (UriPermission perm : perms.values()) {
8914                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8915                            && perm.persistedModeFlags != 0) {
8916                        result.add(perm.buildPersistedPublicApiObject());
8917                    }
8918                }
8919            }
8920        }
8921        return new ParceledListSlice<android.content.UriPermission>(result);
8922    }
8923
8924    @Override
8925    public void clearGrantedUriPermissions(String packageName, int userId) {
8926        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8927                "clearGrantedUriPermissions");
8928        removeUriPermissionsForPackageLocked(packageName, userId, true);
8929    }
8930
8931    @Override
8932    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8933        synchronized (this) {
8934            ProcessRecord app =
8935                who != null ? getRecordForAppLocked(who) : null;
8936            if (app == null) return;
8937
8938            Message msg = Message.obtain();
8939            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8940            msg.obj = app;
8941            msg.arg1 = waiting ? 1 : 0;
8942            mUiHandler.sendMessage(msg);
8943        }
8944    }
8945
8946    @Override
8947    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8948        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8949        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8950        outInfo.availMem = Process.getFreeMemory();
8951        outInfo.totalMem = Process.getTotalMemory();
8952        outInfo.threshold = homeAppMem;
8953        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8954        outInfo.hiddenAppThreshold = cachedAppMem;
8955        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8956                ProcessList.SERVICE_ADJ);
8957        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8958                ProcessList.VISIBLE_APP_ADJ);
8959        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8960                ProcessList.FOREGROUND_APP_ADJ);
8961    }
8962
8963    // =========================================================
8964    // TASK MANAGEMENT
8965    // =========================================================
8966
8967    @Override
8968    public List<IAppTask> getAppTasks(String callingPackage) {
8969        int callingUid = Binder.getCallingUid();
8970        long ident = Binder.clearCallingIdentity();
8971
8972        synchronized(this) {
8973            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8974            try {
8975                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8976
8977                final int N = mRecentTasks.size();
8978                for (int i = 0; i < N; i++) {
8979                    TaskRecord tr = mRecentTasks.get(i);
8980                    // Skip tasks that do not match the caller.  We don't need to verify
8981                    // callingPackage, because we are also limiting to callingUid and know
8982                    // that will limit to the correct security sandbox.
8983                    if (tr.effectiveUid != callingUid) {
8984                        continue;
8985                    }
8986                    Intent intent = tr.getBaseIntent();
8987                    if (intent == null ||
8988                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8989                        continue;
8990                    }
8991                    ActivityManager.RecentTaskInfo taskInfo =
8992                            createRecentTaskInfoFromTaskRecord(tr);
8993                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8994                    list.add(taskImpl);
8995                }
8996            } finally {
8997                Binder.restoreCallingIdentity(ident);
8998            }
8999            return list;
9000        }
9001    }
9002
9003    @Override
9004    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9005        final int callingUid = Binder.getCallingUid();
9006        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9007
9008        synchronized(this) {
9009            if (DEBUG_ALL) Slog.v(
9010                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9011
9012            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9013                    callingUid);
9014
9015            // TODO: Improve with MRU list from all ActivityStacks.
9016            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9017        }
9018
9019        return list;
9020    }
9021
9022    /**
9023     * Creates a new RecentTaskInfo from a TaskRecord.
9024     */
9025    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9026        // Update the task description to reflect any changes in the task stack
9027        tr.updateTaskDescription();
9028
9029        // Compose the recent task info
9030        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9031        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9032        rti.persistentId = tr.taskId;
9033        rti.baseIntent = new Intent(tr.getBaseIntent());
9034        rti.origActivity = tr.origActivity;
9035        rti.realActivity = tr.realActivity;
9036        rti.description = tr.lastDescription;
9037        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9038        rti.userId = tr.userId;
9039        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9040        rti.firstActiveTime = tr.firstActiveTime;
9041        rti.lastActiveTime = tr.lastActiveTime;
9042        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9043        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9044        rti.numActivities = 0;
9045        if (tr.mBounds != null) {
9046            rti.bounds = new Rect(tr.mBounds);
9047        }
9048        rti.isDockable = tr.canGoInDockedStack();
9049        rti.resizeMode = tr.mResizeMode;
9050
9051        ActivityRecord base = null;
9052        ActivityRecord top = null;
9053        ActivityRecord tmp;
9054
9055        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9056            tmp = tr.mActivities.get(i);
9057            if (tmp.finishing) {
9058                continue;
9059            }
9060            base = tmp;
9061            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9062                top = base;
9063            }
9064            rti.numActivities++;
9065        }
9066
9067        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9068        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9069
9070        return rti;
9071    }
9072
9073    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9074        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9075                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9076        if (!allowed) {
9077            if (checkPermission(android.Manifest.permission.GET_TASKS,
9078                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9079                // Temporary compatibility: some existing apps on the system image may
9080                // still be requesting the old permission and not switched to the new
9081                // one; if so, we'll still allow them full access.  This means we need
9082                // to see if they are holding the old permission and are a system app.
9083                try {
9084                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9085                        allowed = true;
9086                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9087                                + " is using old GET_TASKS but privileged; allowing");
9088                    }
9089                } catch (RemoteException e) {
9090                }
9091            }
9092        }
9093        if (!allowed) {
9094            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9095                    + " does not hold REAL_GET_TASKS; limiting output");
9096        }
9097        return allowed;
9098    }
9099
9100    @Override
9101    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9102            int userId) {
9103        final int callingUid = Binder.getCallingUid();
9104        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9105                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9106
9107        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9108        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9109        synchronized (this) {
9110            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9111                    callingUid);
9112            final boolean detailed = checkCallingPermission(
9113                    android.Manifest.permission.GET_DETAILED_TASKS)
9114                    == PackageManager.PERMISSION_GRANTED;
9115
9116            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9117                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9118                return ParceledListSlice.emptyList();
9119            }
9120            mRecentTasks.loadUserRecentsLocked(userId);
9121
9122            final int recentsCount = mRecentTasks.size();
9123            ArrayList<ActivityManager.RecentTaskInfo> res =
9124                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9125
9126            final Set<Integer> includedUsers;
9127            if (includeProfiles) {
9128                includedUsers = mUserController.getProfileIds(userId);
9129            } else {
9130                includedUsers = new HashSet<>();
9131            }
9132            includedUsers.add(Integer.valueOf(userId));
9133
9134            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9135                TaskRecord tr = mRecentTasks.get(i);
9136                // Only add calling user or related users recent tasks
9137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9138                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9139                    continue;
9140                }
9141
9142                if (tr.realActivitySuspended) {
9143                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9144                    continue;
9145                }
9146
9147                // Return the entry if desired by the caller.  We always return
9148                // the first entry, because callers always expect this to be the
9149                // foreground app.  We may filter others if the caller has
9150                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9151                // we should exclude the entry.
9152
9153                if (i == 0
9154                        || withExcluded
9155                        || (tr.intent == null)
9156                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9157                                == 0)) {
9158                    if (!allowed) {
9159                        // If the caller doesn't have the GET_TASKS permission, then only
9160                        // allow them to see a small subset of tasks -- their own and home.
9161                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9163                            continue;
9164                        }
9165                    }
9166                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9167                        if (tr.stack != null && tr.stack.isHomeStack()) {
9168                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                    "Skipping, home stack task: " + tr);
9170                            continue;
9171                        }
9172                    }
9173                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9174                        final ActivityStack stack = tr.stack;
9175                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9176                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9177                                    "Skipping, top task in docked stack: " + tr);
9178                            continue;
9179                        }
9180                    }
9181                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9182                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9183                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                    "Skipping, pinned stack task: " + tr);
9185                            continue;
9186                        }
9187                    }
9188                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9189                        // Don't include auto remove tasks that are finished or finishing.
9190                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9191                                "Skipping, auto-remove without activity: " + tr);
9192                        continue;
9193                    }
9194                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9195                            && !tr.isAvailable) {
9196                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197                                "Skipping, unavail real act: " + tr);
9198                        continue;
9199                    }
9200
9201                    if (!tr.mUserSetupComplete) {
9202                        // Don't include task launched while user is not done setting-up.
9203                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9204                                "Skipping, user setup not complete: " + tr);
9205                        continue;
9206                    }
9207
9208                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9209                    if (!detailed) {
9210                        rti.baseIntent.replaceExtras((Bundle)null);
9211                    }
9212
9213                    res.add(rti);
9214                    maxNum--;
9215                }
9216            }
9217            return new ParceledListSlice<>(res);
9218        }
9219    }
9220
9221    @Override
9222    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9223        synchronized (this) {
9224            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9225                    "getTaskThumbnail()");
9226            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9227                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9228            if (tr != null) {
9229                return tr.getTaskThumbnailLocked();
9230            }
9231        }
9232        return null;
9233    }
9234
9235    @Override
9236    public int addAppTask(IBinder activityToken, Intent intent,
9237            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9238        final int callingUid = Binder.getCallingUid();
9239        final long callingIdent = Binder.clearCallingIdentity();
9240
9241        try {
9242            synchronized (this) {
9243                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9244                if (r == null) {
9245                    throw new IllegalArgumentException("Activity does not exist; token="
9246                            + activityToken);
9247                }
9248                ComponentName comp = intent.getComponent();
9249                if (comp == null) {
9250                    throw new IllegalArgumentException("Intent " + intent
9251                            + " must specify explicit component");
9252                }
9253                if (thumbnail.getWidth() != mThumbnailWidth
9254                        || thumbnail.getHeight() != mThumbnailHeight) {
9255                    throw new IllegalArgumentException("Bad thumbnail size: got "
9256                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9257                            + mThumbnailWidth + "x" + mThumbnailHeight);
9258                }
9259                if (intent.getSelector() != null) {
9260                    intent.setSelector(null);
9261                }
9262                if (intent.getSourceBounds() != null) {
9263                    intent.setSourceBounds(null);
9264                }
9265                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9266                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9267                        // The caller has added this as an auto-remove task...  that makes no
9268                        // sense, so turn off auto-remove.
9269                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9270                    }
9271                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9272                    // Must be a new task.
9273                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9274                }
9275                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9276                    mLastAddedTaskActivity = null;
9277                }
9278                ActivityInfo ainfo = mLastAddedTaskActivity;
9279                if (ainfo == null) {
9280                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9281                            comp, 0, UserHandle.getUserId(callingUid));
9282                    if (ainfo.applicationInfo.uid != callingUid) {
9283                        throw new SecurityException(
9284                                "Can't add task for another application: target uid="
9285                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9286                    }
9287                }
9288
9289                // Use the full screen as the context for the task thumbnail
9290                final Point displaySize = new Point();
9291                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9292                r.task.stack.getDisplaySize(displaySize);
9293                thumbnailInfo.taskWidth = displaySize.x;
9294                thumbnailInfo.taskHeight = displaySize.y;
9295                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9296
9297                TaskRecord task = new TaskRecord(this,
9298                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9299                        ainfo, intent, description, thumbnailInfo);
9300
9301                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9302                if (trimIdx >= 0) {
9303                    // If this would have caused a trim, then we'll abort because that
9304                    // means it would be added at the end of the list but then just removed.
9305                    return INVALID_TASK_ID;
9306                }
9307
9308                final int N = mRecentTasks.size();
9309                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9310                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9311                    tr.removedFromRecents();
9312                }
9313
9314                task.inRecents = true;
9315                mRecentTasks.add(task);
9316                r.task.stack.addTask(task, false, "addAppTask");
9317
9318                task.setLastThumbnailLocked(thumbnail);
9319                task.freeLastThumbnail();
9320
9321                return task.taskId;
9322            }
9323        } finally {
9324            Binder.restoreCallingIdentity(callingIdent);
9325        }
9326    }
9327
9328    @Override
9329    public Point getAppTaskThumbnailSize() {
9330        synchronized (this) {
9331            return new Point(mThumbnailWidth,  mThumbnailHeight);
9332        }
9333    }
9334
9335    @Override
9336    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9337        synchronized (this) {
9338            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9339            if (r != null) {
9340                r.setTaskDescription(td);
9341                r.task.updateTaskDescription();
9342            }
9343        }
9344    }
9345
9346    @Override
9347    public void setTaskResizeable(int taskId, int resizeableMode) {
9348        synchronized (this) {
9349            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351            if (task == null) {
9352                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9353                return;
9354            }
9355            if (task.mResizeMode != resizeableMode) {
9356                task.mResizeMode = resizeableMode;
9357                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9358                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9359                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9360            }
9361        }
9362    }
9363
9364    @Override
9365    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9367        long ident = Binder.clearCallingIdentity();
9368        try {
9369            synchronized (this) {
9370                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9371                if (task == null) {
9372                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9373                    return;
9374                }
9375                int stackId = task.stack.mStackId;
9376                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9377                // in crop windows resize mode or if the task size is affected by the docked stack
9378                // changing size. No need to update configuration.
9379                if (bounds != null && task.inCropWindowsResizeMode()
9380                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9381                    mWindowManager.scrollTask(task.taskId, bounds);
9382                    return;
9383                }
9384
9385                // Place the task in the right stack if it isn't there already based on
9386                // the requested bounds.
9387                // The stack transition logic is:
9388                // - a null bounds on a freeform task moves that task to fullscreen
9389                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9390                //   that task to freeform
9391                // - otherwise the task is not moved
9392                if (!StackId.isTaskResizeAllowed(stackId)) {
9393                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9394                }
9395                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9396                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9397                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9398                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9399                }
9400                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9401                if (stackId != task.stack.mStackId) {
9402                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9403                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9404                    preserveWindow = false;
9405                }
9406
9407                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9408                        false /* deferResume */);
9409            }
9410        } finally {
9411            Binder.restoreCallingIdentity(ident);
9412        }
9413    }
9414
9415    @Override
9416    public Rect getTaskBounds(int taskId) {
9417        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9418        long ident = Binder.clearCallingIdentity();
9419        Rect rect = new Rect();
9420        try {
9421            synchronized (this) {
9422                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9423                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9424                if (task == null) {
9425                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9426                    return rect;
9427                }
9428                if (task.stack != null) {
9429                    // Return the bounds from window manager since it will be adjusted for various
9430                    // things like the presense of a docked stack for tasks that aren't resizeable.
9431                    mWindowManager.getTaskBounds(task.taskId, rect);
9432                } else {
9433                    // Task isn't in window manager yet since it isn't associated with a stack.
9434                    // Return the persist value from activity manager
9435                    if (task.mBounds != null) {
9436                        rect.set(task.mBounds);
9437                    } else if (task.mLastNonFullscreenBounds != null) {
9438                        rect.set(task.mLastNonFullscreenBounds);
9439                    }
9440                }
9441            }
9442        } finally {
9443            Binder.restoreCallingIdentity(ident);
9444        }
9445        return rect;
9446    }
9447
9448    @Override
9449    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9450        if (userId != UserHandle.getCallingUserId()) {
9451            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9452                    "getTaskDescriptionIcon");
9453        }
9454        final File passedIconFile = new File(filePath);
9455        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9456                passedIconFile.getName());
9457        if (!legitIconFile.getPath().equals(filePath)
9458                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9459            throw new IllegalArgumentException("Bad file path: " + filePath
9460                    + " passed for userId " + userId);
9461        }
9462        return mRecentTasks.getTaskDescriptionIcon(filePath);
9463    }
9464
9465    @Override
9466    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9467            throws RemoteException {
9468        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9469                opts.getCustomInPlaceResId() == 0) {
9470            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9471                    "with valid animation");
9472        }
9473        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9474        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9475                opts.getCustomInPlaceResId());
9476        mWindowManager.executeAppTransition();
9477    }
9478
9479    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9480            boolean removeFromRecents) {
9481        if (removeFromRecents) {
9482            mRecentTasks.remove(tr);
9483            tr.removedFromRecents();
9484        }
9485        ComponentName component = tr.getBaseIntent().getComponent();
9486        if (component == null) {
9487            Slog.w(TAG, "No component for base intent of task: " + tr);
9488            return;
9489        }
9490
9491        // Find any running services associated with this app and stop if needed.
9492        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9493
9494        if (!killProcess) {
9495            return;
9496        }
9497
9498        // Determine if the process(es) for this task should be killed.
9499        final String pkg = component.getPackageName();
9500        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9501        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9502        for (int i = 0; i < pmap.size(); i++) {
9503
9504            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9505            for (int j = 0; j < uids.size(); j++) {
9506                ProcessRecord proc = uids.valueAt(j);
9507                if (proc.userId != tr.userId) {
9508                    // Don't kill process for a different user.
9509                    continue;
9510                }
9511                if (proc == mHomeProcess) {
9512                    // Don't kill the home process along with tasks from the same package.
9513                    continue;
9514                }
9515                if (!proc.pkgList.containsKey(pkg)) {
9516                    // Don't kill process that is not associated with this task.
9517                    continue;
9518                }
9519
9520                for (int k = 0; k < proc.activities.size(); k++) {
9521                    TaskRecord otherTask = proc.activities.get(k).task;
9522                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9523                        // Don't kill process(es) that has an activity in a different task that is
9524                        // also in recents.
9525                        return;
9526                    }
9527                }
9528
9529                if (proc.foregroundServices) {
9530                    // Don't kill process(es) with foreground service.
9531                    return;
9532                }
9533
9534                // Add process to kill list.
9535                procsToKill.add(proc);
9536            }
9537        }
9538
9539        // Kill the running processes.
9540        for (int i = 0; i < procsToKill.size(); i++) {
9541            ProcessRecord pr = procsToKill.get(i);
9542            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9543                    && pr.curReceiver == null) {
9544                pr.kill("remove task", true);
9545            } else {
9546                // We delay killing processes that are not in the background or running a receiver.
9547                pr.waitingToKill = "remove task";
9548            }
9549        }
9550    }
9551
9552    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9553        // Remove all tasks with activities in the specified package from the list of recent tasks
9554        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9555            TaskRecord tr = mRecentTasks.get(i);
9556            if (tr.userId != userId) continue;
9557
9558            ComponentName cn = tr.intent.getComponent();
9559            if (cn != null && cn.getPackageName().equals(packageName)) {
9560                // If the package name matches, remove the task.
9561                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9562            }
9563        }
9564    }
9565
9566    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9567            int userId) {
9568
9569        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9570            TaskRecord tr = mRecentTasks.get(i);
9571            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9572                continue;
9573            }
9574
9575            ComponentName cn = tr.intent.getComponent();
9576            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9577                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9578            if (sameComponent) {
9579                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9580            }
9581        }
9582    }
9583
9584    /**
9585     * Removes the task with the specified task id.
9586     *
9587     * @param taskId Identifier of the task to be removed.
9588     * @param killProcess Kill any process associated with the task if possible.
9589     * @param removeFromRecents Whether to also remove the task from recents.
9590     * @return Returns true if the given task was found and removed.
9591     */
9592    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9593            boolean removeFromRecents) {
9594        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9595                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9596        if (tr != null) {
9597            tr.removeTaskActivitiesLocked();
9598            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9599            if (tr.isPersistable) {
9600                notifyTaskPersisterLocked(null, true);
9601            }
9602            return true;
9603        }
9604        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9605        return false;
9606    }
9607
9608    @Override
9609    public void removeStack(int stackId) {
9610        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9611        if (stackId == HOME_STACK_ID) {
9612            throw new IllegalArgumentException("Removing home stack is not allowed.");
9613        }
9614
9615        synchronized (this) {
9616            final long ident = Binder.clearCallingIdentity();
9617            try {
9618                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9619                if (stack == null) {
9620                    return;
9621                }
9622                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9623                for (int i = tasks.size() - 1; i >= 0; i--) {
9624                    removeTaskByIdLocked(
9625                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9626                }
9627            } finally {
9628                Binder.restoreCallingIdentity(ident);
9629            }
9630        }
9631    }
9632
9633    @Override
9634    public boolean removeTask(int taskId) {
9635        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9636        synchronized (this) {
9637            final long ident = Binder.clearCallingIdentity();
9638            try {
9639                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9640            } finally {
9641                Binder.restoreCallingIdentity(ident);
9642            }
9643        }
9644    }
9645
9646    /**
9647     * TODO: Add mController hook
9648     */
9649    @Override
9650    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9651        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9652
9653        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9654        synchronized(this) {
9655            moveTaskToFrontLocked(taskId, flags, bOptions);
9656        }
9657    }
9658
9659    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9660        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9661
9662        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9663                Binder.getCallingUid(), -1, -1, "Task to front")) {
9664            ActivityOptions.abort(options);
9665            return;
9666        }
9667        final long origId = Binder.clearCallingIdentity();
9668        try {
9669            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9670            if (task == null) {
9671                Slog.d(TAG, "Could not find task for id: "+ taskId);
9672                return;
9673            }
9674            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9675                mStackSupervisor.showLockTaskToast();
9676                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9677                return;
9678            }
9679            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9680            if (prev != null && prev.isRecentsActivity()) {
9681                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9682            }
9683            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9684                    false /* forceNonResizable */);
9685        } finally {
9686            Binder.restoreCallingIdentity(origId);
9687        }
9688        ActivityOptions.abort(options);
9689    }
9690
9691    /**
9692     * Moves an activity, and all of the other activities within the same task, to the bottom
9693     * of the history stack.  The activity's order within the task is unchanged.
9694     *
9695     * @param token A reference to the activity we wish to move
9696     * @param nonRoot If false then this only works if the activity is the root
9697     *                of a task; if true it will work for any activity in a task.
9698     * @return Returns true if the move completed, false if not.
9699     */
9700    @Override
9701    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9702        enforceNotIsolatedCaller("moveActivityTaskToBack");
9703        synchronized(this) {
9704            final long origId = Binder.clearCallingIdentity();
9705            try {
9706                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9707                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9708                if (task != null) {
9709                    if (mStackSupervisor.isLockedTask(task)) {
9710                        mStackSupervisor.showLockTaskToast();
9711                        return false;
9712                    }
9713                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9714                }
9715            } finally {
9716                Binder.restoreCallingIdentity(origId);
9717            }
9718        }
9719        return false;
9720    }
9721
9722    @Override
9723    public void moveTaskBackwards(int task) {
9724        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9725                "moveTaskBackwards()");
9726
9727        synchronized(this) {
9728            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9729                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9730                return;
9731            }
9732            final long origId = Binder.clearCallingIdentity();
9733            moveTaskBackwardsLocked(task);
9734            Binder.restoreCallingIdentity(origId);
9735        }
9736    }
9737
9738    private final void moveTaskBackwardsLocked(int task) {
9739        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9740    }
9741
9742    @Override
9743    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9744            IActivityContainerCallback callback) throws RemoteException {
9745        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9746        synchronized (this) {
9747            if (parentActivityToken == null) {
9748                throw new IllegalArgumentException("parent token must not be null");
9749            }
9750            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9751            if (r == null) {
9752                return null;
9753            }
9754            if (callback == null) {
9755                throw new IllegalArgumentException("callback must not be null");
9756            }
9757            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9758        }
9759    }
9760
9761    @Override
9762    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9764        synchronized (this) {
9765            mStackSupervisor.deleteActivityContainer(container);
9766        }
9767    }
9768
9769    @Override
9770    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9771        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9772        synchronized (this) {
9773            final int stackId = mStackSupervisor.getNextStackId();
9774            final ActivityStack stack =
9775                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9776            if (stack == null) {
9777                return null;
9778            }
9779            return stack.mActivityContainer;
9780        }
9781    }
9782
9783    @Override
9784    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9785        synchronized (this) {
9786            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9787            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9788                return stack.mActivityContainer.getDisplayId();
9789            }
9790            return Display.DEFAULT_DISPLAY;
9791        }
9792    }
9793
9794    @Override
9795    public int getActivityStackId(IBinder token) throws RemoteException {
9796        synchronized (this) {
9797            ActivityStack stack = ActivityRecord.getStackLocked(token);
9798            if (stack == null) {
9799                return INVALID_STACK_ID;
9800            }
9801            return stack.mStackId;
9802        }
9803    }
9804
9805    @Override
9806    public void exitFreeformMode(IBinder token) throws RemoteException {
9807        synchronized (this) {
9808            long ident = Binder.clearCallingIdentity();
9809            try {
9810                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9811                if (r == null) {
9812                    throw new IllegalArgumentException(
9813                            "exitFreeformMode: No activity record matching token=" + token);
9814                }
9815                final ActivityStack stack = r.getStackLocked(token);
9816                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9817                    throw new IllegalStateException(
9818                            "exitFreeformMode: You can only go fullscreen from freeform.");
9819                }
9820                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9821                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9822                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9823            } finally {
9824                Binder.restoreCallingIdentity(ident);
9825            }
9826        }
9827    }
9828
9829    @Override
9830    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9831        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9832        if (stackId == HOME_STACK_ID) {
9833            throw new IllegalArgumentException(
9834                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9835        }
9836        synchronized (this) {
9837            long ident = Binder.clearCallingIdentity();
9838            try {
9839                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9840                        + " to stackId=" + stackId + " toTop=" + toTop);
9841                if (stackId == DOCKED_STACK_ID) {
9842                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9843                            null /* initialBounds */);
9844                }
9845                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9846                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9847                if (result && stackId == DOCKED_STACK_ID) {
9848                    // If task moved to docked stack - show recents if needed.
9849                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9850                            "moveTaskToDockedStack");
9851                }
9852            } finally {
9853                Binder.restoreCallingIdentity(ident);
9854            }
9855        }
9856    }
9857
9858    @Override
9859    public void swapDockedAndFullscreenStack() throws RemoteException {
9860        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9861        synchronized (this) {
9862            long ident = Binder.clearCallingIdentity();
9863            try {
9864                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9865                        FULLSCREEN_WORKSPACE_STACK_ID);
9866                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9867                        : null;
9868                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9869                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9870                        : null;
9871                if (topTask == null || tasks == null || tasks.size() == 0) {
9872                    Slog.w(TAG,
9873                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9874                    return;
9875                }
9876
9877                // TODO: App transition
9878                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9879
9880                // Defer the resume so resume/pausing while moving stacks is dangerous.
9881                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9882                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9883                        ANIMATE, true /* deferResume */);
9884                final int size = tasks.size();
9885                for (int i = 0; i < size; i++) {
9886                    final int id = tasks.get(i).taskId;
9887                    if (id == topTask.taskId) {
9888                        continue;
9889                    }
9890                    mStackSupervisor.moveTaskToStackLocked(id,
9891                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9892                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9893                }
9894
9895                // Because we deferred the resume, to avoid conflicts with stack switches while
9896                // resuming, we need to do it after all the tasks are moved.
9897                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9898                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9899
9900                mWindowManager.executeAppTransition();
9901            } finally {
9902                Binder.restoreCallingIdentity(ident);
9903            }
9904        }
9905    }
9906
9907    /**
9908     * Moves the input task to the docked stack.
9909     *
9910     * @param taskId Id of task to move.
9911     * @param createMode The mode the docked stack should be created in if it doesn't exist
9912     *                   already. See
9913     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9914     *                   and
9915     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9916     * @param toTop If the task and stack should be moved to the top.
9917     * @param animate Whether we should play an animation for the moving the task
9918     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9919     *                      docked stack. Pass {@code null} to use default bounds.
9920     */
9921    @Override
9922    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9923            Rect initialBounds, boolean moveHomeStackFront) {
9924        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9925        synchronized (this) {
9926            long ident = Binder.clearCallingIdentity();
9927            try {
9928                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9929                        + " to createMode=" + createMode + " toTop=" + toTop);
9930                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9931                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9932                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9933                        animate, DEFER_RESUME);
9934                if (moved) {
9935                    if (moveHomeStackFront) {
9936                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9937                    }
9938                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9939                }
9940                return moved;
9941            } finally {
9942                Binder.restoreCallingIdentity(ident);
9943            }
9944        }
9945    }
9946
9947    /**
9948     * Moves the top activity in the input stackId to the pinned stack.
9949     *
9950     * @param stackId Id of stack to move the top activity to pinned stack.
9951     * @param bounds Bounds to use for pinned stack.
9952     *
9953     * @return True if the top activity of the input stack was successfully moved to the pinned
9954     *          stack.
9955     */
9956    @Override
9957    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9958        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9959        synchronized (this) {
9960            if (!mSupportsPictureInPicture) {
9961                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9962                        + "Device doesn't support picture-in-pciture mode");
9963            }
9964
9965            long ident = Binder.clearCallingIdentity();
9966            try {
9967                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9968            } finally {
9969                Binder.restoreCallingIdentity(ident);
9970            }
9971        }
9972    }
9973
9974    @Override
9975    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9976            boolean preserveWindows, boolean animate, int animationDuration) {
9977        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9978        long ident = Binder.clearCallingIdentity();
9979        try {
9980            synchronized (this) {
9981                if (animate) {
9982                    if (stackId == PINNED_STACK_ID) {
9983                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9984                    } else {
9985                        throw new IllegalArgumentException("Stack: " + stackId
9986                                + " doesn't support animated resize.");
9987                    }
9988                } else {
9989                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9990                            null /* tempTaskInsetBounds */, preserveWindows,
9991                            allowResizeInDockedMode, !DEFER_RESUME);
9992                }
9993            }
9994        } finally {
9995            Binder.restoreCallingIdentity(ident);
9996        }
9997    }
9998
9999    @Override
10000    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10001            Rect tempDockedTaskInsetBounds,
10002            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10003        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10004                "resizeDockedStack()");
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            synchronized (this) {
10008                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10009                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10010                        PRESERVE_WINDOWS);
10011            }
10012        } finally {
10013            Binder.restoreCallingIdentity(ident);
10014        }
10015    }
10016
10017    @Override
10018    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10019        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10020                "resizePinnedStack()");
10021        final long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public void positionTaskInStack(int taskId, int stackId, int position) {
10033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10034        if (stackId == HOME_STACK_ID) {
10035            throw new IllegalArgumentException(
10036                    "positionTaskInStack: Attempt to change the position of task "
10037                    + taskId + " in/to home stack");
10038        }
10039        synchronized (this) {
10040            long ident = Binder.clearCallingIdentity();
10041            try {
10042                if (DEBUG_STACK) Slog.d(TAG_STACK,
10043                        "positionTaskInStack: positioning task=" + taskId
10044                        + " in stackId=" + stackId + " at position=" + position);
10045                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10046            } finally {
10047                Binder.restoreCallingIdentity(ident);
10048            }
10049        }
10050    }
10051
10052    @Override
10053    public List<StackInfo> getAllStackInfos() {
10054        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10055        long ident = Binder.clearCallingIdentity();
10056        try {
10057            synchronized (this) {
10058                return mStackSupervisor.getAllStackInfosLocked();
10059            }
10060        } finally {
10061            Binder.restoreCallingIdentity(ident);
10062        }
10063    }
10064
10065    @Override
10066    public StackInfo getStackInfo(int stackId) {
10067        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10068        long ident = Binder.clearCallingIdentity();
10069        try {
10070            synchronized (this) {
10071                return mStackSupervisor.getStackInfoLocked(stackId);
10072            }
10073        } finally {
10074            Binder.restoreCallingIdentity(ident);
10075        }
10076    }
10077
10078    @Override
10079    public boolean isInHomeStack(int taskId) {
10080        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10081        long ident = Binder.clearCallingIdentity();
10082        try {
10083            synchronized (this) {
10084                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10085                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10086                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10087            }
10088        } finally {
10089            Binder.restoreCallingIdentity(ident);
10090        }
10091    }
10092
10093    @Override
10094    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10095        synchronized(this) {
10096            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10097        }
10098    }
10099
10100    @Override
10101    public void updateDeviceOwner(String packageName) {
10102        final int callingUid = Binder.getCallingUid();
10103        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10104            throw new SecurityException("updateDeviceOwner called from non-system process");
10105        }
10106        synchronized (this) {
10107            mDeviceOwnerName = packageName;
10108        }
10109    }
10110
10111    @Override
10112    public void updateLockTaskPackages(int userId, String[] packages) {
10113        final int callingUid = Binder.getCallingUid();
10114        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10115            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10116                    "updateLockTaskPackages()");
10117        }
10118        synchronized (this) {
10119            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10120                    Arrays.toString(packages));
10121            mLockTaskPackages.put(userId, packages);
10122            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10123        }
10124    }
10125
10126
10127    void startLockTaskModeLocked(TaskRecord task) {
10128        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10129        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10130            return;
10131        }
10132
10133        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10134        // is initiated by system after the pinning request was shown and locked mode is initiated
10135        // by an authorized app directly
10136        final int callingUid = Binder.getCallingUid();
10137        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10138        long ident = Binder.clearCallingIdentity();
10139        try {
10140            if (!isSystemInitiated) {
10141                task.mLockTaskUid = callingUid;
10142                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10143                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10144                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10145                    StatusBarManagerInternal statusBarManager =
10146                            LocalServices.getService(StatusBarManagerInternal.class);
10147                    if (statusBarManager != null) {
10148                        statusBarManager.showScreenPinningRequest(task.taskId);
10149                    }
10150                    return;
10151                }
10152
10153                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10154                if (stack == null || task != stack.topTask()) {
10155                    throw new IllegalArgumentException("Invalid task, not in foreground");
10156                }
10157            }
10158            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10159                    "Locking fully");
10160            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10161                    ActivityManager.LOCK_TASK_MODE_PINNED :
10162                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10163                    "startLockTask", true);
10164        } finally {
10165            Binder.restoreCallingIdentity(ident);
10166        }
10167    }
10168
10169    @Override
10170    public void startLockTaskMode(int taskId) {
10171        synchronized (this) {
10172            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10173            if (task != null) {
10174                startLockTaskModeLocked(task);
10175            }
10176        }
10177    }
10178
10179    @Override
10180    public void startLockTaskMode(IBinder token) {
10181        synchronized (this) {
10182            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10183            if (r == null) {
10184                return;
10185            }
10186            final TaskRecord task = r.task;
10187            if (task != null) {
10188                startLockTaskModeLocked(task);
10189            }
10190        }
10191    }
10192
10193    @Override
10194    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10195        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10196        // This makes inner call to look as if it was initiated by system.
10197        long ident = Binder.clearCallingIdentity();
10198        try {
10199            synchronized (this) {
10200                startLockTaskMode(taskId);
10201            }
10202        } finally {
10203            Binder.restoreCallingIdentity(ident);
10204        }
10205    }
10206
10207    @Override
10208    public void stopLockTaskMode() {
10209        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10210        if (lockTask == null) {
10211            // Our work here is done.
10212            return;
10213        }
10214
10215        final int callingUid = Binder.getCallingUid();
10216        final int lockTaskUid = lockTask.mLockTaskUid;
10217        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10218        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10219            // Done.
10220            return;
10221        } else {
10222            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10223            // It is possible lockTaskMode was started by the system process because
10224            // android:lockTaskMode is set to a locking value in the application manifest
10225            // instead of the app calling startLockTaskMode. In this case
10226            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10227            // {@link TaskRecord.effectiveUid} instead. Also caller with
10228            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10229            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10230                    && callingUid != lockTaskUid
10231                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10232                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10233                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10234            }
10235        }
10236        long ident = Binder.clearCallingIdentity();
10237        try {
10238            Log.d(TAG, "stopLockTaskMode");
10239            // Stop lock task
10240            synchronized (this) {
10241                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10242                        "stopLockTask", true);
10243            }
10244            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10245            if (tm != null) {
10246                tm.showInCallScreen(false);
10247            }
10248        } finally {
10249            Binder.restoreCallingIdentity(ident);
10250        }
10251    }
10252
10253    /**
10254     * This API should be called by SystemUI only when user perform certain action to dismiss
10255     * lock task mode. We should only dismiss pinned lock task mode in this case.
10256     */
10257    @Override
10258    public void stopSystemLockTaskMode() throws RemoteException {
10259        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10260            stopLockTaskMode();
10261        } else {
10262            mStackSupervisor.showLockTaskToast();
10263        }
10264    }
10265
10266    @Override
10267    public boolean isInLockTaskMode() {
10268        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10269    }
10270
10271    @Override
10272    public int getLockTaskModeState() {
10273        synchronized (this) {
10274            return mStackSupervisor.getLockTaskModeState();
10275        }
10276    }
10277
10278    @Override
10279    public void showLockTaskEscapeMessage(IBinder token) {
10280        synchronized (this) {
10281            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10282            if (r == null) {
10283                return;
10284            }
10285            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10286        }
10287    }
10288
10289    // =========================================================
10290    // CONTENT PROVIDERS
10291    // =========================================================
10292
10293    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10294        List<ProviderInfo> providers = null;
10295        try {
10296            providers = AppGlobals.getPackageManager()
10297                    .queryContentProviders(app.processName, app.uid,
10298                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10299                                    | MATCH_DEBUG_TRIAGED_MISSING)
10300                    .getList();
10301        } catch (RemoteException ex) {
10302        }
10303        if (DEBUG_MU) Slog.v(TAG_MU,
10304                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10305        int userId = app.userId;
10306        if (providers != null) {
10307            int N = providers.size();
10308            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10309            for (int i=0; i<N; i++) {
10310                // TODO: keep logic in sync with installEncryptionUnawareProviders
10311                ProviderInfo cpi =
10312                    (ProviderInfo)providers.get(i);
10313                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10314                        cpi.name, cpi.flags);
10315                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10316                    // This is a singleton provider, but a user besides the
10317                    // default user is asking to initialize a process it runs
10318                    // in...  well, no, it doesn't actually run in this process,
10319                    // it runs in the process of the default user.  Get rid of it.
10320                    providers.remove(i);
10321                    N--;
10322                    i--;
10323                    continue;
10324                }
10325
10326                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10327                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10328                if (cpr == null) {
10329                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10330                    mProviderMap.putProviderByClass(comp, cpr);
10331                }
10332                if (DEBUG_MU) Slog.v(TAG_MU,
10333                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10334                app.pubProviders.put(cpi.name, cpr);
10335                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10336                    // Don't add this if it is a platform component that is marked
10337                    // to run in multiple processes, because this is actually
10338                    // part of the framework so doesn't make sense to track as a
10339                    // separate apk in the process.
10340                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10341                            mProcessStats);
10342                }
10343                notifyPackageUse(cpi.applicationInfo.packageName,
10344                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10345            }
10346        }
10347        return providers;
10348    }
10349
10350    /**
10351     * Check if {@link ProcessRecord} has a possible chance at accessing the
10352     * given {@link ProviderInfo}. Final permission checking is always done
10353     * in {@link ContentProvider}.
10354     */
10355    private final String checkContentProviderPermissionLocked(
10356            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10357        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10358        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10359        boolean checkedGrants = false;
10360        if (checkUser) {
10361            // Looking for cross-user grants before enforcing the typical cross-users permissions
10362            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10363            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10364                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10365                    return null;
10366                }
10367                checkedGrants = true;
10368            }
10369            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10370                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10371            if (userId != tmpTargetUserId) {
10372                // When we actually went to determine the final targer user ID, this ended
10373                // up different than our initial check for the authority.  This is because
10374                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10375                // SELF.  So we need to re-check the grants again.
10376                checkedGrants = false;
10377            }
10378        }
10379        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10380                cpi.applicationInfo.uid, cpi.exported)
10381                == PackageManager.PERMISSION_GRANTED) {
10382            return null;
10383        }
10384        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10385                cpi.applicationInfo.uid, cpi.exported)
10386                == PackageManager.PERMISSION_GRANTED) {
10387            return null;
10388        }
10389
10390        PathPermission[] pps = cpi.pathPermissions;
10391        if (pps != null) {
10392            int i = pps.length;
10393            while (i > 0) {
10394                i--;
10395                PathPermission pp = pps[i];
10396                String pprperm = pp.getReadPermission();
10397                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10398                        cpi.applicationInfo.uid, cpi.exported)
10399                        == PackageManager.PERMISSION_GRANTED) {
10400                    return null;
10401                }
10402                String ppwperm = pp.getWritePermission();
10403                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10404                        cpi.applicationInfo.uid, cpi.exported)
10405                        == PackageManager.PERMISSION_GRANTED) {
10406                    return null;
10407                }
10408            }
10409        }
10410        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10411            return null;
10412        }
10413
10414        String msg;
10415        if (!cpi.exported) {
10416            msg = "Permission Denial: opening provider " + cpi.name
10417                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10418                    + ", uid=" + callingUid + ") that is not exported from uid "
10419                    + cpi.applicationInfo.uid;
10420        } else {
10421            msg = "Permission Denial: opening provider " + cpi.name
10422                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10423                    + ", uid=" + callingUid + ") requires "
10424                    + cpi.readPermission + " or " + cpi.writePermission;
10425        }
10426        Slog.w(TAG, msg);
10427        return msg;
10428    }
10429
10430    /**
10431     * Returns if the ContentProvider has granted a uri to callingUid
10432     */
10433    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10434        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10435        if (perms != null) {
10436            for (int i=perms.size()-1; i>=0; i--) {
10437                GrantUri grantUri = perms.keyAt(i);
10438                if (grantUri.sourceUserId == userId || !checkUser) {
10439                    if (matchesProvider(grantUri.uri, cpi)) {
10440                        return true;
10441                    }
10442                }
10443            }
10444        }
10445        return false;
10446    }
10447
10448    /**
10449     * Returns true if the uri authority is one of the authorities specified in the provider.
10450     */
10451    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10452        String uriAuth = uri.getAuthority();
10453        String cpiAuth = cpi.authority;
10454        if (cpiAuth.indexOf(';') == -1) {
10455            return cpiAuth.equals(uriAuth);
10456        }
10457        String[] cpiAuths = cpiAuth.split(";");
10458        int length = cpiAuths.length;
10459        for (int i = 0; i < length; i++) {
10460            if (cpiAuths[i].equals(uriAuth)) return true;
10461        }
10462        return false;
10463    }
10464
10465    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10466            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10467        if (r != null) {
10468            for (int i=0; i<r.conProviders.size(); i++) {
10469                ContentProviderConnection conn = r.conProviders.get(i);
10470                if (conn.provider == cpr) {
10471                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10472                            "Adding provider requested by "
10473                            + r.processName + " from process "
10474                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10475                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10476                    if (stable) {
10477                        conn.stableCount++;
10478                        conn.numStableIncs++;
10479                    } else {
10480                        conn.unstableCount++;
10481                        conn.numUnstableIncs++;
10482                    }
10483                    return conn;
10484                }
10485            }
10486            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10487            if (stable) {
10488                conn.stableCount = 1;
10489                conn.numStableIncs = 1;
10490            } else {
10491                conn.unstableCount = 1;
10492                conn.numUnstableIncs = 1;
10493            }
10494            cpr.connections.add(conn);
10495            r.conProviders.add(conn);
10496            startAssociationLocked(r.uid, r.processName, r.curProcState,
10497                    cpr.uid, cpr.name, cpr.info.processName);
10498            return conn;
10499        }
10500        cpr.addExternalProcessHandleLocked(externalProcessToken);
10501        return null;
10502    }
10503
10504    boolean decProviderCountLocked(ContentProviderConnection conn,
10505            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10506        if (conn != null) {
10507            cpr = conn.provider;
10508            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10509                    "Removing provider requested by "
10510                    + conn.client.processName + " from process "
10511                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10512                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10513            if (stable) {
10514                conn.stableCount--;
10515            } else {
10516                conn.unstableCount--;
10517            }
10518            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10519                cpr.connections.remove(conn);
10520                conn.client.conProviders.remove(conn);
10521                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10522                    // The client is more important than last activity -- note the time this
10523                    // is happening, so we keep the old provider process around a bit as last
10524                    // activity to avoid thrashing it.
10525                    if (cpr.proc != null) {
10526                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10527                    }
10528                }
10529                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10530                return true;
10531            }
10532            return false;
10533        }
10534        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10535        return false;
10536    }
10537
10538    private void checkTime(long startTime, String where) {
10539        long now = SystemClock.uptimeMillis();
10540        if ((now-startTime) > 50) {
10541            // If we are taking more than 50ms, log about it.
10542            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10543        }
10544    }
10545
10546    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10547            PROC_SPACE_TERM,
10548            PROC_SPACE_TERM|PROC_PARENS,
10549            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10550    };
10551
10552    private final long[] mProcessStateStatsLongs = new long[1];
10553
10554    boolean isProcessAliveLocked(ProcessRecord proc) {
10555        if (proc.procStatFile == null) {
10556            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10557        }
10558        mProcessStateStatsLongs[0] = 0;
10559        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10560                mProcessStateStatsLongs, null)) {
10561            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10562            return false;
10563        }
10564        final long state = mProcessStateStatsLongs[0];
10565        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10566                + (char)state);
10567        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10568    }
10569
10570    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10571            String name, IBinder token, boolean stable, int userId) {
10572        ContentProviderRecord cpr;
10573        ContentProviderConnection conn = null;
10574        ProviderInfo cpi = null;
10575
10576        synchronized(this) {
10577            long startTime = SystemClock.uptimeMillis();
10578
10579            ProcessRecord r = null;
10580            if (caller != null) {
10581                r = getRecordForAppLocked(caller);
10582                if (r == null) {
10583                    throw new SecurityException(
10584                            "Unable to find app for caller " + caller
10585                          + " (pid=" + Binder.getCallingPid()
10586                          + ") when getting content provider " + name);
10587                }
10588            }
10589
10590            boolean checkCrossUser = true;
10591
10592            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10593
10594            // First check if this content provider has been published...
10595            cpr = mProviderMap.getProviderByName(name, userId);
10596            // If that didn't work, check if it exists for user 0 and then
10597            // verify that it's a singleton provider before using it.
10598            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10599                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10600                if (cpr != null) {
10601                    cpi = cpr.info;
10602                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10603                            cpi.name, cpi.flags)
10604                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10605                        userId = UserHandle.USER_SYSTEM;
10606                        checkCrossUser = false;
10607                    } else {
10608                        cpr = null;
10609                        cpi = null;
10610                    }
10611                }
10612            }
10613
10614            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10615            if (providerRunning) {
10616                cpi = cpr.info;
10617                String msg;
10618                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10619                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10620                        != null) {
10621                    throw new SecurityException(msg);
10622                }
10623                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10624
10625                if (r != null && cpr.canRunHere(r)) {
10626                    // This provider has been published or is in the process
10627                    // of being published...  but it is also allowed to run
10628                    // in the caller's process, so don't make a connection
10629                    // and just let the caller instantiate its own instance.
10630                    ContentProviderHolder holder = cpr.newHolder(null);
10631                    // don't give caller the provider object, it needs
10632                    // to make its own.
10633                    holder.provider = null;
10634                    return holder;
10635                }
10636
10637                final long origId = Binder.clearCallingIdentity();
10638
10639                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10640
10641                // In this case the provider instance already exists, so we can
10642                // return it right away.
10643                conn = incProviderCountLocked(r, cpr, token, stable);
10644                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10645                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10646                        // If this is a perceptible app accessing the provider,
10647                        // make sure to count it as being accessed and thus
10648                        // back up on the LRU list.  This is good because
10649                        // content providers are often expensive to start.
10650                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10651                        updateLruProcessLocked(cpr.proc, false, null);
10652                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10653                    }
10654                }
10655
10656                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10657                final int verifiedAdj = cpr.proc.verifiedAdj;
10658                boolean success = updateOomAdjLocked(cpr.proc);
10659                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10660                // if the process has been successfully adjusted.  So to reduce races with
10661                // it, we will check whether the process still exists.  Note that this doesn't
10662                // completely get rid of races with LMK killing the process, but should make
10663                // them much smaller.
10664                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10665                    success = false;
10666                }
10667                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10668                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10669                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10670                // NOTE: there is still a race here where a signal could be
10671                // pending on the process even though we managed to update its
10672                // adj level.  Not sure what to do about this, but at least
10673                // the race is now smaller.
10674                if (!success) {
10675                    // Uh oh...  it looks like the provider's process
10676                    // has been killed on us.  We need to wait for a new
10677                    // process to be started, and make sure its death
10678                    // doesn't kill our process.
10679                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10680                            + " is crashing; detaching " + r);
10681                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10682                    checkTime(startTime, "getContentProviderImpl: before appDied");
10683                    appDiedLocked(cpr.proc);
10684                    checkTime(startTime, "getContentProviderImpl: after appDied");
10685                    if (!lastRef) {
10686                        // This wasn't the last ref our process had on
10687                        // the provider...  we have now been killed, bail.
10688                        return null;
10689                    }
10690                    providerRunning = false;
10691                    conn = null;
10692                } else {
10693                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10694                }
10695
10696                Binder.restoreCallingIdentity(origId);
10697            }
10698
10699            if (!providerRunning) {
10700                try {
10701                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10702                    cpi = AppGlobals.getPackageManager().
10703                        resolveContentProvider(name,
10704                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10705                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10706                } catch (RemoteException ex) {
10707                }
10708                if (cpi == null) {
10709                    return null;
10710                }
10711                // If the provider is a singleton AND
10712                // (it's a call within the same user || the provider is a
10713                // privileged app)
10714                // Then allow connecting to the singleton provider
10715                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10716                        cpi.name, cpi.flags)
10717                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10718                if (singleton) {
10719                    userId = UserHandle.USER_SYSTEM;
10720                }
10721                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10722                checkTime(startTime, "getContentProviderImpl: got app info for user");
10723
10724                String msg;
10725                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10726                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10727                        != null) {
10728                    throw new SecurityException(msg);
10729                }
10730                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10731
10732                if (!mProcessesReady
10733                        && !cpi.processName.equals("system")) {
10734                    // If this content provider does not run in the system
10735                    // process, and the system is not yet ready to run other
10736                    // processes, then fail fast instead of hanging.
10737                    throw new IllegalArgumentException(
10738                            "Attempt to launch content provider before system ready");
10739                }
10740
10741                // Make sure that the user who owns this provider is running.  If not,
10742                // we don't want to allow it to run.
10743                if (!mUserController.isUserRunningLocked(userId, 0)) {
10744                    Slog.w(TAG, "Unable to launch app "
10745                            + cpi.applicationInfo.packageName + "/"
10746                            + cpi.applicationInfo.uid + " for provider "
10747                            + name + ": user " + userId + " is stopped");
10748                    return null;
10749                }
10750
10751                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10752                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10753                cpr = mProviderMap.getProviderByClass(comp, userId);
10754                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10755                final boolean firstClass = cpr == null;
10756                if (firstClass) {
10757                    final long ident = Binder.clearCallingIdentity();
10758
10759                    // If permissions need a review before any of the app components can run,
10760                    // we return no provider and launch a review activity if the calling app
10761                    // is in the foreground.
10762                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10763                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10764                            return null;
10765                        }
10766                    }
10767
10768                    try {
10769                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10770                        ApplicationInfo ai =
10771                            AppGlobals.getPackageManager().
10772                                getApplicationInfo(
10773                                        cpi.applicationInfo.packageName,
10774                                        STOCK_PM_FLAGS, userId);
10775                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10776                        if (ai == null) {
10777                            Slog.w(TAG, "No package info for content provider "
10778                                    + cpi.name);
10779                            return null;
10780                        }
10781                        ai = getAppInfoForUser(ai, userId);
10782                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10783                    } catch (RemoteException ex) {
10784                        // pm is in same process, this will never happen.
10785                    } finally {
10786                        Binder.restoreCallingIdentity(ident);
10787                    }
10788                }
10789
10790                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10791
10792                if (r != null && cpr.canRunHere(r)) {
10793                    // If this is a multiprocess provider, then just return its
10794                    // info and allow the caller to instantiate it.  Only do
10795                    // this if the provider is the same user as the caller's
10796                    // process, or can run as root (so can be in any process).
10797                    return cpr.newHolder(null);
10798                }
10799
10800                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10801                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10802                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10803
10804                // This is single process, and our app is now connecting to it.
10805                // See if we are already in the process of launching this
10806                // provider.
10807                final int N = mLaunchingProviders.size();
10808                int i;
10809                for (i = 0; i < N; i++) {
10810                    if (mLaunchingProviders.get(i) == cpr) {
10811                        break;
10812                    }
10813                }
10814
10815                // If the provider is not already being launched, then get it
10816                // started.
10817                if (i >= N) {
10818                    final long origId = Binder.clearCallingIdentity();
10819
10820                    try {
10821                        // Content provider is now in use, its package can't be stopped.
10822                        try {
10823                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10824                            AppGlobals.getPackageManager().setPackageStoppedState(
10825                                    cpr.appInfo.packageName, false, userId);
10826                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10827                        } catch (RemoteException e) {
10828                        } catch (IllegalArgumentException e) {
10829                            Slog.w(TAG, "Failed trying to unstop package "
10830                                    + cpr.appInfo.packageName + ": " + e);
10831                        }
10832
10833                        // Use existing process if already started
10834                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10835                        ProcessRecord proc = getProcessRecordLocked(
10836                                cpi.processName, cpr.appInfo.uid, false);
10837                        if (proc != null && proc.thread != null && !proc.killed) {
10838                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10839                                    "Installing in existing process " + proc);
10840                            if (!proc.pubProviders.containsKey(cpi.name)) {
10841                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10842                                proc.pubProviders.put(cpi.name, cpr);
10843                                try {
10844                                    proc.thread.scheduleInstallProvider(cpi);
10845                                } catch (RemoteException e) {
10846                                }
10847                            }
10848                        } else {
10849                            checkTime(startTime, "getContentProviderImpl: before start process");
10850                            proc = startProcessLocked(cpi.processName,
10851                                    cpr.appInfo, false, 0, "content provider",
10852                                    new ComponentName(cpi.applicationInfo.packageName,
10853                                            cpi.name), false, false, false);
10854                            checkTime(startTime, "getContentProviderImpl: after start process");
10855                            if (proc == null) {
10856                                Slog.w(TAG, "Unable to launch app "
10857                                        + cpi.applicationInfo.packageName + "/"
10858                                        + cpi.applicationInfo.uid + " for provider "
10859                                        + name + ": process is bad");
10860                                return null;
10861                            }
10862                        }
10863                        cpr.launchingApp = proc;
10864                        mLaunchingProviders.add(cpr);
10865                    } finally {
10866                        Binder.restoreCallingIdentity(origId);
10867                    }
10868                }
10869
10870                checkTime(startTime, "getContentProviderImpl: updating data structures");
10871
10872                // Make sure the provider is published (the same provider class
10873                // may be published under multiple names).
10874                if (firstClass) {
10875                    mProviderMap.putProviderByClass(comp, cpr);
10876                }
10877
10878                mProviderMap.putProviderByName(name, cpr);
10879                conn = incProviderCountLocked(r, cpr, token, stable);
10880                if (conn != null) {
10881                    conn.waiting = true;
10882                }
10883            }
10884            checkTime(startTime, "getContentProviderImpl: done!");
10885        }
10886
10887        // Wait for the provider to be published...
10888        synchronized (cpr) {
10889            while (cpr.provider == null) {
10890                if (cpr.launchingApp == null) {
10891                    Slog.w(TAG, "Unable to launch app "
10892                            + cpi.applicationInfo.packageName + "/"
10893                            + cpi.applicationInfo.uid + " for provider "
10894                            + name + ": launching app became null");
10895                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10896                            UserHandle.getUserId(cpi.applicationInfo.uid),
10897                            cpi.applicationInfo.packageName,
10898                            cpi.applicationInfo.uid, name);
10899                    return null;
10900                }
10901                try {
10902                    if (DEBUG_MU) Slog.v(TAG_MU,
10903                            "Waiting to start provider " + cpr
10904                            + " launchingApp=" + cpr.launchingApp);
10905                    if (conn != null) {
10906                        conn.waiting = true;
10907                    }
10908                    cpr.wait();
10909                } catch (InterruptedException ex) {
10910                } finally {
10911                    if (conn != null) {
10912                        conn.waiting = false;
10913                    }
10914                }
10915            }
10916        }
10917        return cpr != null ? cpr.newHolder(conn) : null;
10918    }
10919
10920    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10921            ProcessRecord r, final int userId) {
10922        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10923                cpi.packageName, userId)) {
10924
10925            final boolean callerForeground = r == null || r.setSchedGroup
10926                    != ProcessList.SCHED_GROUP_BACKGROUND;
10927
10928            // Show a permission review UI only for starting from a foreground app
10929            if (!callerForeground) {
10930                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10931                        + cpi.packageName + " requires a permissions review");
10932                return false;
10933            }
10934
10935            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10936            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10937                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10938            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10939
10940            if (DEBUG_PERMISSIONS_REVIEW) {
10941                Slog.i(TAG, "u" + userId + " Launching permission review "
10942                        + "for package " + cpi.packageName);
10943            }
10944
10945            final UserHandle userHandle = new UserHandle(userId);
10946            mHandler.post(new Runnable() {
10947                @Override
10948                public void run() {
10949                    mContext.startActivityAsUser(intent, userHandle);
10950                }
10951            });
10952
10953            return false;
10954        }
10955
10956        return true;
10957    }
10958
10959    PackageManagerInternal getPackageManagerInternalLocked() {
10960        if (mPackageManagerInt == null) {
10961            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10962        }
10963        return mPackageManagerInt;
10964    }
10965
10966    @Override
10967    public final ContentProviderHolder getContentProvider(
10968            IApplicationThread caller, String name, int userId, boolean stable) {
10969        enforceNotIsolatedCaller("getContentProvider");
10970        if (caller == null) {
10971            String msg = "null IApplicationThread when getting content provider "
10972                    + name;
10973            Slog.w(TAG, msg);
10974            throw new SecurityException(msg);
10975        }
10976        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10977        // with cross-user grant.
10978        return getContentProviderImpl(caller, name, null, stable, userId);
10979    }
10980
10981    public ContentProviderHolder getContentProviderExternal(
10982            String name, int userId, IBinder token) {
10983        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10984            "Do not have permission in call getContentProviderExternal()");
10985        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10986                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10987        return getContentProviderExternalUnchecked(name, token, userId);
10988    }
10989
10990    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10991            IBinder token, int userId) {
10992        return getContentProviderImpl(null, name, token, true, userId);
10993    }
10994
10995    /**
10996     * Drop a content provider from a ProcessRecord's bookkeeping
10997     */
10998    public void removeContentProvider(IBinder connection, boolean stable) {
10999        enforceNotIsolatedCaller("removeContentProvider");
11000        long ident = Binder.clearCallingIdentity();
11001        try {
11002            synchronized (this) {
11003                ContentProviderConnection conn;
11004                try {
11005                    conn = (ContentProviderConnection)connection;
11006                } catch (ClassCastException e) {
11007                    String msg ="removeContentProvider: " + connection
11008                            + " not a ContentProviderConnection";
11009                    Slog.w(TAG, msg);
11010                    throw new IllegalArgumentException(msg);
11011                }
11012                if (conn == null) {
11013                    throw new NullPointerException("connection is null");
11014                }
11015                if (decProviderCountLocked(conn, null, null, stable)) {
11016                    updateOomAdjLocked();
11017                }
11018            }
11019        } finally {
11020            Binder.restoreCallingIdentity(ident);
11021        }
11022    }
11023
11024    public void removeContentProviderExternal(String name, IBinder token) {
11025        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11026            "Do not have permission in call removeContentProviderExternal()");
11027        int userId = UserHandle.getCallingUserId();
11028        long ident = Binder.clearCallingIdentity();
11029        try {
11030            removeContentProviderExternalUnchecked(name, token, userId);
11031        } finally {
11032            Binder.restoreCallingIdentity(ident);
11033        }
11034    }
11035
11036    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11037        synchronized (this) {
11038            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11039            if(cpr == null) {
11040                //remove from mProvidersByClass
11041                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11042                return;
11043            }
11044
11045            //update content provider record entry info
11046            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11047            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11048            if (localCpr.hasExternalProcessHandles()) {
11049                if (localCpr.removeExternalProcessHandleLocked(token)) {
11050                    updateOomAdjLocked();
11051                } else {
11052                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11053                            + " with no external reference for token: "
11054                            + token + ".");
11055                }
11056            } else {
11057                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11058                        + " with no external references.");
11059            }
11060        }
11061    }
11062
11063    public final void publishContentProviders(IApplicationThread caller,
11064            List<ContentProviderHolder> providers) {
11065        if (providers == null) {
11066            return;
11067        }
11068
11069        enforceNotIsolatedCaller("publishContentProviders");
11070        synchronized (this) {
11071            final ProcessRecord r = getRecordForAppLocked(caller);
11072            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11073            if (r == null) {
11074                throw new SecurityException(
11075                        "Unable to find app for caller " + caller
11076                      + " (pid=" + Binder.getCallingPid()
11077                      + ") when publishing content providers");
11078            }
11079
11080            final long origId = Binder.clearCallingIdentity();
11081
11082            final int N = providers.size();
11083            for (int i = 0; i < N; i++) {
11084                ContentProviderHolder src = providers.get(i);
11085                if (src == null || src.info == null || src.provider == null) {
11086                    continue;
11087                }
11088                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11089                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11090                if (dst != null) {
11091                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11092                    mProviderMap.putProviderByClass(comp, dst);
11093                    String names[] = dst.info.authority.split(";");
11094                    for (int j = 0; j < names.length; j++) {
11095                        mProviderMap.putProviderByName(names[j], dst);
11096                    }
11097
11098                    int launchingCount = mLaunchingProviders.size();
11099                    int j;
11100                    boolean wasInLaunchingProviders = false;
11101                    for (j = 0; j < launchingCount; j++) {
11102                        if (mLaunchingProviders.get(j) == dst) {
11103                            mLaunchingProviders.remove(j);
11104                            wasInLaunchingProviders = true;
11105                            j--;
11106                            launchingCount--;
11107                        }
11108                    }
11109                    if (wasInLaunchingProviders) {
11110                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11111                    }
11112                    synchronized (dst) {
11113                        dst.provider = src.provider;
11114                        dst.proc = r;
11115                        dst.notifyAll();
11116                    }
11117                    updateOomAdjLocked(r);
11118                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11119                            src.info.authority);
11120                }
11121            }
11122
11123            Binder.restoreCallingIdentity(origId);
11124        }
11125    }
11126
11127    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11128        ContentProviderConnection conn;
11129        try {
11130            conn = (ContentProviderConnection)connection;
11131        } catch (ClassCastException e) {
11132            String msg ="refContentProvider: " + connection
11133                    + " not a ContentProviderConnection";
11134            Slog.w(TAG, msg);
11135            throw new IllegalArgumentException(msg);
11136        }
11137        if (conn == null) {
11138            throw new NullPointerException("connection is null");
11139        }
11140
11141        synchronized (this) {
11142            if (stable > 0) {
11143                conn.numStableIncs += stable;
11144            }
11145            stable = conn.stableCount + stable;
11146            if (stable < 0) {
11147                throw new IllegalStateException("stableCount < 0: " + stable);
11148            }
11149
11150            if (unstable > 0) {
11151                conn.numUnstableIncs += unstable;
11152            }
11153            unstable = conn.unstableCount + unstable;
11154            if (unstable < 0) {
11155                throw new IllegalStateException("unstableCount < 0: " + unstable);
11156            }
11157
11158            if ((stable+unstable) <= 0) {
11159                throw new IllegalStateException("ref counts can't go to zero here: stable="
11160                        + stable + " unstable=" + unstable);
11161            }
11162            conn.stableCount = stable;
11163            conn.unstableCount = unstable;
11164            return !conn.dead;
11165        }
11166    }
11167
11168    public void unstableProviderDied(IBinder connection) {
11169        ContentProviderConnection conn;
11170        try {
11171            conn = (ContentProviderConnection)connection;
11172        } catch (ClassCastException e) {
11173            String msg ="refContentProvider: " + connection
11174                    + " not a ContentProviderConnection";
11175            Slog.w(TAG, msg);
11176            throw new IllegalArgumentException(msg);
11177        }
11178        if (conn == null) {
11179            throw new NullPointerException("connection is null");
11180        }
11181
11182        // Safely retrieve the content provider associated with the connection.
11183        IContentProvider provider;
11184        synchronized (this) {
11185            provider = conn.provider.provider;
11186        }
11187
11188        if (provider == null) {
11189            // Um, yeah, we're way ahead of you.
11190            return;
11191        }
11192
11193        // Make sure the caller is being honest with us.
11194        if (provider.asBinder().pingBinder()) {
11195            // Er, no, still looks good to us.
11196            synchronized (this) {
11197                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11198                        + " says " + conn + " died, but we don't agree");
11199                return;
11200            }
11201        }
11202
11203        // Well look at that!  It's dead!
11204        synchronized (this) {
11205            if (conn.provider.provider != provider) {
11206                // But something changed...  good enough.
11207                return;
11208            }
11209
11210            ProcessRecord proc = conn.provider.proc;
11211            if (proc == null || proc.thread == null) {
11212                // Seems like the process is already cleaned up.
11213                return;
11214            }
11215
11216            // As far as we're concerned, this is just like receiving a
11217            // death notification...  just a bit prematurely.
11218            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11219                    + ") early provider death");
11220            final long ident = Binder.clearCallingIdentity();
11221            try {
11222                appDiedLocked(proc);
11223            } finally {
11224                Binder.restoreCallingIdentity(ident);
11225            }
11226        }
11227    }
11228
11229    @Override
11230    public void appNotRespondingViaProvider(IBinder connection) {
11231        enforceCallingPermission(
11232                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11233
11234        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11235        if (conn == null) {
11236            Slog.w(TAG, "ContentProviderConnection is null");
11237            return;
11238        }
11239
11240        final ProcessRecord host = conn.provider.proc;
11241        if (host == null) {
11242            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11243            return;
11244        }
11245
11246        mHandler.post(new Runnable() {
11247            @Override
11248            public void run() {
11249                mAppErrors.appNotResponding(host, null, null, false,
11250                        "ContentProvider not responding");
11251            }
11252        });
11253    }
11254
11255    public final void installSystemProviders() {
11256        List<ProviderInfo> providers;
11257        synchronized (this) {
11258            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11259            providers = generateApplicationProvidersLocked(app);
11260            if (providers != null) {
11261                for (int i=providers.size()-1; i>=0; i--) {
11262                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11263                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11264                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11265                                + ": not system .apk");
11266                        providers.remove(i);
11267                    }
11268                }
11269            }
11270        }
11271        if (providers != null) {
11272            mSystemThread.installSystemProviders(providers);
11273        }
11274
11275        mCoreSettingsObserver = new CoreSettingsObserver(this);
11276        mFontScaleSettingObserver = new FontScaleSettingObserver();
11277
11278        //mUsageStatsService.monitorPackages();
11279    }
11280
11281    private void startPersistentApps(int matchFlags) {
11282        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11283
11284        synchronized (this) {
11285            try {
11286                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11287                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11288                for (ApplicationInfo app : apps) {
11289                    if (!"android".equals(app.packageName)) {
11290                        addAppLocked(app, false, null /* ABI override */);
11291                    }
11292                }
11293            } catch (RemoteException ex) {
11294            }
11295        }
11296    }
11297
11298    /**
11299     * When a user is unlocked, we need to install encryption-unaware providers
11300     * belonging to any running apps.
11301     */
11302    private void installEncryptionUnawareProviders(int userId) {
11303        // We're only interested in providers that are encryption unaware, and
11304        // we don't care about uninstalled apps, since there's no way they're
11305        // running at this point.
11306        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11307
11308        synchronized (this) {
11309            final int NP = mProcessNames.getMap().size();
11310            for (int ip = 0; ip < NP; ip++) {
11311                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11312                final int NA = apps.size();
11313                for (int ia = 0; ia < NA; ia++) {
11314                    final ProcessRecord app = apps.valueAt(ia);
11315                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11316
11317                    final int NG = app.pkgList.size();
11318                    for (int ig = 0; ig < NG; ig++) {
11319                        try {
11320                            final String pkgName = app.pkgList.keyAt(ig);
11321                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11322                                    .getPackageInfo(pkgName, matchFlags, userId);
11323                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11324                                for (ProviderInfo pi : pkgInfo.providers) {
11325                                    // TODO: keep in sync with generateApplicationProvidersLocked
11326                                    final boolean processMatch = Objects.equals(pi.processName,
11327                                            app.processName) || pi.multiprocess;
11328                                    final boolean userMatch = isSingleton(pi.processName,
11329                                            pi.applicationInfo, pi.name, pi.flags)
11330                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11331                                    if (processMatch && userMatch) {
11332                                        Log.v(TAG, "Installing " + pi);
11333                                        app.thread.scheduleInstallProvider(pi);
11334                                    } else {
11335                                        Log.v(TAG, "Skipping " + pi);
11336                                    }
11337                                }
11338                            }
11339                        } catch (RemoteException ignored) {
11340                        }
11341                    }
11342                }
11343            }
11344        }
11345    }
11346
11347    /**
11348     * Allows apps to retrieve the MIME type of a URI.
11349     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11350     * users, then it does not need permission to access the ContentProvider.
11351     * Either, it needs cross-user uri grants.
11352     *
11353     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11354     *
11355     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11356     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11357     */
11358    public String getProviderMimeType(Uri uri, int userId) {
11359        enforceNotIsolatedCaller("getProviderMimeType");
11360        final String name = uri.getAuthority();
11361        int callingUid = Binder.getCallingUid();
11362        int callingPid = Binder.getCallingPid();
11363        long ident = 0;
11364        boolean clearedIdentity = false;
11365        synchronized (this) {
11366            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11367        }
11368        if (canClearIdentity(callingPid, callingUid, userId)) {
11369            clearedIdentity = true;
11370            ident = Binder.clearCallingIdentity();
11371        }
11372        ContentProviderHolder holder = null;
11373        try {
11374            holder = getContentProviderExternalUnchecked(name, null, userId);
11375            if (holder != null) {
11376                return holder.provider.getType(uri);
11377            }
11378        } catch (RemoteException e) {
11379            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11380            return null;
11381        } catch (Exception e) {
11382            Log.w(TAG, "Exception while determining type of " + uri, e);
11383            return null;
11384        } finally {
11385            // We need to clear the identity to call removeContentProviderExternalUnchecked
11386            if (!clearedIdentity) {
11387                ident = Binder.clearCallingIdentity();
11388            }
11389            try {
11390                if (holder != null) {
11391                    removeContentProviderExternalUnchecked(name, null, userId);
11392                }
11393            } finally {
11394                Binder.restoreCallingIdentity(ident);
11395            }
11396        }
11397
11398        return null;
11399    }
11400
11401    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11402        if (UserHandle.getUserId(callingUid) == userId) {
11403            return true;
11404        }
11405        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11406                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11407                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11408                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11409                return true;
11410        }
11411        return false;
11412    }
11413
11414    // =========================================================
11415    // GLOBAL MANAGEMENT
11416    // =========================================================
11417
11418    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11419            boolean isolated, int isolatedUid) {
11420        String proc = customProcess != null ? customProcess : info.processName;
11421        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11422        final int userId = UserHandle.getUserId(info.uid);
11423        int uid = info.uid;
11424        if (isolated) {
11425            if (isolatedUid == 0) {
11426                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11427                while (true) {
11428                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11429                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11430                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11431                    }
11432                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11433                    mNextIsolatedProcessUid++;
11434                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11435                        // No process for this uid, use it.
11436                        break;
11437                    }
11438                    stepsLeft--;
11439                    if (stepsLeft <= 0) {
11440                        return null;
11441                    }
11442                }
11443            } else {
11444                // Special case for startIsolatedProcess (internal only), where
11445                // the uid of the isolated process is specified by the caller.
11446                uid = isolatedUid;
11447            }
11448        }
11449        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11450        if (!mBooted && !mBooting
11451                && userId == UserHandle.USER_SYSTEM
11452                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11453            r.persistent = true;
11454        }
11455        addProcessNameLocked(r);
11456        return r;
11457    }
11458
11459    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11460            String abiOverride) {
11461        ProcessRecord app;
11462        if (!isolated) {
11463            app = getProcessRecordLocked(info.processName, info.uid, true);
11464        } else {
11465            app = null;
11466        }
11467
11468        if (app == null) {
11469            app = newProcessRecordLocked(info, null, isolated, 0);
11470            updateLruProcessLocked(app, false, null);
11471            updateOomAdjLocked();
11472        }
11473
11474        // This package really, really can not be stopped.
11475        try {
11476            AppGlobals.getPackageManager().setPackageStoppedState(
11477                    info.packageName, false, UserHandle.getUserId(app.uid));
11478        } catch (RemoteException e) {
11479        } catch (IllegalArgumentException e) {
11480            Slog.w(TAG, "Failed trying to unstop package "
11481                    + info.packageName + ": " + e);
11482        }
11483
11484        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11485            app.persistent = true;
11486            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11487        }
11488        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11489            mPersistentStartingProcesses.add(app);
11490            startProcessLocked(app, "added application", app.processName, abiOverride,
11491                    null /* entryPoint */, null /* entryPointArgs */);
11492        }
11493
11494        return app;
11495    }
11496
11497    public void unhandledBack() {
11498        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11499                "unhandledBack()");
11500
11501        synchronized(this) {
11502            final long origId = Binder.clearCallingIdentity();
11503            try {
11504                getFocusedStack().unhandledBackLocked();
11505            } finally {
11506                Binder.restoreCallingIdentity(origId);
11507            }
11508        }
11509    }
11510
11511    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11512        enforceNotIsolatedCaller("openContentUri");
11513        final int userId = UserHandle.getCallingUserId();
11514        String name = uri.getAuthority();
11515        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11516        ParcelFileDescriptor pfd = null;
11517        if (cph != null) {
11518            // We record the binder invoker's uid in thread-local storage before
11519            // going to the content provider to open the file.  Later, in the code
11520            // that handles all permissions checks, we look for this uid and use
11521            // that rather than the Activity Manager's own uid.  The effect is that
11522            // we do the check against the caller's permissions even though it looks
11523            // to the content provider like the Activity Manager itself is making
11524            // the request.
11525            Binder token = new Binder();
11526            sCallerIdentity.set(new Identity(
11527                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11528            try {
11529                pfd = cph.provider.openFile(null, uri, "r", null, token);
11530            } catch (FileNotFoundException e) {
11531                // do nothing; pfd will be returned null
11532            } finally {
11533                // Ensure that whatever happens, we clean up the identity state
11534                sCallerIdentity.remove();
11535                // Ensure we're done with the provider.
11536                removeContentProviderExternalUnchecked(name, null, userId);
11537            }
11538        } else {
11539            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11540        }
11541        return pfd;
11542    }
11543
11544    // Actually is sleeping or shutting down or whatever else in the future
11545    // is an inactive state.
11546    boolean isSleepingOrShuttingDownLocked() {
11547        return isSleepingLocked() || mShuttingDown;
11548    }
11549
11550    boolean isShuttingDownLocked() {
11551        return mShuttingDown;
11552    }
11553
11554    boolean isSleepingLocked() {
11555        return mSleeping;
11556    }
11557
11558    void onWakefulnessChanged(int wakefulness) {
11559        synchronized(this) {
11560            mWakefulness = wakefulness;
11561            updateSleepIfNeededLocked();
11562        }
11563    }
11564
11565    void finishRunningVoiceLocked() {
11566        if (mRunningVoice != null) {
11567            mRunningVoice = null;
11568            mVoiceWakeLock.release();
11569            updateSleepIfNeededLocked();
11570        }
11571    }
11572
11573    void startTimeTrackingFocusedActivityLocked() {
11574        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11575            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11576        }
11577    }
11578
11579    void updateSleepIfNeededLocked() {
11580        if (mSleeping && !shouldSleepLocked()) {
11581            mSleeping = false;
11582            startTimeTrackingFocusedActivityLocked();
11583            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11584            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11585            updateOomAdjLocked();
11586        } else if (!mSleeping && shouldSleepLocked()) {
11587            mSleeping = true;
11588            if (mCurAppTimeTracker != null) {
11589                mCurAppTimeTracker.stop();
11590            }
11591            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11592            mStackSupervisor.goingToSleepLocked();
11593            updateOomAdjLocked();
11594
11595            // Initialize the wake times of all processes.
11596            checkExcessivePowerUsageLocked(false);
11597            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11598            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11599            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11600        }
11601    }
11602
11603    private boolean shouldSleepLocked() {
11604        // Resume applications while running a voice interactor.
11605        if (mRunningVoice != null) {
11606            return false;
11607        }
11608
11609        // TODO: Transform the lock screen state into a sleep token instead.
11610        switch (mWakefulness) {
11611            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11612            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11613            case PowerManagerInternal.WAKEFULNESS_DOZING:
11614                // Pause applications whenever the lock screen is shown or any sleep
11615                // tokens have been acquired.
11616                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11617            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11618            default:
11619                // If we're asleep then pause applications unconditionally.
11620                return true;
11621        }
11622    }
11623
11624    /** Pokes the task persister. */
11625    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11626        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11627    }
11628
11629    /** Notifies all listeners when the task stack has changed. */
11630    void notifyTaskStackChangedLocked() {
11631        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11632        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11633        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11634        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11635    }
11636
11637    /** Notifies all listeners when an Activity is pinned. */
11638    void notifyActivityPinnedLocked() {
11639        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11640        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11641    }
11642
11643    /**
11644     * Notifies all listeners when an attempt was made to start an an activity that is already
11645     * running in the pinned stack and the activity was not actually started, but the task is
11646     * either brought to the front or a new Intent is delivered to it.
11647     */
11648    void notifyPinnedActivityRestartAttemptLocked() {
11649        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11650        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11651    }
11652
11653    /** Notifies all listeners when the pinned stack animation ends. */
11654    @Override
11655    public void notifyPinnedStackAnimationEnded() {
11656        synchronized (this) {
11657            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11658            mHandler.obtainMessage(
11659                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11660        }
11661    }
11662
11663    @Override
11664    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11665        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11666    }
11667
11668    @Override
11669    public boolean shutdown(int timeout) {
11670        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11671                != PackageManager.PERMISSION_GRANTED) {
11672            throw new SecurityException("Requires permission "
11673                    + android.Manifest.permission.SHUTDOWN);
11674        }
11675
11676        boolean timedout = false;
11677
11678        synchronized(this) {
11679            mShuttingDown = true;
11680            updateEventDispatchingLocked();
11681            timedout = mStackSupervisor.shutdownLocked(timeout);
11682        }
11683
11684        mAppOpsService.shutdown();
11685        if (mUsageStatsService != null) {
11686            mUsageStatsService.prepareShutdown();
11687        }
11688        mBatteryStatsService.shutdown();
11689        synchronized (this) {
11690            mProcessStats.shutdownLocked();
11691            notifyTaskPersisterLocked(null, true);
11692        }
11693
11694        return timedout;
11695    }
11696
11697    public final void activitySlept(IBinder token) {
11698        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11699
11700        final long origId = Binder.clearCallingIdentity();
11701
11702        synchronized (this) {
11703            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11704            if (r != null) {
11705                mStackSupervisor.activitySleptLocked(r);
11706            }
11707        }
11708
11709        Binder.restoreCallingIdentity(origId);
11710    }
11711
11712    private String lockScreenShownToString() {
11713        switch (mLockScreenShown) {
11714            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11715            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11716            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11717            default: return "Unknown=" + mLockScreenShown;
11718        }
11719    }
11720
11721    void logLockScreen(String msg) {
11722        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11723                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11724                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11725                + " mSleeping=" + mSleeping);
11726    }
11727
11728    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11729        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11730        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11731        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11732            boolean wasRunningVoice = mRunningVoice != null;
11733            mRunningVoice = session;
11734            if (!wasRunningVoice) {
11735                mVoiceWakeLock.acquire();
11736                updateSleepIfNeededLocked();
11737            }
11738        }
11739    }
11740
11741    private void updateEventDispatchingLocked() {
11742        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11743    }
11744
11745    public void setLockScreenShown(boolean showing, boolean occluded) {
11746        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11747                != PackageManager.PERMISSION_GRANTED) {
11748            throw new SecurityException("Requires permission "
11749                    + android.Manifest.permission.DEVICE_POWER);
11750        }
11751
11752        synchronized(this) {
11753            long ident = Binder.clearCallingIdentity();
11754            try {
11755                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11756                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11757                if (showing && occluded) {
11758                    // The lock screen is currently showing, but is occluded by a window that can
11759                    // show on top of the lock screen. In this can we want to dismiss the docked
11760                    // stack since it will be complicated/risky to try to put the activity on top
11761                    // of the lock screen in the right fullscreen configuration.
11762                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11763                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11764                }
11765
11766                updateSleepIfNeededLocked();
11767            } finally {
11768                Binder.restoreCallingIdentity(ident);
11769            }
11770        }
11771    }
11772
11773    @Override
11774    public void notifyLockedProfile(@UserIdInt int userId) {
11775        try {
11776            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11777                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11778            }
11779        } catch (RemoteException ex) {
11780            throw new SecurityException("Fail to check is caller a privileged app", ex);
11781        }
11782
11783        synchronized (this) {
11784            if (mStackSupervisor.isUserLockedProfile(userId)) {
11785                final long ident = Binder.clearCallingIdentity();
11786                try {
11787                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11788                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11789                        // If there is no device lock, we will show the profile's credential page.
11790                        mActivityStarter.showConfirmDeviceCredential(userId);
11791                    } else {
11792                        // Showing launcher to avoid user entering credential twice.
11793                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11794                    }
11795                } finally {
11796                    Binder.restoreCallingIdentity(ident);
11797                }
11798            }
11799        }
11800    }
11801
11802    @Override
11803    public void startConfirmDeviceCredentialIntent(Intent intent) {
11804        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11805        synchronized (this) {
11806            final long ident = Binder.clearCallingIdentity();
11807            try {
11808                mActivityStarter.startConfirmCredentialIntent(intent);
11809            } finally {
11810                Binder.restoreCallingIdentity(ident);
11811            }
11812        }
11813    }
11814
11815    @Override
11816    public void stopAppSwitches() {
11817        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11818                != PackageManager.PERMISSION_GRANTED) {
11819            throw new SecurityException("viewquires permission "
11820                    + android.Manifest.permission.STOP_APP_SWITCHES);
11821        }
11822
11823        synchronized(this) {
11824            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11825                    + APP_SWITCH_DELAY_TIME;
11826            mDidAppSwitch = false;
11827            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11828            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11829            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11830        }
11831    }
11832
11833    public void resumeAppSwitches() {
11834        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11835                != PackageManager.PERMISSION_GRANTED) {
11836            throw new SecurityException("Requires permission "
11837                    + android.Manifest.permission.STOP_APP_SWITCHES);
11838        }
11839
11840        synchronized(this) {
11841            // Note that we don't execute any pending app switches... we will
11842            // let those wait until either the timeout, or the next start
11843            // activity request.
11844            mAppSwitchesAllowedTime = 0;
11845        }
11846    }
11847
11848    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11849            int callingPid, int callingUid, String name) {
11850        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11851            return true;
11852        }
11853
11854        int perm = checkComponentPermission(
11855                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11856                sourceUid, -1, true);
11857        if (perm == PackageManager.PERMISSION_GRANTED) {
11858            return true;
11859        }
11860
11861        // If the actual IPC caller is different from the logical source, then
11862        // also see if they are allowed to control app switches.
11863        if (callingUid != -1 && callingUid != sourceUid) {
11864            perm = checkComponentPermission(
11865                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11866                    callingUid, -1, true);
11867            if (perm == PackageManager.PERMISSION_GRANTED) {
11868                return true;
11869            }
11870        }
11871
11872        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11873        return false;
11874    }
11875
11876    public void setDebugApp(String packageName, boolean waitForDebugger,
11877            boolean persistent) {
11878        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11879                "setDebugApp()");
11880
11881        long ident = Binder.clearCallingIdentity();
11882        try {
11883            // Note that this is not really thread safe if there are multiple
11884            // callers into it at the same time, but that's not a situation we
11885            // care about.
11886            if (persistent) {
11887                final ContentResolver resolver = mContext.getContentResolver();
11888                Settings.Global.putString(
11889                    resolver, Settings.Global.DEBUG_APP,
11890                    packageName);
11891                Settings.Global.putInt(
11892                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11893                    waitForDebugger ? 1 : 0);
11894            }
11895
11896            synchronized (this) {
11897                if (!persistent) {
11898                    mOrigDebugApp = mDebugApp;
11899                    mOrigWaitForDebugger = mWaitForDebugger;
11900                }
11901                mDebugApp = packageName;
11902                mWaitForDebugger = waitForDebugger;
11903                mDebugTransient = !persistent;
11904                if (packageName != null) {
11905                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11906                            false, UserHandle.USER_ALL, "set debug app");
11907                }
11908            }
11909        } finally {
11910            Binder.restoreCallingIdentity(ident);
11911        }
11912    }
11913
11914    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11915        synchronized (this) {
11916            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11917            if (!isDebuggable) {
11918                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11919                    throw new SecurityException("Process not debuggable: " + app.packageName);
11920                }
11921            }
11922
11923            mTrackAllocationApp = processName;
11924        }
11925    }
11926
11927    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11928        synchronized (this) {
11929            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11930            if (!isDebuggable) {
11931                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11932                    throw new SecurityException("Process not debuggable: " + app.packageName);
11933                }
11934            }
11935            mProfileApp = processName;
11936            mProfileFile = profilerInfo.profileFile;
11937            if (mProfileFd != null) {
11938                try {
11939                    mProfileFd.close();
11940                } catch (IOException e) {
11941                }
11942                mProfileFd = null;
11943            }
11944            mProfileFd = profilerInfo.profileFd;
11945            mSamplingInterval = profilerInfo.samplingInterval;
11946            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11947            mProfileType = 0;
11948        }
11949    }
11950
11951    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11952        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11953        if (!isDebuggable) {
11954            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11955                throw new SecurityException("Process not debuggable: " + app.packageName);
11956            }
11957        }
11958        mNativeDebuggingApp = processName;
11959    }
11960
11961    @Override
11962    public void setAlwaysFinish(boolean enabled) {
11963        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11964                "setAlwaysFinish()");
11965
11966        long ident = Binder.clearCallingIdentity();
11967        try {
11968            Settings.Global.putInt(
11969                    mContext.getContentResolver(),
11970                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11971
11972            synchronized (this) {
11973                mAlwaysFinishActivities = enabled;
11974            }
11975        } finally {
11976            Binder.restoreCallingIdentity(ident);
11977        }
11978    }
11979
11980    @Override
11981    public void setLenientBackgroundCheck(boolean enabled) {
11982        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11983                "setLenientBackgroundCheck()");
11984
11985        long ident = Binder.clearCallingIdentity();
11986        try {
11987            Settings.Global.putInt(
11988                    mContext.getContentResolver(),
11989                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11990
11991            synchronized (this) {
11992                mLenientBackgroundCheck = enabled;
11993            }
11994        } finally {
11995            Binder.restoreCallingIdentity(ident);
11996        }
11997    }
11998
11999    @Override
12000    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12001        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12002                "setActivityController()");
12003        synchronized (this) {
12004            mController = controller;
12005            mControllerIsAMonkey = imAMonkey;
12006            Watchdog.getInstance().setActivityController(controller);
12007        }
12008    }
12009
12010    @Override
12011    public void setUserIsMonkey(boolean userIsMonkey) {
12012        synchronized (this) {
12013            synchronized (mPidsSelfLocked) {
12014                final int callingPid = Binder.getCallingPid();
12015                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12016                if (precessRecord == null) {
12017                    throw new SecurityException("Unknown process: " + callingPid);
12018                }
12019                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12020                    throw new SecurityException("Only an instrumentation process "
12021                            + "with a UiAutomation can call setUserIsMonkey");
12022                }
12023            }
12024            mUserIsMonkey = userIsMonkey;
12025        }
12026    }
12027
12028    @Override
12029    public boolean isUserAMonkey() {
12030        synchronized (this) {
12031            // If there is a controller also implies the user is a monkey.
12032            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12033        }
12034    }
12035
12036    public void requestBugReport(int bugreportType) {
12037        String service = null;
12038        switch (bugreportType) {
12039            case ActivityManager.BUGREPORT_OPTION_FULL:
12040                service = "bugreport";
12041                break;
12042            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12043                service = "bugreportplus";
12044                break;
12045            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12046                service = "bugreportremote";
12047                break;
12048        }
12049        if (service == null) {
12050            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12051                    + bugreportType);
12052        }
12053        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12054        SystemProperties.set("ctl.start", service);
12055    }
12056
12057    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12058        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12059    }
12060
12061    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12062        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12063            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12064        }
12065        return KEY_DISPATCHING_TIMEOUT;
12066    }
12067
12068    @Override
12069    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12070        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12071                != PackageManager.PERMISSION_GRANTED) {
12072            throw new SecurityException("Requires permission "
12073                    + android.Manifest.permission.FILTER_EVENTS);
12074        }
12075        ProcessRecord proc;
12076        long timeout;
12077        synchronized (this) {
12078            synchronized (mPidsSelfLocked) {
12079                proc = mPidsSelfLocked.get(pid);
12080            }
12081            timeout = getInputDispatchingTimeoutLocked(proc);
12082        }
12083
12084        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12085            return -1;
12086        }
12087
12088        return timeout;
12089    }
12090
12091    /**
12092     * Handle input dispatching timeouts.
12093     * Returns whether input dispatching should be aborted or not.
12094     */
12095    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12096            final ActivityRecord activity, final ActivityRecord parent,
12097            final boolean aboveSystem, String reason) {
12098        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12099                != PackageManager.PERMISSION_GRANTED) {
12100            throw new SecurityException("Requires permission "
12101                    + android.Manifest.permission.FILTER_EVENTS);
12102        }
12103
12104        final String annotation;
12105        if (reason == null) {
12106            annotation = "Input dispatching timed out";
12107        } else {
12108            annotation = "Input dispatching timed out (" + reason + ")";
12109        }
12110
12111        if (proc != null) {
12112            synchronized (this) {
12113                if (proc.debugging) {
12114                    return false;
12115                }
12116
12117                if (mDidDexOpt) {
12118                    // Give more time since we were dexopting.
12119                    mDidDexOpt = false;
12120                    return false;
12121                }
12122
12123                if (proc.instrumentationClass != null) {
12124                    Bundle info = new Bundle();
12125                    info.putString("shortMsg", "keyDispatchingTimedOut");
12126                    info.putString("longMsg", annotation);
12127                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12128                    return true;
12129                }
12130            }
12131            mHandler.post(new Runnable() {
12132                @Override
12133                public void run() {
12134                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12135                }
12136            });
12137        }
12138
12139        return true;
12140    }
12141
12142    @Override
12143    public Bundle getAssistContextExtras(int requestType) {
12144        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12145                null, null, true /* focused */, true /* newSessionId */,
12146                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12147        if (pae == null) {
12148            return null;
12149        }
12150        synchronized (pae) {
12151            while (!pae.haveResult) {
12152                try {
12153                    pae.wait();
12154                } catch (InterruptedException e) {
12155                }
12156            }
12157        }
12158        synchronized (this) {
12159            buildAssistBundleLocked(pae, pae.result);
12160            mPendingAssistExtras.remove(pae);
12161            mUiHandler.removeCallbacks(pae);
12162        }
12163        return pae.extras;
12164    }
12165
12166    @Override
12167    public boolean isAssistDataAllowedOnCurrentActivity() {
12168        int userId;
12169        synchronized (this) {
12170            userId = mUserController.getCurrentUserIdLocked();
12171            ActivityRecord activity = getFocusedStack().topActivity();
12172            if (activity == null) {
12173                return false;
12174            }
12175            userId = activity.userId;
12176        }
12177        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12178                Context.DEVICE_POLICY_SERVICE);
12179        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12180    }
12181
12182    @Override
12183    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12184        long ident = Binder.clearCallingIdentity();
12185        try {
12186            synchronized (this) {
12187                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12188                ActivityRecord top = getFocusedStack().topActivity();
12189                if (top != caller) {
12190                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12191                            + " is not current top " + top);
12192                    return false;
12193                }
12194                if (!top.nowVisible) {
12195                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12196                            + " is not visible");
12197                    return false;
12198                }
12199            }
12200            AssistUtils utils = new AssistUtils(mContext);
12201            return utils.showSessionForActiveService(args,
12202                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12203        } finally {
12204            Binder.restoreCallingIdentity(ident);
12205        }
12206    }
12207
12208    @Override
12209    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12210            Bundle receiverExtras,
12211            IBinder activityToken, boolean focused, boolean newSessionId) {
12212        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12213                activityToken, focused, newSessionId,
12214                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12215                != null;
12216    }
12217
12218    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12219            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12220            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12221        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12222                "enqueueAssistContext()");
12223        synchronized (this) {
12224            ActivityRecord activity = getFocusedStack().topActivity();
12225            if (activity == null) {
12226                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12227                return null;
12228            }
12229            if (activity.app == null || activity.app.thread == null) {
12230                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12231                return null;
12232            }
12233            if (focused) {
12234                if (activityToken != null) {
12235                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12236                    if (activity != caller) {
12237                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12238                                + " is not current top " + activity);
12239                        return null;
12240                    }
12241                }
12242            } else {
12243                activity = ActivityRecord.forTokenLocked(activityToken);
12244                if (activity == null) {
12245                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12246                            + " couldn't be found");
12247                    return null;
12248                }
12249            }
12250
12251            PendingAssistExtras pae;
12252            Bundle extras = new Bundle();
12253            if (args != null) {
12254                extras.putAll(args);
12255            }
12256            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12257            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12258            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12259                    userHandle);
12260            // Increment the sessionId if necessary
12261            if (newSessionId) {
12262                mViSessionId++;
12263            }
12264            try {
12265                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12266                        requestType, mViSessionId);
12267                mPendingAssistExtras.add(pae);
12268                mUiHandler.postDelayed(pae, timeout);
12269            } catch (RemoteException e) {
12270                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12271                return null;
12272            }
12273            return pae;
12274        }
12275    }
12276
12277    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12278        IResultReceiver receiver;
12279        synchronized (this) {
12280            mPendingAssistExtras.remove(pae);
12281            receiver = pae.receiver;
12282        }
12283        if (receiver != null) {
12284            // Caller wants result sent back to them.
12285            Bundle sendBundle = new Bundle();
12286            // At least return the receiver extras
12287            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12288                    pae.receiverExtras);
12289            try {
12290                pae.receiver.send(0, sendBundle);
12291            } catch (RemoteException e) {
12292            }
12293        }
12294    }
12295
12296    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12297        if (result != null) {
12298            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12299        }
12300        if (pae.hint != null) {
12301            pae.extras.putBoolean(pae.hint, true);
12302        }
12303    }
12304
12305    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12306            AssistContent content, Uri referrer) {
12307        PendingAssistExtras pae = (PendingAssistExtras)token;
12308        synchronized (pae) {
12309            pae.result = extras;
12310            pae.structure = structure;
12311            pae.content = content;
12312            if (referrer != null) {
12313                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12314            }
12315            pae.haveResult = true;
12316            pae.notifyAll();
12317            if (pae.intent == null && pae.receiver == null) {
12318                // Caller is just waiting for the result.
12319                return;
12320            }
12321        }
12322
12323        // We are now ready to launch the assist activity.
12324        IResultReceiver sendReceiver = null;
12325        Bundle sendBundle = null;
12326        synchronized (this) {
12327            buildAssistBundleLocked(pae, extras);
12328            boolean exists = mPendingAssistExtras.remove(pae);
12329            mUiHandler.removeCallbacks(pae);
12330            if (!exists) {
12331                // Timed out.
12332                return;
12333            }
12334            if ((sendReceiver=pae.receiver) != null) {
12335                // Caller wants result sent back to them.
12336                sendBundle = new Bundle();
12337                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12338                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12339                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12340                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12341                        pae.receiverExtras);
12342            }
12343        }
12344        if (sendReceiver != null) {
12345            try {
12346                sendReceiver.send(0, sendBundle);
12347            } catch (RemoteException e) {
12348            }
12349            return;
12350        }
12351
12352        long ident = Binder.clearCallingIdentity();
12353        try {
12354            pae.intent.replaceExtras(pae.extras);
12355            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12356                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12357                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12358            closeSystemDialogs("assist");
12359            try {
12360                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12361            } catch (ActivityNotFoundException e) {
12362                Slog.w(TAG, "No activity to handle assist action.", e);
12363            }
12364        } finally {
12365            Binder.restoreCallingIdentity(ident);
12366        }
12367    }
12368
12369    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12370            Bundle args) {
12371        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12372                true /* focused */, true /* newSessionId */,
12373                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12374    }
12375
12376    public void registerProcessObserver(IProcessObserver observer) {
12377        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12378                "registerProcessObserver()");
12379        synchronized (this) {
12380            mProcessObservers.register(observer);
12381        }
12382    }
12383
12384    @Override
12385    public void unregisterProcessObserver(IProcessObserver observer) {
12386        synchronized (this) {
12387            mProcessObservers.unregister(observer);
12388        }
12389    }
12390
12391    @Override
12392    public void registerUidObserver(IUidObserver observer, int which) {
12393        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12394                "registerUidObserver()");
12395        synchronized (this) {
12396            mUidObservers.register(observer, which);
12397        }
12398    }
12399
12400    @Override
12401    public void unregisterUidObserver(IUidObserver observer) {
12402        synchronized (this) {
12403            mUidObservers.unregister(observer);
12404        }
12405    }
12406
12407    @Override
12408    public boolean convertFromTranslucent(IBinder token) {
12409        final long origId = Binder.clearCallingIdentity();
12410        try {
12411            synchronized (this) {
12412                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12413                if (r == null) {
12414                    return false;
12415                }
12416                final boolean translucentChanged = r.changeWindowTranslucency(true);
12417                if (translucentChanged) {
12418                    r.task.stack.releaseBackgroundResources(r);
12419                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12420                }
12421                mWindowManager.setAppFullscreen(token, true);
12422                return translucentChanged;
12423            }
12424        } finally {
12425            Binder.restoreCallingIdentity(origId);
12426        }
12427    }
12428
12429    @Override
12430    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12431        final long origId = Binder.clearCallingIdentity();
12432        try {
12433            synchronized (this) {
12434                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12435                if (r == null) {
12436                    return false;
12437                }
12438                int index = r.task.mActivities.lastIndexOf(r);
12439                if (index > 0) {
12440                    ActivityRecord under = r.task.mActivities.get(index - 1);
12441                    under.returningOptions = options;
12442                }
12443                final boolean translucentChanged = r.changeWindowTranslucency(false);
12444                if (translucentChanged) {
12445                    r.task.stack.convertActivityToTranslucent(r);
12446                }
12447                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12448                mWindowManager.setAppFullscreen(token, false);
12449                return translucentChanged;
12450            }
12451        } finally {
12452            Binder.restoreCallingIdentity(origId);
12453        }
12454    }
12455
12456    @Override
12457    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12458        final long origId = Binder.clearCallingIdentity();
12459        try {
12460            synchronized (this) {
12461                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12462                if (r != null) {
12463                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12464                }
12465            }
12466            return false;
12467        } finally {
12468            Binder.restoreCallingIdentity(origId);
12469        }
12470    }
12471
12472    @Override
12473    public boolean isBackgroundVisibleBehind(IBinder token) {
12474        final long origId = Binder.clearCallingIdentity();
12475        try {
12476            synchronized (this) {
12477                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12478                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12479                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12480                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12481                return visible;
12482            }
12483        } finally {
12484            Binder.restoreCallingIdentity(origId);
12485        }
12486    }
12487
12488    @Override
12489    public ActivityOptions getActivityOptions(IBinder token) {
12490        final long origId = Binder.clearCallingIdentity();
12491        try {
12492            synchronized (this) {
12493                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12494                if (r != null) {
12495                    final ActivityOptions activityOptions = r.pendingOptions;
12496                    r.pendingOptions = null;
12497                    return activityOptions;
12498                }
12499                return null;
12500            }
12501        } finally {
12502            Binder.restoreCallingIdentity(origId);
12503        }
12504    }
12505
12506    @Override
12507    public void setImmersive(IBinder token, boolean immersive) {
12508        synchronized(this) {
12509            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12510            if (r == null) {
12511                throw new IllegalArgumentException();
12512            }
12513            r.immersive = immersive;
12514
12515            // update associated state if we're frontmost
12516            if (r == mFocusedActivity) {
12517                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12518                applyUpdateLockStateLocked(r);
12519            }
12520        }
12521    }
12522
12523    @Override
12524    public boolean isImmersive(IBinder token) {
12525        synchronized (this) {
12526            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12527            if (r == null) {
12528                throw new IllegalArgumentException();
12529            }
12530            return r.immersive;
12531        }
12532    }
12533
12534    @Override
12535    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12536        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12537            throw new UnsupportedOperationException("VR mode not supported on this device!");
12538        }
12539
12540        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12541
12542        ActivityRecord r;
12543        synchronized (this) {
12544            r = ActivityRecord.isInStackLocked(token);
12545        }
12546
12547        if (r == null) {
12548            throw new IllegalArgumentException();
12549        }
12550
12551        int err;
12552        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12553                VrManagerInternal.NO_ERROR) {
12554            return err;
12555        }
12556
12557        synchronized(this) {
12558            r.requestedVrComponent = (enabled) ? packageName : null;
12559
12560            // Update associated state if this activity is currently focused
12561            if (r == mFocusedActivity) {
12562                applyUpdateVrModeLocked(r);
12563            }
12564            return 0;
12565        }
12566    }
12567
12568    @Override
12569    public boolean isVrModePackageEnabled(ComponentName packageName) {
12570        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12571            throw new UnsupportedOperationException("VR mode not supported on this device!");
12572        }
12573
12574        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12575
12576        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12577                VrManagerInternal.NO_ERROR;
12578    }
12579
12580    public boolean isTopActivityImmersive() {
12581        enforceNotIsolatedCaller("startActivity");
12582        synchronized (this) {
12583            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12584            return (r != null) ? r.immersive : false;
12585        }
12586    }
12587
12588    @Override
12589    public boolean isTopOfTask(IBinder token) {
12590        synchronized (this) {
12591            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12592            if (r == null) {
12593                throw new IllegalArgumentException();
12594            }
12595            return r.task.getTopActivity() == r;
12596        }
12597    }
12598
12599    public final void enterSafeMode() {
12600        synchronized(this) {
12601            // It only makes sense to do this before the system is ready
12602            // and started launching other packages.
12603            if (!mSystemReady) {
12604                try {
12605                    AppGlobals.getPackageManager().enterSafeMode();
12606                } catch (RemoteException e) {
12607                }
12608            }
12609
12610            mSafeMode = true;
12611        }
12612    }
12613
12614    public final void showSafeModeOverlay() {
12615        View v = LayoutInflater.from(mContext).inflate(
12616                com.android.internal.R.layout.safe_mode, null);
12617        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12618        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12619        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12620        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12621        lp.gravity = Gravity.BOTTOM | Gravity.START;
12622        lp.format = v.getBackground().getOpacity();
12623        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12624                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12625        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12626        ((WindowManager)mContext.getSystemService(
12627                Context.WINDOW_SERVICE)).addView(v, lp);
12628    }
12629
12630    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, 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            if (mBatteryStatsService.isOnBattery()) {
12638                mBatteryStatsService.enforceCallingPermission();
12639                int MY_UID = Binder.getCallingUid();
12640                final int uid;
12641                if (sender == null) {
12642                    uid = sourceUid;
12643                } else {
12644                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12645                }
12646                BatteryStatsImpl.Uid.Pkg pkg =
12647                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12648                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12649                pkg.noteWakeupAlarmLocked(tag);
12650            }
12651        }
12652    }
12653
12654    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12655        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12656            return;
12657        }
12658        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12659        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12660        synchronized (stats) {
12661            mBatteryStatsService.enforceCallingPermission();
12662            int MY_UID = Binder.getCallingUid();
12663            final int uid;
12664            if (sender == null) {
12665                uid = sourceUid;
12666            } else {
12667                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12668            }
12669            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12670        }
12671    }
12672
12673    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12674        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12675            return;
12676        }
12677        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12678        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12679        synchronized (stats) {
12680            mBatteryStatsService.enforceCallingPermission();
12681            int MY_UID = Binder.getCallingUid();
12682            final int uid;
12683            if (sender == null) {
12684                uid = sourceUid;
12685            } else {
12686                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12687            }
12688            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12689        }
12690    }
12691
12692    public boolean killPids(int[] pids, String pReason, boolean secure) {
12693        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12694            throw new SecurityException("killPids only available to the system");
12695        }
12696        String reason = (pReason == null) ? "Unknown" : pReason;
12697        // XXX Note: don't acquire main activity lock here, because the window
12698        // manager calls in with its locks held.
12699
12700        boolean killed = false;
12701        synchronized (mPidsSelfLocked) {
12702            int worstType = 0;
12703            for (int i=0; i<pids.length; i++) {
12704                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12705                if (proc != null) {
12706                    int type = proc.setAdj;
12707                    if (type > worstType) {
12708                        worstType = type;
12709                    }
12710                }
12711            }
12712
12713            // If the worst oom_adj is somewhere in the cached proc LRU range,
12714            // then constrain it so we will kill all cached procs.
12715            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12716                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12717                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12718            }
12719
12720            // If this is not a secure call, don't let it kill processes that
12721            // are important.
12722            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12723                worstType = ProcessList.SERVICE_ADJ;
12724            }
12725
12726            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12727            for (int i=0; i<pids.length; i++) {
12728                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12729                if (proc == null) {
12730                    continue;
12731                }
12732                int adj = proc.setAdj;
12733                if (adj >= worstType && !proc.killedByAm) {
12734                    proc.kill(reason, true);
12735                    killed = true;
12736                }
12737            }
12738        }
12739        return killed;
12740    }
12741
12742    @Override
12743    public void killUid(int appId, int userId, String reason) {
12744        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12745        synchronized (this) {
12746            final long identity = Binder.clearCallingIdentity();
12747            try {
12748                killPackageProcessesLocked(null, appId, userId,
12749                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12750                        reason != null ? reason : "kill uid");
12751            } finally {
12752                Binder.restoreCallingIdentity(identity);
12753            }
12754        }
12755    }
12756
12757    @Override
12758    public boolean killProcessesBelowForeground(String reason) {
12759        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12760            throw new SecurityException("killProcessesBelowForeground() only available to system");
12761        }
12762
12763        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12764    }
12765
12766    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12767        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12768            throw new SecurityException("killProcessesBelowAdj() only available to system");
12769        }
12770
12771        boolean killed = false;
12772        synchronized (mPidsSelfLocked) {
12773            final int size = mPidsSelfLocked.size();
12774            for (int i = 0; i < size; i++) {
12775                final int pid = mPidsSelfLocked.keyAt(i);
12776                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12777                if (proc == null) continue;
12778
12779                final int adj = proc.setAdj;
12780                if (adj > belowAdj && !proc.killedByAm) {
12781                    proc.kill(reason, true);
12782                    killed = true;
12783                }
12784            }
12785        }
12786        return killed;
12787    }
12788
12789    @Override
12790    public void hang(final IBinder who, boolean allowRestart) {
12791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12792                != PackageManager.PERMISSION_GRANTED) {
12793            throw new SecurityException("Requires permission "
12794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12795        }
12796
12797        final IBinder.DeathRecipient death = new DeathRecipient() {
12798            @Override
12799            public void binderDied() {
12800                synchronized (this) {
12801                    notifyAll();
12802                }
12803            }
12804        };
12805
12806        try {
12807            who.linkToDeath(death, 0);
12808        } catch (RemoteException e) {
12809            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12810            return;
12811        }
12812
12813        synchronized (this) {
12814            Watchdog.getInstance().setAllowRestart(allowRestart);
12815            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12816            synchronized (death) {
12817                while (who.isBinderAlive()) {
12818                    try {
12819                        death.wait();
12820                    } catch (InterruptedException e) {
12821                    }
12822                }
12823            }
12824            Watchdog.getInstance().setAllowRestart(true);
12825        }
12826    }
12827
12828    @Override
12829    public void restart() {
12830        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12831                != PackageManager.PERMISSION_GRANTED) {
12832            throw new SecurityException("Requires permission "
12833                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12834        }
12835
12836        Log.i(TAG, "Sending shutdown broadcast...");
12837
12838        BroadcastReceiver br = new BroadcastReceiver() {
12839            @Override public void onReceive(Context context, Intent intent) {
12840                // Now the broadcast is done, finish up the low-level shutdown.
12841                Log.i(TAG, "Shutting down activity manager...");
12842                shutdown(10000);
12843                Log.i(TAG, "Shutdown complete, restarting!");
12844                Process.killProcess(Process.myPid());
12845                System.exit(10);
12846            }
12847        };
12848
12849        // First send the high-level shut down broadcast.
12850        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12851        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12852        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12853        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12854        mContext.sendOrderedBroadcastAsUser(intent,
12855                UserHandle.ALL, null, br, mHandler, 0, null, null);
12856        */
12857        br.onReceive(mContext, intent);
12858    }
12859
12860    private long getLowRamTimeSinceIdle(long now) {
12861        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12862    }
12863
12864    @Override
12865    public void performIdleMaintenance() {
12866        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12867                != PackageManager.PERMISSION_GRANTED) {
12868            throw new SecurityException("Requires permission "
12869                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12870        }
12871
12872        synchronized (this) {
12873            final long now = SystemClock.uptimeMillis();
12874            final long timeSinceLastIdle = now - mLastIdleTime;
12875            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12876            mLastIdleTime = now;
12877            mLowRamTimeSinceLastIdle = 0;
12878            if (mLowRamStartTime != 0) {
12879                mLowRamStartTime = now;
12880            }
12881
12882            StringBuilder sb = new StringBuilder(128);
12883            sb.append("Idle maintenance over ");
12884            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12885            sb.append(" low RAM for ");
12886            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12887            Slog.i(TAG, sb.toString());
12888
12889            // If at least 1/3 of our time since the last idle period has been spent
12890            // with RAM low, then we want to kill processes.
12891            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12892
12893            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12894                ProcessRecord proc = mLruProcesses.get(i);
12895                if (proc.notCachedSinceIdle) {
12896                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12897                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12898                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12899                        if (doKilling && proc.initialIdlePss != 0
12900                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12901                            sb = new StringBuilder(128);
12902                            sb.append("Kill");
12903                            sb.append(proc.processName);
12904                            sb.append(" in idle maint: pss=");
12905                            sb.append(proc.lastPss);
12906                            sb.append(", swapPss=");
12907                            sb.append(proc.lastSwapPss);
12908                            sb.append(", initialPss=");
12909                            sb.append(proc.initialIdlePss);
12910                            sb.append(", period=");
12911                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12912                            sb.append(", lowRamPeriod=");
12913                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12914                            Slog.wtfQuiet(TAG, sb.toString());
12915                            proc.kill("idle maint (pss " + proc.lastPss
12916                                    + " from " + proc.initialIdlePss + ")", true);
12917                        }
12918                    }
12919                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12920                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12921                    proc.notCachedSinceIdle = true;
12922                    proc.initialIdlePss = 0;
12923                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12924                            mTestPssMode, isSleepingLocked(), now);
12925                }
12926            }
12927
12928            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12929            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12930        }
12931    }
12932
12933    @Override
12934    public void sendIdleJobTrigger() {
12935        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12936                != PackageManager.PERMISSION_GRANTED) {
12937            throw new SecurityException("Requires permission "
12938                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12939        }
12940
12941        final long ident = Binder.clearCallingIdentity();
12942        try {
12943            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12944                    .setPackage("android")
12945                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12946            broadcastIntent(null, intent, null, null, 0, null, null, null,
12947                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12948        } finally {
12949            Binder.restoreCallingIdentity(ident);
12950        }
12951    }
12952
12953    private void retrieveSettings() {
12954        final ContentResolver resolver = mContext.getContentResolver();
12955        final boolean freeformWindowManagement =
12956                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12957                        || Settings.Global.getInt(
12958                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12959        final boolean supportsPictureInPicture =
12960                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12961
12962        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12963        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12964        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12965        final boolean alwaysFinishActivities =
12966                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12967        final boolean lenientBackgroundCheck =
12968                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12969        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12970        final boolean forceResizable = Settings.Global.getInt(
12971                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12972        final boolean supportsLeanbackOnly =
12973                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12974
12975        // Transfer any global setting for forcing RTL layout, into a System Property
12976        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12977
12978        final Configuration configuration = new Configuration();
12979        Settings.System.getConfiguration(resolver, configuration);
12980        if (forceRtl) {
12981            // This will take care of setting the correct layout direction flags
12982            configuration.setLayoutDirection(configuration.locale);
12983        }
12984
12985        synchronized (this) {
12986            mDebugApp = mOrigDebugApp = debugApp;
12987            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12988            mAlwaysFinishActivities = alwaysFinishActivities;
12989            mLenientBackgroundCheck = lenientBackgroundCheck;
12990            mSupportsLeanbackOnly = supportsLeanbackOnly;
12991            mForceResizableActivities = forceResizable;
12992            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12993            if (supportsMultiWindow || forceResizable) {
12994                mSupportsMultiWindow = true;
12995                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12996                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12997            } else {
12998                mSupportsMultiWindow = false;
12999                mSupportsFreeformWindowManagement = false;
13000                mSupportsPictureInPicture = false;
13001            }
13002            // This happens before any activities are started, so we can
13003            // change mConfiguration in-place.
13004            updateConfigurationLocked(configuration, null, true);
13005            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13006                    "Initial config: " + mConfiguration);
13007
13008            // Load resources only after the current configuration has been set.
13009            final Resources res = mContext.getResources();
13010            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13011            mThumbnailWidth = res.getDimensionPixelSize(
13012                    com.android.internal.R.dimen.thumbnail_width);
13013            mThumbnailHeight = res.getDimensionPixelSize(
13014                    com.android.internal.R.dimen.thumbnail_height);
13015            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13016                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13017            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13018                    com.android.internal.R.string.config_appsNotReportingCrashes));
13019            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13020                mFullscreenThumbnailScale = (float) res
13021                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13022                    (float) mConfiguration.screenWidthDp;
13023            } else {
13024                mFullscreenThumbnailScale = res.getFraction(
13025                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13026            }
13027        }
13028    }
13029
13030    public boolean testIsSystemReady() {
13031        // no need to synchronize(this) just to read & return the value
13032        return mSystemReady;
13033    }
13034
13035    public void systemReady(final Runnable goingCallback) {
13036        synchronized(this) {
13037            if (mSystemReady) {
13038                // If we're done calling all the receivers, run the next "boot phase" passed in
13039                // by the SystemServer
13040                if (goingCallback != null) {
13041                    goingCallback.run();
13042                }
13043                return;
13044            }
13045
13046            mLocalDeviceIdleController
13047                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13048
13049            // Make sure we have the current profile info, since it is needed for security checks.
13050            mUserController.onSystemReady();
13051            mRecentTasks.onSystemReadyLocked();
13052            mAppOpsService.systemReady();
13053            mSystemReady = true;
13054        }
13055
13056        ArrayList<ProcessRecord> procsToKill = null;
13057        synchronized(mPidsSelfLocked) {
13058            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13059                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13060                if (!isAllowedWhileBooting(proc.info)){
13061                    if (procsToKill == null) {
13062                        procsToKill = new ArrayList<ProcessRecord>();
13063                    }
13064                    procsToKill.add(proc);
13065                }
13066            }
13067        }
13068
13069        synchronized(this) {
13070            if (procsToKill != null) {
13071                for (int i=procsToKill.size()-1; i>=0; i--) {
13072                    ProcessRecord proc = procsToKill.get(i);
13073                    Slog.i(TAG, "Removing system update proc: " + proc);
13074                    removeProcessLocked(proc, true, false, "system update done");
13075                }
13076            }
13077
13078            // Now that we have cleaned up any update processes, we
13079            // are ready to start launching real processes and know that
13080            // we won't trample on them any more.
13081            mProcessesReady = true;
13082        }
13083
13084        Slog.i(TAG, "System now ready");
13085        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13086            SystemClock.uptimeMillis());
13087
13088        synchronized(this) {
13089            // Make sure we have no pre-ready processes sitting around.
13090
13091            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13092                ResolveInfo ri = mContext.getPackageManager()
13093                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13094                                STOCK_PM_FLAGS);
13095                CharSequence errorMsg = null;
13096                if (ri != null) {
13097                    ActivityInfo ai = ri.activityInfo;
13098                    ApplicationInfo app = ai.applicationInfo;
13099                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13100                        mTopAction = Intent.ACTION_FACTORY_TEST;
13101                        mTopData = null;
13102                        mTopComponent = new ComponentName(app.packageName,
13103                                ai.name);
13104                    } else {
13105                        errorMsg = mContext.getResources().getText(
13106                                com.android.internal.R.string.factorytest_not_system);
13107                    }
13108                } else {
13109                    errorMsg = mContext.getResources().getText(
13110                            com.android.internal.R.string.factorytest_no_action);
13111                }
13112                if (errorMsg != null) {
13113                    mTopAction = null;
13114                    mTopData = null;
13115                    mTopComponent = null;
13116                    Message msg = Message.obtain();
13117                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13118                    msg.getData().putCharSequence("msg", errorMsg);
13119                    mUiHandler.sendMessage(msg);
13120                }
13121            }
13122        }
13123
13124        retrieveSettings();
13125        final int currentUserId;
13126        synchronized (this) {
13127            currentUserId = mUserController.getCurrentUserIdLocked();
13128            readGrantedUriPermissionsLocked();
13129        }
13130
13131        if (goingCallback != null) goingCallback.run();
13132
13133        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13134                Integer.toString(currentUserId), currentUserId);
13135        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13136                Integer.toString(currentUserId), currentUserId);
13137        mSystemServiceManager.startUser(currentUserId);
13138
13139        synchronized (this) {
13140            // Only start up encryption-aware persistent apps; once user is
13141            // unlocked we'll come back around and start unaware apps
13142            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13143
13144            // Start up initial activity.
13145            mBooting = true;
13146            // Enable home activity for system user, so that the system can always boot
13147            if (UserManager.isSplitSystemUser()) {
13148                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13149                try {
13150                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13151                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13152                            UserHandle.USER_SYSTEM);
13153                } catch (RemoteException e) {
13154                    throw e.rethrowAsRuntimeException();
13155                }
13156            }
13157            startHomeActivityLocked(currentUserId, "systemReady");
13158
13159            try {
13160                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13161                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13162                            + " data partition or your device will be unstable.");
13163                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13164                }
13165            } catch (RemoteException e) {
13166            }
13167
13168            if (!Build.isBuildConsistent()) {
13169                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13170                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13171            }
13172
13173            long ident = Binder.clearCallingIdentity();
13174            try {
13175                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13176                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13177                        | Intent.FLAG_RECEIVER_FOREGROUND);
13178                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13179                broadcastIntentLocked(null, null, intent,
13180                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13181                        null, false, false, MY_PID, Process.SYSTEM_UID,
13182                        currentUserId);
13183                intent = new Intent(Intent.ACTION_USER_STARTING);
13184                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13185                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13186                broadcastIntentLocked(null, null, intent,
13187                        null, new IIntentReceiver.Stub() {
13188                            @Override
13189                            public void performReceive(Intent intent, int resultCode, String data,
13190                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13191                                    throws RemoteException {
13192                            }
13193                        }, 0, null, null,
13194                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13195                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13196            } catch (Throwable t) {
13197                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13198            } finally {
13199                Binder.restoreCallingIdentity(ident);
13200            }
13201            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13202            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13203        }
13204    }
13205
13206    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13207        synchronized (this) {
13208            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13209        }
13210    }
13211
13212    void skipCurrentReceiverLocked(ProcessRecord app) {
13213        for (BroadcastQueue queue : mBroadcastQueues) {
13214            queue.skipCurrentReceiverLocked(app);
13215        }
13216    }
13217
13218    /**
13219     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13220     * The application process will exit immediately after this call returns.
13221     * @param app object of the crashing app, null for the system server
13222     * @param crashInfo describing the exception
13223     */
13224    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13225        ProcessRecord r = findAppProcess(app, "Crash");
13226        final String processName = app == null ? "system_server"
13227                : (r == null ? "unknown" : r.processName);
13228
13229        handleApplicationCrashInner("crash", r, processName, crashInfo);
13230    }
13231
13232    /* Native crash reporting uses this inner version because it needs to be somewhat
13233     * decoupled from the AM-managed cleanup lifecycle
13234     */
13235    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13236            ApplicationErrorReport.CrashInfo crashInfo) {
13237        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13238                UserHandle.getUserId(Binder.getCallingUid()), processName,
13239                r == null ? -1 : r.info.flags,
13240                crashInfo.exceptionClassName,
13241                crashInfo.exceptionMessage,
13242                crashInfo.throwFileName,
13243                crashInfo.throwLineNumber);
13244
13245        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13246
13247        mAppErrors.crashApplication(r, crashInfo);
13248    }
13249
13250    public void handleApplicationStrictModeViolation(
13251            IBinder app,
13252            int violationMask,
13253            StrictMode.ViolationInfo info) {
13254        ProcessRecord r = findAppProcess(app, "StrictMode");
13255        if (r == null) {
13256            return;
13257        }
13258
13259        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13260            Integer stackFingerprint = info.hashCode();
13261            boolean logIt = true;
13262            synchronized (mAlreadyLoggedViolatedStacks) {
13263                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13264                    logIt = false;
13265                    // TODO: sub-sample into EventLog for these, with
13266                    // the info.durationMillis?  Then we'd get
13267                    // the relative pain numbers, without logging all
13268                    // the stack traces repeatedly.  We'd want to do
13269                    // likewise in the client code, which also does
13270                    // dup suppression, before the Binder call.
13271                } else {
13272                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13273                        mAlreadyLoggedViolatedStacks.clear();
13274                    }
13275                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13276                }
13277            }
13278            if (logIt) {
13279                logStrictModeViolationToDropBox(r, info);
13280            }
13281        }
13282
13283        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13284            AppErrorResult result = new AppErrorResult();
13285            synchronized (this) {
13286                final long origId = Binder.clearCallingIdentity();
13287
13288                Message msg = Message.obtain();
13289                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13290                HashMap<String, Object> data = new HashMap<String, Object>();
13291                data.put("result", result);
13292                data.put("app", r);
13293                data.put("violationMask", violationMask);
13294                data.put("info", info);
13295                msg.obj = data;
13296                mUiHandler.sendMessage(msg);
13297
13298                Binder.restoreCallingIdentity(origId);
13299            }
13300            int res = result.get();
13301            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13302        }
13303    }
13304
13305    // Depending on the policy in effect, there could be a bunch of
13306    // these in quick succession so we try to batch these together to
13307    // minimize disk writes, number of dropbox entries, and maximize
13308    // compression, by having more fewer, larger records.
13309    private void logStrictModeViolationToDropBox(
13310            ProcessRecord process,
13311            StrictMode.ViolationInfo info) {
13312        if (info == null) {
13313            return;
13314        }
13315        final boolean isSystemApp = process == null ||
13316                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13317                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13318        final String processName = process == null ? "unknown" : process.processName;
13319        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13320        final DropBoxManager dbox = (DropBoxManager)
13321                mContext.getSystemService(Context.DROPBOX_SERVICE);
13322
13323        // Exit early if the dropbox isn't configured to accept this report type.
13324        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13325
13326        boolean bufferWasEmpty;
13327        boolean needsFlush;
13328        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13329        synchronized (sb) {
13330            bufferWasEmpty = sb.length() == 0;
13331            appendDropBoxProcessHeaders(process, processName, sb);
13332            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13333            sb.append("System-App: ").append(isSystemApp).append("\n");
13334            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13335            if (info.violationNumThisLoop != 0) {
13336                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13337            }
13338            if (info.numAnimationsRunning != 0) {
13339                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13340            }
13341            if (info.broadcastIntentAction != null) {
13342                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13343            }
13344            if (info.durationMillis != -1) {
13345                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13346            }
13347            if (info.numInstances != -1) {
13348                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13349            }
13350            if (info.tags != null) {
13351                for (String tag : info.tags) {
13352                    sb.append("Span-Tag: ").append(tag).append("\n");
13353                }
13354            }
13355            sb.append("\n");
13356            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13357                sb.append(info.crashInfo.stackTrace);
13358                sb.append("\n");
13359            }
13360            if (info.message != null) {
13361                sb.append(info.message);
13362                sb.append("\n");
13363            }
13364
13365            // Only buffer up to ~64k.  Various logging bits truncate
13366            // things at 128k.
13367            needsFlush = (sb.length() > 64 * 1024);
13368        }
13369
13370        // Flush immediately if the buffer's grown too large, or this
13371        // is a non-system app.  Non-system apps are isolated with a
13372        // different tag & policy and not batched.
13373        //
13374        // Batching is useful during internal testing with
13375        // StrictMode settings turned up high.  Without batching,
13376        // thousands of separate files could be created on boot.
13377        if (!isSystemApp || needsFlush) {
13378            new Thread("Error dump: " + dropboxTag) {
13379                @Override
13380                public void run() {
13381                    String report;
13382                    synchronized (sb) {
13383                        report = sb.toString();
13384                        sb.delete(0, sb.length());
13385                        sb.trimToSize();
13386                    }
13387                    if (report.length() != 0) {
13388                        dbox.addText(dropboxTag, report);
13389                    }
13390                }
13391            }.start();
13392            return;
13393        }
13394
13395        // System app batching:
13396        if (!bufferWasEmpty) {
13397            // An existing dropbox-writing thread is outstanding, so
13398            // we don't need to start it up.  The existing thread will
13399            // catch the buffer appends we just did.
13400            return;
13401        }
13402
13403        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13404        // (After this point, we shouldn't access AMS internal data structures.)
13405        new Thread("Error dump: " + dropboxTag) {
13406            @Override
13407            public void run() {
13408                // 5 second sleep to let stacks arrive and be batched together
13409                try {
13410                    Thread.sleep(5000);  // 5 seconds
13411                } catch (InterruptedException e) {}
13412
13413                String errorReport;
13414                synchronized (mStrictModeBuffer) {
13415                    errorReport = mStrictModeBuffer.toString();
13416                    if (errorReport.length() == 0) {
13417                        return;
13418                    }
13419                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13420                    mStrictModeBuffer.trimToSize();
13421                }
13422                dbox.addText(dropboxTag, errorReport);
13423            }
13424        }.start();
13425    }
13426
13427    /**
13428     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13429     * @param app object of the crashing app, null for the system server
13430     * @param tag reported by the caller
13431     * @param system whether this wtf is coming from the system
13432     * @param crashInfo describing the context of the error
13433     * @return true if the process should exit immediately (WTF is fatal)
13434     */
13435    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13436            final ApplicationErrorReport.CrashInfo crashInfo) {
13437        final int callingUid = Binder.getCallingUid();
13438        final int callingPid = Binder.getCallingPid();
13439
13440        if (system) {
13441            // If this is coming from the system, we could very well have low-level
13442            // system locks held, so we want to do this all asynchronously.  And we
13443            // never want this to become fatal, so there is that too.
13444            mHandler.post(new Runnable() {
13445                @Override public void run() {
13446                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13447                }
13448            });
13449            return false;
13450        }
13451
13452        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13453                crashInfo);
13454
13455        if (r != null && r.pid != Process.myPid() &&
13456                Settings.Global.getInt(mContext.getContentResolver(),
13457                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13458            mAppErrors.crashApplication(r, crashInfo);
13459            return true;
13460        } else {
13461            return false;
13462        }
13463    }
13464
13465    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13466            final ApplicationErrorReport.CrashInfo crashInfo) {
13467        final ProcessRecord r = findAppProcess(app, "WTF");
13468        final String processName = app == null ? "system_server"
13469                : (r == null ? "unknown" : r.processName);
13470
13471        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13472                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13473
13474        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13475
13476        return r;
13477    }
13478
13479    /**
13480     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13481     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13482     */
13483    private ProcessRecord findAppProcess(IBinder app, String reason) {
13484        if (app == null) {
13485            return null;
13486        }
13487
13488        synchronized (this) {
13489            final int NP = mProcessNames.getMap().size();
13490            for (int ip=0; ip<NP; ip++) {
13491                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13492                final int NA = apps.size();
13493                for (int ia=0; ia<NA; ia++) {
13494                    ProcessRecord p = apps.valueAt(ia);
13495                    if (p.thread != null && p.thread.asBinder() == app) {
13496                        return p;
13497                    }
13498                }
13499            }
13500
13501            Slog.w(TAG, "Can't find mystery application for " + reason
13502                    + " from pid=" + Binder.getCallingPid()
13503                    + " uid=" + Binder.getCallingUid() + ": " + app);
13504            return null;
13505        }
13506    }
13507
13508    /**
13509     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13510     * to append various headers to the dropbox log text.
13511     */
13512    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13513            StringBuilder sb) {
13514        // Watchdog thread ends up invoking this function (with
13515        // a null ProcessRecord) to add the stack file to dropbox.
13516        // Do not acquire a lock on this (am) in such cases, as it
13517        // could cause a potential deadlock, if and when watchdog
13518        // is invoked due to unavailability of lock on am and it
13519        // would prevent watchdog from killing system_server.
13520        if (process == null) {
13521            sb.append("Process: ").append(processName).append("\n");
13522            return;
13523        }
13524        // Note: ProcessRecord 'process' is guarded by the service
13525        // instance.  (notably process.pkgList, which could otherwise change
13526        // concurrently during execution of this method)
13527        synchronized (this) {
13528            sb.append("Process: ").append(processName).append("\n");
13529            int flags = process.info.flags;
13530            IPackageManager pm = AppGlobals.getPackageManager();
13531            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13532            for (int ip=0; ip<process.pkgList.size(); ip++) {
13533                String pkg = process.pkgList.keyAt(ip);
13534                sb.append("Package: ").append(pkg);
13535                try {
13536                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13537                    if (pi != null) {
13538                        sb.append(" v").append(pi.versionCode);
13539                        if (pi.versionName != null) {
13540                            sb.append(" (").append(pi.versionName).append(")");
13541                        }
13542                    }
13543                } catch (RemoteException e) {
13544                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13545                }
13546                sb.append("\n");
13547            }
13548        }
13549    }
13550
13551    private static String processClass(ProcessRecord process) {
13552        if (process == null || process.pid == MY_PID) {
13553            return "system_server";
13554        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13555            return "system_app";
13556        } else {
13557            return "data_app";
13558        }
13559    }
13560
13561    private volatile long mWtfClusterStart;
13562    private volatile int mWtfClusterCount;
13563
13564    /**
13565     * Write a description of an error (crash, WTF, ANR) to the drop box.
13566     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13567     * @param process which caused the error, null means the system server
13568     * @param activity which triggered the error, null if unknown
13569     * @param parent activity related to the error, null if unknown
13570     * @param subject line related to the error, null if absent
13571     * @param report in long form describing the error, null if absent
13572     * @param dataFile text file to include in the report, null if none
13573     * @param crashInfo giving an application stack trace, null if absent
13574     */
13575    public void addErrorToDropBox(String eventType,
13576            ProcessRecord process, String processName, ActivityRecord activity,
13577            ActivityRecord parent, String subject,
13578            final String report, final File dataFile,
13579            final ApplicationErrorReport.CrashInfo crashInfo) {
13580        // NOTE -- this must never acquire the ActivityManagerService lock,
13581        // otherwise the watchdog may be prevented from resetting the system.
13582
13583        final String dropboxTag = processClass(process) + "_" + eventType;
13584        final DropBoxManager dbox = (DropBoxManager)
13585                mContext.getSystemService(Context.DROPBOX_SERVICE);
13586
13587        // Exit early if the dropbox isn't configured to accept this report type.
13588        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13589
13590        // Rate-limit how often we're willing to do the heavy lifting below to
13591        // collect and record logs; currently 5 logs per 10 second period.
13592        final long now = SystemClock.elapsedRealtime();
13593        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13594            mWtfClusterStart = now;
13595            mWtfClusterCount = 1;
13596        } else {
13597            if (mWtfClusterCount++ >= 5) return;
13598        }
13599
13600        final StringBuilder sb = new StringBuilder(1024);
13601        appendDropBoxProcessHeaders(process, processName, sb);
13602        if (process != null) {
13603            sb.append("Foreground: ")
13604                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13605                    .append("\n");
13606        }
13607        if (activity != null) {
13608            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13609        }
13610        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13611            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13612        }
13613        if (parent != null && parent != activity) {
13614            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13615        }
13616        if (subject != null) {
13617            sb.append("Subject: ").append(subject).append("\n");
13618        }
13619        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13620        if (Debug.isDebuggerConnected()) {
13621            sb.append("Debugger: Connected\n");
13622        }
13623        sb.append("\n");
13624
13625        // Do the rest in a worker thread to avoid blocking the caller on I/O
13626        // (After this point, we shouldn't access AMS internal data structures.)
13627        Thread worker = new Thread("Error dump: " + dropboxTag) {
13628            @Override
13629            public void run() {
13630                if (report != null) {
13631                    sb.append(report);
13632                }
13633
13634                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13635                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13636                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13637                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13638
13639                if (dataFile != null && maxDataFileSize > 0) {
13640                    try {
13641                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13642                                    "\n\n[[TRUNCATED]]"));
13643                    } catch (IOException e) {
13644                        Slog.e(TAG, "Error reading " + dataFile, e);
13645                    }
13646                }
13647                if (crashInfo != null && crashInfo.stackTrace != null) {
13648                    sb.append(crashInfo.stackTrace);
13649                }
13650
13651                if (lines > 0) {
13652                    sb.append("\n");
13653
13654                    // Merge several logcat streams, and take the last N lines
13655                    InputStreamReader input = null;
13656                    try {
13657                        java.lang.Process logcat = new ProcessBuilder(
13658                                "/system/bin/timeout", "-k", "15s", "10s",
13659                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13660                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13661                                        .redirectErrorStream(true).start();
13662
13663                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13664                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13665                        input = new InputStreamReader(logcat.getInputStream());
13666
13667                        int num;
13668                        char[] buf = new char[8192];
13669                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13670                    } catch (IOException e) {
13671                        Slog.e(TAG, "Error running logcat", e);
13672                    } finally {
13673                        if (input != null) try { input.close(); } catch (IOException e) {}
13674                    }
13675                }
13676
13677                dbox.addText(dropboxTag, sb.toString());
13678            }
13679        };
13680
13681        if (process == null) {
13682            // If process is null, we are being called from some internal code
13683            // and may be about to die -- run this synchronously.
13684            worker.run();
13685        } else {
13686            worker.start();
13687        }
13688    }
13689
13690    @Override
13691    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13692        enforceNotIsolatedCaller("getProcessesInErrorState");
13693        // assume our apps are happy - lazy create the list
13694        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13695
13696        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13697                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13698        int userId = UserHandle.getUserId(Binder.getCallingUid());
13699
13700        synchronized (this) {
13701
13702            // iterate across all processes
13703            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13704                ProcessRecord app = mLruProcesses.get(i);
13705                if (!allUsers && app.userId != userId) {
13706                    continue;
13707                }
13708                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13709                    // This one's in trouble, so we'll generate a report for it
13710                    // crashes are higher priority (in case there's a crash *and* an anr)
13711                    ActivityManager.ProcessErrorStateInfo report = null;
13712                    if (app.crashing) {
13713                        report = app.crashingReport;
13714                    } else if (app.notResponding) {
13715                        report = app.notRespondingReport;
13716                    }
13717
13718                    if (report != null) {
13719                        if (errList == null) {
13720                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13721                        }
13722                        errList.add(report);
13723                    } else {
13724                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13725                                " crashing = " + app.crashing +
13726                                " notResponding = " + app.notResponding);
13727                    }
13728                }
13729            }
13730        }
13731
13732        return errList;
13733    }
13734
13735    static int procStateToImportance(int procState, int memAdj,
13736            ActivityManager.RunningAppProcessInfo currApp) {
13737        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13738        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13739            currApp.lru = memAdj;
13740        } else {
13741            currApp.lru = 0;
13742        }
13743        return imp;
13744    }
13745
13746    private void fillInProcMemInfo(ProcessRecord app,
13747            ActivityManager.RunningAppProcessInfo outInfo) {
13748        outInfo.pid = app.pid;
13749        outInfo.uid = app.info.uid;
13750        if (mHeavyWeightProcess == app) {
13751            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13752        }
13753        if (app.persistent) {
13754            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13755        }
13756        if (app.activities.size() > 0) {
13757            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13758        }
13759        outInfo.lastTrimLevel = app.trimMemoryLevel;
13760        int adj = app.curAdj;
13761        int procState = app.curProcState;
13762        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13763        outInfo.importanceReasonCode = app.adjTypeCode;
13764        outInfo.processState = app.curProcState;
13765    }
13766
13767    @Override
13768    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13769        enforceNotIsolatedCaller("getRunningAppProcesses");
13770
13771        final int callingUid = Binder.getCallingUid();
13772
13773        // Lazy instantiation of list
13774        List<ActivityManager.RunningAppProcessInfo> runList = null;
13775        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13776                callingUid) == PackageManager.PERMISSION_GRANTED;
13777        final int userId = UserHandle.getUserId(callingUid);
13778        final boolean allUids = isGetTasksAllowed(
13779                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13780
13781        synchronized (this) {
13782            // Iterate across all processes
13783            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13784                ProcessRecord app = mLruProcesses.get(i);
13785                if ((!allUsers && app.userId != userId)
13786                        || (!allUids && app.uid != callingUid)) {
13787                    continue;
13788                }
13789                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13790                    // Generate process state info for running application
13791                    ActivityManager.RunningAppProcessInfo currApp =
13792                        new ActivityManager.RunningAppProcessInfo(app.processName,
13793                                app.pid, app.getPackageList());
13794                    fillInProcMemInfo(app, currApp);
13795                    if (app.adjSource instanceof ProcessRecord) {
13796                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13797                        currApp.importanceReasonImportance =
13798                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13799                                        app.adjSourceProcState);
13800                    } else if (app.adjSource instanceof ActivityRecord) {
13801                        ActivityRecord r = (ActivityRecord)app.adjSource;
13802                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13803                    }
13804                    if (app.adjTarget instanceof ComponentName) {
13805                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13806                    }
13807                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13808                    //        + " lru=" + currApp.lru);
13809                    if (runList == null) {
13810                        runList = new ArrayList<>();
13811                    }
13812                    runList.add(currApp);
13813                }
13814            }
13815        }
13816        return runList;
13817    }
13818
13819    @Override
13820    public List<ApplicationInfo> getRunningExternalApplications() {
13821        enforceNotIsolatedCaller("getRunningExternalApplications");
13822        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13823        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13824        if (runningApps != null && runningApps.size() > 0) {
13825            Set<String> extList = new HashSet<String>();
13826            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13827                if (app.pkgList != null) {
13828                    for (String pkg : app.pkgList) {
13829                        extList.add(pkg);
13830                    }
13831                }
13832            }
13833            IPackageManager pm = AppGlobals.getPackageManager();
13834            for (String pkg : extList) {
13835                try {
13836                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13837                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13838                        retList.add(info);
13839                    }
13840                } catch (RemoteException e) {
13841                }
13842            }
13843        }
13844        return retList;
13845    }
13846
13847    @Override
13848    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13849        enforceNotIsolatedCaller("getMyMemoryState");
13850        synchronized (this) {
13851            ProcessRecord proc;
13852            synchronized (mPidsSelfLocked) {
13853                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13854            }
13855            fillInProcMemInfo(proc, outInfo);
13856        }
13857    }
13858
13859    @Override
13860    public int getMemoryTrimLevel() {
13861        enforceNotIsolatedCaller("getMyMemoryState");
13862        synchronized (this) {
13863            return mLastMemoryLevel;
13864        }
13865    }
13866
13867    @Override
13868    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13869            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13870        (new ActivityManagerShellCommand(this, false)).exec(
13871                this, in, out, err, args, resultReceiver);
13872    }
13873
13874    @Override
13875    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13876        if (checkCallingPermission(android.Manifest.permission.DUMP)
13877                != PackageManager.PERMISSION_GRANTED) {
13878            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13879                    + Binder.getCallingPid()
13880                    + ", uid=" + Binder.getCallingUid()
13881                    + " without permission "
13882                    + android.Manifest.permission.DUMP);
13883            return;
13884        }
13885
13886        boolean dumpAll = false;
13887        boolean dumpClient = false;
13888        boolean dumpCheckin = false;
13889        boolean dumpCheckinFormat = false;
13890        String dumpPackage = null;
13891
13892        int opti = 0;
13893        while (opti < args.length) {
13894            String opt = args[opti];
13895            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13896                break;
13897            }
13898            opti++;
13899            if ("-a".equals(opt)) {
13900                dumpAll = true;
13901            } else if ("-c".equals(opt)) {
13902                dumpClient = true;
13903            } else if ("-p".equals(opt)) {
13904                if (opti < args.length) {
13905                    dumpPackage = args[opti];
13906                    opti++;
13907                } else {
13908                    pw.println("Error: -p option requires package argument");
13909                    return;
13910                }
13911                dumpClient = true;
13912            } else if ("--checkin".equals(opt)) {
13913                dumpCheckin = dumpCheckinFormat = true;
13914            } else if ("-C".equals(opt)) {
13915                dumpCheckinFormat = true;
13916            } else if ("-h".equals(opt)) {
13917                ActivityManagerShellCommand.dumpHelp(pw, true);
13918                return;
13919            } else {
13920                pw.println("Unknown argument: " + opt + "; use -h for help");
13921            }
13922        }
13923
13924        long origId = Binder.clearCallingIdentity();
13925        boolean more = false;
13926        // Is the caller requesting to dump a particular piece of data?
13927        if (opti < args.length) {
13928            String cmd = args[opti];
13929            opti++;
13930            if ("activities".equals(cmd) || "a".equals(cmd)) {
13931                synchronized (this) {
13932                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13933                }
13934            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13935                synchronized (this) {
13936                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13937                }
13938            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13939                String[] newArgs;
13940                String name;
13941                if (opti >= args.length) {
13942                    name = null;
13943                    newArgs = EMPTY_STRING_ARRAY;
13944                } else {
13945                    dumpPackage = args[opti];
13946                    opti++;
13947                    newArgs = new String[args.length - opti];
13948                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13949                            args.length - opti);
13950                }
13951                synchronized (this) {
13952                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13953                }
13954            } else if ("broadcast-stats".equals(cmd)) {
13955                String[] newArgs;
13956                String name;
13957                if (opti >= args.length) {
13958                    name = null;
13959                    newArgs = EMPTY_STRING_ARRAY;
13960                } else {
13961                    dumpPackage = args[opti];
13962                    opti++;
13963                    newArgs = new String[args.length - opti];
13964                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13965                            args.length - opti);
13966                }
13967                synchronized (this) {
13968                    if (dumpCheckinFormat) {
13969                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13970                                dumpPackage);
13971                    } else {
13972                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13973                    }
13974                }
13975            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13976                String[] newArgs;
13977                String name;
13978                if (opti >= args.length) {
13979                    name = null;
13980                    newArgs = EMPTY_STRING_ARRAY;
13981                } else {
13982                    dumpPackage = args[opti];
13983                    opti++;
13984                    newArgs = new String[args.length - opti];
13985                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13986                            args.length - opti);
13987                }
13988                synchronized (this) {
13989                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13990                }
13991            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13992                String[] newArgs;
13993                String name;
13994                if (opti >= args.length) {
13995                    name = null;
13996                    newArgs = EMPTY_STRING_ARRAY;
13997                } else {
13998                    dumpPackage = args[opti];
13999                    opti++;
14000                    newArgs = new String[args.length - opti];
14001                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14002                            args.length - opti);
14003                }
14004                synchronized (this) {
14005                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14006                }
14007            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14008                synchronized (this) {
14009                    dumpOomLocked(fd, pw, args, opti, true);
14010                }
14011            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14012                synchronized (this) {
14013                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14014                }
14015            } else if ("provider".equals(cmd)) {
14016                String[] newArgs;
14017                String name;
14018                if (opti >= args.length) {
14019                    name = null;
14020                    newArgs = EMPTY_STRING_ARRAY;
14021                } else {
14022                    name = args[opti];
14023                    opti++;
14024                    newArgs = new String[args.length - opti];
14025                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14026                }
14027                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14028                    pw.println("No providers match: " + name);
14029                    pw.println("Use -h for help.");
14030                }
14031            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14032                synchronized (this) {
14033                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14034                }
14035            } else if ("service".equals(cmd)) {
14036                String[] newArgs;
14037                String name;
14038                if (opti >= args.length) {
14039                    name = null;
14040                    newArgs = EMPTY_STRING_ARRAY;
14041                } else {
14042                    name = args[opti];
14043                    opti++;
14044                    newArgs = new String[args.length - opti];
14045                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14046                            args.length - opti);
14047                }
14048                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14049                    pw.println("No services match: " + name);
14050                    pw.println("Use -h for help.");
14051                }
14052            } else if ("package".equals(cmd)) {
14053                String[] newArgs;
14054                if (opti >= args.length) {
14055                    pw.println("package: no package name specified");
14056                    pw.println("Use -h for help.");
14057                } else {
14058                    dumpPackage = args[opti];
14059                    opti++;
14060                    newArgs = new String[args.length - opti];
14061                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14062                            args.length - opti);
14063                    args = newArgs;
14064                    opti = 0;
14065                    more = true;
14066                }
14067            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14068                synchronized (this) {
14069                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14070                }
14071            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14072                if (dumpClient) {
14073                    ActiveServices.ServiceDumper dumper;
14074                    synchronized (this) {
14075                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14076                                dumpPackage);
14077                    }
14078                    dumper.dumpWithClient();
14079                } else {
14080                    synchronized (this) {
14081                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14082                                dumpPackage).dumpLocked();
14083                    }
14084                }
14085            } else if ("locks".equals(cmd)) {
14086                LockGuard.dump(fd, pw, args);
14087            } else {
14088                // Dumping a single activity?
14089                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14090                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14091                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14092                    if (res < 0) {
14093                        pw.println("Bad activity command, or no activities match: " + cmd);
14094                        pw.println("Use -h for help.");
14095                    }
14096                }
14097            }
14098            if (!more) {
14099                Binder.restoreCallingIdentity(origId);
14100                return;
14101            }
14102        }
14103
14104        // No piece of data specified, dump everything.
14105        if (dumpCheckinFormat) {
14106            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14107        } else if (dumpClient) {
14108            ActiveServices.ServiceDumper sdumper;
14109            synchronized (this) {
14110                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14111                pw.println();
14112                if (dumpAll) {
14113                    pw.println("-------------------------------------------------------------------------------");
14114                }
14115                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14116                pw.println();
14117                if (dumpAll) {
14118                    pw.println("-------------------------------------------------------------------------------");
14119                }
14120                if (dumpAll || dumpPackage != null) {
14121                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14122                    pw.println();
14123                    if (dumpAll) {
14124                        pw.println("-------------------------------------------------------------------------------");
14125                    }
14126                }
14127                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14128                pw.println();
14129                if (dumpAll) {
14130                    pw.println("-------------------------------------------------------------------------------");
14131                }
14132                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14133                pw.println();
14134                if (dumpAll) {
14135                    pw.println("-------------------------------------------------------------------------------");
14136                }
14137                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14138                        dumpPackage);
14139            }
14140            sdumper.dumpWithClient();
14141            pw.println();
14142            synchronized (this) {
14143                if (dumpAll) {
14144                    pw.println("-------------------------------------------------------------------------------");
14145                }
14146                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14147                pw.println();
14148                if (dumpAll) {
14149                    pw.println("-------------------------------------------------------------------------------");
14150                }
14151                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14152                if (mAssociations.size() > 0) {
14153                    pw.println();
14154                    if (dumpAll) {
14155                        pw.println("-------------------------------------------------------------------------------");
14156                    }
14157                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14158                }
14159                pw.println();
14160                if (dumpAll) {
14161                    pw.println("-------------------------------------------------------------------------------");
14162                }
14163                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14164            }
14165
14166        } else {
14167            synchronized (this) {
14168                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14169                pw.println();
14170                if (dumpAll) {
14171                    pw.println("-------------------------------------------------------------------------------");
14172                }
14173                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14174                pw.println();
14175                if (dumpAll) {
14176                    pw.println("-------------------------------------------------------------------------------");
14177                }
14178                if (dumpAll || dumpPackage != null) {
14179                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14180                    pw.println();
14181                    if (dumpAll) {
14182                        pw.println("-------------------------------------------------------------------------------");
14183                    }
14184                }
14185                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14186                pw.println();
14187                if (dumpAll) {
14188                    pw.println("-------------------------------------------------------------------------------");
14189                }
14190                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14191                pw.println();
14192                if (dumpAll) {
14193                    pw.println("-------------------------------------------------------------------------------");
14194                }
14195                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14196                        .dumpLocked();
14197                pw.println();
14198                if (dumpAll) {
14199                    pw.println("-------------------------------------------------------------------------------");
14200                }
14201                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14202                pw.println();
14203                if (dumpAll) {
14204                    pw.println("-------------------------------------------------------------------------------");
14205                }
14206                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14207                if (mAssociations.size() > 0) {
14208                    pw.println();
14209                    if (dumpAll) {
14210                        pw.println("-------------------------------------------------------------------------------");
14211                    }
14212                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14213                }
14214                pw.println();
14215                if (dumpAll) {
14216                    pw.println("-------------------------------------------------------------------------------");
14217                }
14218                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14219            }
14220        }
14221        Binder.restoreCallingIdentity(origId);
14222    }
14223
14224    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14225            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14226        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14227
14228        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14229                dumpPackage);
14230        boolean needSep = printedAnything;
14231
14232        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14233                dumpPackage, needSep, "  mFocusedActivity: ");
14234        if (printed) {
14235            printedAnything = true;
14236            needSep = false;
14237        }
14238
14239        if (dumpPackage == null) {
14240            if (needSep) {
14241                pw.println();
14242            }
14243            needSep = true;
14244            printedAnything = true;
14245            mStackSupervisor.dump(pw, "  ");
14246        }
14247
14248        if (!printedAnything) {
14249            pw.println("  (nothing)");
14250        }
14251    }
14252
14253    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14254            int opti, boolean dumpAll, String dumpPackage) {
14255        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14256
14257        boolean printedAnything = false;
14258
14259        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14260            boolean printedHeader = false;
14261
14262            final int N = mRecentTasks.size();
14263            for (int i=0; i<N; i++) {
14264                TaskRecord tr = mRecentTasks.get(i);
14265                if (dumpPackage != null) {
14266                    if (tr.realActivity == null ||
14267                            !dumpPackage.equals(tr.realActivity)) {
14268                        continue;
14269                    }
14270                }
14271                if (!printedHeader) {
14272                    pw.println("  Recent tasks:");
14273                    printedHeader = true;
14274                    printedAnything = true;
14275                }
14276                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14277                        pw.println(tr);
14278                if (dumpAll) {
14279                    mRecentTasks.get(i).dump(pw, "    ");
14280                }
14281            }
14282        }
14283
14284        if (!printedAnything) {
14285            pw.println("  (nothing)");
14286        }
14287    }
14288
14289    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14290            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14291        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14292
14293        int dumpUid = 0;
14294        if (dumpPackage != null) {
14295            IPackageManager pm = AppGlobals.getPackageManager();
14296            try {
14297                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14298            } catch (RemoteException e) {
14299            }
14300        }
14301
14302        boolean printedAnything = false;
14303
14304        final long now = SystemClock.uptimeMillis();
14305
14306        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14307            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14308                    = mAssociations.valueAt(i1);
14309            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14310                SparseArray<ArrayMap<String, Association>> sourceUids
14311                        = targetComponents.valueAt(i2);
14312                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14313                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14314                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14315                        Association ass = sourceProcesses.valueAt(i4);
14316                        if (dumpPackage != null) {
14317                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14318                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14319                                continue;
14320                            }
14321                        }
14322                        printedAnything = true;
14323                        pw.print("  ");
14324                        pw.print(ass.mTargetProcess);
14325                        pw.print("/");
14326                        UserHandle.formatUid(pw, ass.mTargetUid);
14327                        pw.print(" <- ");
14328                        pw.print(ass.mSourceProcess);
14329                        pw.print("/");
14330                        UserHandle.formatUid(pw, ass.mSourceUid);
14331                        pw.println();
14332                        pw.print("    via ");
14333                        pw.print(ass.mTargetComponent.flattenToShortString());
14334                        pw.println();
14335                        pw.print("    ");
14336                        long dur = ass.mTime;
14337                        if (ass.mNesting > 0) {
14338                            dur += now - ass.mStartTime;
14339                        }
14340                        TimeUtils.formatDuration(dur, pw);
14341                        pw.print(" (");
14342                        pw.print(ass.mCount);
14343                        pw.print(" times)");
14344                        pw.print("  ");
14345                        for (int i=0; i<ass.mStateTimes.length; i++) {
14346                            long amt = ass.mStateTimes[i];
14347                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14348                                amt += now - ass.mLastStateUptime;
14349                            }
14350                            if (amt != 0) {
14351                                pw.print(" ");
14352                                pw.print(ProcessList.makeProcStateString(
14353                                            i + ActivityManager.MIN_PROCESS_STATE));
14354                                pw.print("=");
14355                                TimeUtils.formatDuration(amt, pw);
14356                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14357                                    pw.print("*");
14358                                }
14359                            }
14360                        }
14361                        pw.println();
14362                        if (ass.mNesting > 0) {
14363                            pw.print("    Currently active: ");
14364                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14365                            pw.println();
14366                        }
14367                    }
14368                }
14369            }
14370
14371        }
14372
14373        if (!printedAnything) {
14374            pw.println("  (nothing)");
14375        }
14376    }
14377
14378    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14379            String header, boolean needSep) {
14380        boolean printed = false;
14381        int whichAppId = -1;
14382        if (dumpPackage != null) {
14383            try {
14384                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14385                        dumpPackage, 0);
14386                whichAppId = UserHandle.getAppId(info.uid);
14387            } catch (NameNotFoundException e) {
14388                e.printStackTrace();
14389            }
14390        }
14391        for (int i=0; i<uids.size(); i++) {
14392            UidRecord uidRec = uids.valueAt(i);
14393            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14394                continue;
14395            }
14396            if (!printed) {
14397                printed = true;
14398                if (needSep) {
14399                    pw.println();
14400                }
14401                pw.print("  ");
14402                pw.println(header);
14403                needSep = true;
14404            }
14405            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14406            pw.print(": "); pw.println(uidRec);
14407        }
14408        return printed;
14409    }
14410
14411    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14412            int opti, boolean dumpAll, String dumpPackage) {
14413        boolean needSep = false;
14414        boolean printedAnything = false;
14415        int numPers = 0;
14416
14417        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14418
14419        if (dumpAll) {
14420            final int NP = mProcessNames.getMap().size();
14421            for (int ip=0; ip<NP; ip++) {
14422                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14423                final int NA = procs.size();
14424                for (int ia=0; ia<NA; ia++) {
14425                    ProcessRecord r = procs.valueAt(ia);
14426                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14427                        continue;
14428                    }
14429                    if (!needSep) {
14430                        pw.println("  All known processes:");
14431                        needSep = true;
14432                        printedAnything = true;
14433                    }
14434                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14435                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14436                        pw.print(" "); pw.println(r);
14437                    r.dump(pw, "    ");
14438                    if (r.persistent) {
14439                        numPers++;
14440                    }
14441                }
14442            }
14443        }
14444
14445        if (mIsolatedProcesses.size() > 0) {
14446            boolean printed = false;
14447            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14448                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14449                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14450                    continue;
14451                }
14452                if (!printed) {
14453                    if (needSep) {
14454                        pw.println();
14455                    }
14456                    pw.println("  Isolated process list (sorted by uid):");
14457                    printedAnything = true;
14458                    printed = true;
14459                    needSep = true;
14460                }
14461                pw.println(String.format("%sIsolated #%2d: %s",
14462                        "    ", i, r.toString()));
14463            }
14464        }
14465
14466        if (mActiveUids.size() > 0) {
14467            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14468                printedAnything = needSep = true;
14469            }
14470        }
14471        if (mValidateUids.size() > 0) {
14472            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14473                printedAnything = needSep = true;
14474            }
14475        }
14476
14477        if (mLruProcesses.size() > 0) {
14478            if (needSep) {
14479                pw.println();
14480            }
14481            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14482                    pw.print(" total, non-act at ");
14483                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14484                    pw.print(", non-svc at ");
14485                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14486                    pw.println("):");
14487            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14488            needSep = true;
14489            printedAnything = true;
14490        }
14491
14492        if (dumpAll || dumpPackage != null) {
14493            synchronized (mPidsSelfLocked) {
14494                boolean printed = false;
14495                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14496                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14497                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14498                        continue;
14499                    }
14500                    if (!printed) {
14501                        if (needSep) pw.println();
14502                        needSep = true;
14503                        pw.println("  PID mappings:");
14504                        printed = true;
14505                        printedAnything = true;
14506                    }
14507                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14508                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14509                }
14510            }
14511        }
14512
14513        if (mForegroundProcesses.size() > 0) {
14514            synchronized (mPidsSelfLocked) {
14515                boolean printed = false;
14516                for (int i=0; i<mForegroundProcesses.size(); i++) {
14517                    ProcessRecord r = mPidsSelfLocked.get(
14518                            mForegroundProcesses.valueAt(i).pid);
14519                    if (dumpPackage != null && (r == null
14520                            || !r.pkgList.containsKey(dumpPackage))) {
14521                        continue;
14522                    }
14523                    if (!printed) {
14524                        if (needSep) pw.println();
14525                        needSep = true;
14526                        pw.println("  Foreground Processes:");
14527                        printed = true;
14528                        printedAnything = true;
14529                    }
14530                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14531                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14532                }
14533            }
14534        }
14535
14536        if (mPersistentStartingProcesses.size() > 0) {
14537            if (needSep) pw.println();
14538            needSep = true;
14539            printedAnything = true;
14540            pw.println("  Persisent processes that are starting:");
14541            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14542                    "Starting Norm", "Restarting PERS", dumpPackage);
14543        }
14544
14545        if (mRemovedProcesses.size() > 0) {
14546            if (needSep) pw.println();
14547            needSep = true;
14548            printedAnything = true;
14549            pw.println("  Processes that are being removed:");
14550            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14551                    "Removed Norm", "Removed PERS", dumpPackage);
14552        }
14553
14554        if (mProcessesOnHold.size() > 0) {
14555            if (needSep) pw.println();
14556            needSep = true;
14557            printedAnything = true;
14558            pw.println("  Processes that are on old until the system is ready:");
14559            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14560                    "OnHold Norm", "OnHold PERS", dumpPackage);
14561        }
14562
14563        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14564
14565        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14566        if (needSep) {
14567            printedAnything = true;
14568        }
14569
14570        if (dumpPackage == null) {
14571            pw.println();
14572            needSep = false;
14573            mUserController.dump(pw, dumpAll);
14574        }
14575        if (mHomeProcess != null && (dumpPackage == null
14576                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14577            if (needSep) {
14578                pw.println();
14579                needSep = false;
14580            }
14581            pw.println("  mHomeProcess: " + mHomeProcess);
14582        }
14583        if (mPreviousProcess != null && (dumpPackage == null
14584                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14585            if (needSep) {
14586                pw.println();
14587                needSep = false;
14588            }
14589            pw.println("  mPreviousProcess: " + mPreviousProcess);
14590        }
14591        if (dumpAll) {
14592            StringBuilder sb = new StringBuilder(128);
14593            sb.append("  mPreviousProcessVisibleTime: ");
14594            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14595            pw.println(sb);
14596        }
14597        if (mHeavyWeightProcess != null && (dumpPackage == null
14598                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14599            if (needSep) {
14600                pw.println();
14601                needSep = false;
14602            }
14603            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14604        }
14605        if (dumpPackage == null) {
14606            pw.println("  mConfiguration: " + mConfiguration);
14607        }
14608        if (dumpAll) {
14609            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14610            if (mCompatModePackages.getPackages().size() > 0) {
14611                boolean printed = false;
14612                for (Map.Entry<String, Integer> entry
14613                        : mCompatModePackages.getPackages().entrySet()) {
14614                    String pkg = entry.getKey();
14615                    int mode = entry.getValue();
14616                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14617                        continue;
14618                    }
14619                    if (!printed) {
14620                        pw.println("  mScreenCompatPackages:");
14621                        printed = true;
14622                    }
14623                    pw.print("    "); pw.print(pkg); pw.print(": ");
14624                            pw.print(mode); pw.println();
14625                }
14626            }
14627        }
14628        if (dumpPackage == null) {
14629            pw.println("  mWakefulness="
14630                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14631            pw.println("  mSleepTokens=" + mSleepTokens);
14632            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14633                    + lockScreenShownToString());
14634            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14635            if (mRunningVoice != null) {
14636                pw.println("  mRunningVoice=" + mRunningVoice);
14637                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14638            }
14639        }
14640        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14641                || mOrigWaitForDebugger) {
14642            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14643                    || dumpPackage.equals(mOrigDebugApp)) {
14644                if (needSep) {
14645                    pw.println();
14646                    needSep = false;
14647                }
14648                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14649                        + " mDebugTransient=" + mDebugTransient
14650                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14651            }
14652        }
14653        if (mCurAppTimeTracker != null) {
14654            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14655        }
14656        if (mMemWatchProcesses.getMap().size() > 0) {
14657            pw.println("  Mem watch processes:");
14658            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14659                    = mMemWatchProcesses.getMap();
14660            for (int i=0; i<procs.size(); i++) {
14661                final String proc = procs.keyAt(i);
14662                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14663                for (int j=0; j<uids.size(); j++) {
14664                    if (needSep) {
14665                        pw.println();
14666                        needSep = false;
14667                    }
14668                    StringBuilder sb = new StringBuilder();
14669                    sb.append("    ").append(proc).append('/');
14670                    UserHandle.formatUid(sb, uids.keyAt(j));
14671                    Pair<Long, String> val = uids.valueAt(j);
14672                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14673                    if (val.second != null) {
14674                        sb.append(", report to ").append(val.second);
14675                    }
14676                    pw.println(sb.toString());
14677                }
14678            }
14679            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14680            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14681            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14682                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14683        }
14684        if (mTrackAllocationApp != null) {
14685            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14686                if (needSep) {
14687                    pw.println();
14688                    needSep = false;
14689                }
14690                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14691            }
14692        }
14693        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14694                || mProfileFd != null) {
14695            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14696                if (needSep) {
14697                    pw.println();
14698                    needSep = false;
14699                }
14700                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14701                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14702                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14703                        + mAutoStopProfiler);
14704                pw.println("  mProfileType=" + mProfileType);
14705            }
14706        }
14707        if (mNativeDebuggingApp != null) {
14708            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14709                if (needSep) {
14710                    pw.println();
14711                    needSep = false;
14712                }
14713                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14714            }
14715        }
14716        if (dumpPackage == null) {
14717            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14718                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14719                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14720            }
14721            if (mController != null) {
14722                pw.println("  mController=" + mController
14723                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14724            }
14725            if (dumpAll) {
14726                pw.println("  Total persistent processes: " + numPers);
14727                pw.println("  mProcessesReady=" + mProcessesReady
14728                        + " mSystemReady=" + mSystemReady
14729                        + " mBooted=" + mBooted
14730                        + " mFactoryTest=" + mFactoryTest);
14731                pw.println("  mBooting=" + mBooting
14732                        + " mCallFinishBooting=" + mCallFinishBooting
14733                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14734                pw.print("  mLastPowerCheckRealtime=");
14735                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14736                        pw.println("");
14737                pw.print("  mLastPowerCheckUptime=");
14738                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14739                        pw.println("");
14740                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14741                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14742                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14743                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14744                        + " (" + mLruProcesses.size() + " total)"
14745                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14746                        + " mNumServiceProcs=" + mNumServiceProcs
14747                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14748                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14749                        + " mLastMemoryLevel=" + mLastMemoryLevel
14750                        + " mLastNumProcesses=" + mLastNumProcesses);
14751                long now = SystemClock.uptimeMillis();
14752                pw.print("  mLastIdleTime=");
14753                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14754                        pw.print(" mLowRamSinceLastIdle=");
14755                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14756                        pw.println();
14757            }
14758        }
14759
14760        if (!printedAnything) {
14761            pw.println("  (nothing)");
14762        }
14763    }
14764
14765    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14766            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14767        if (mProcessesToGc.size() > 0) {
14768            boolean printed = false;
14769            long now = SystemClock.uptimeMillis();
14770            for (int i=0; i<mProcessesToGc.size(); i++) {
14771                ProcessRecord proc = mProcessesToGc.get(i);
14772                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14773                    continue;
14774                }
14775                if (!printed) {
14776                    if (needSep) pw.println();
14777                    needSep = true;
14778                    pw.println("  Processes that are waiting to GC:");
14779                    printed = true;
14780                }
14781                pw.print("    Process "); pw.println(proc);
14782                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14783                        pw.print(", last gced=");
14784                        pw.print(now-proc.lastRequestedGc);
14785                        pw.print(" ms ago, last lowMem=");
14786                        pw.print(now-proc.lastLowMemory);
14787                        pw.println(" ms ago");
14788
14789            }
14790        }
14791        return needSep;
14792    }
14793
14794    void printOomLevel(PrintWriter pw, String name, int adj) {
14795        pw.print("    ");
14796        if (adj >= 0) {
14797            pw.print(' ');
14798            if (adj < 10) pw.print(' ');
14799        } else {
14800            if (adj > -10) pw.print(' ');
14801        }
14802        pw.print(adj);
14803        pw.print(": ");
14804        pw.print(name);
14805        pw.print(" (");
14806        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14807        pw.println(")");
14808    }
14809
14810    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14811            int opti, boolean dumpAll) {
14812        boolean needSep = false;
14813
14814        if (mLruProcesses.size() > 0) {
14815            if (needSep) pw.println();
14816            needSep = true;
14817            pw.println("  OOM levels:");
14818            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14819            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14820            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14821            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14822            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14823            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14824            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14825            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14826            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14827            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14828            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14829            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14830            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14831            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14832
14833            if (needSep) pw.println();
14834            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14835                    pw.print(" total, non-act at ");
14836                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14837                    pw.print(", non-svc at ");
14838                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14839                    pw.println("):");
14840            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14841            needSep = true;
14842        }
14843
14844        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14845
14846        pw.println();
14847        pw.println("  mHomeProcess: " + mHomeProcess);
14848        pw.println("  mPreviousProcess: " + mPreviousProcess);
14849        if (mHeavyWeightProcess != null) {
14850            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14851        }
14852
14853        return true;
14854    }
14855
14856    /**
14857     * There are three ways to call this:
14858     *  - no provider specified: dump all the providers
14859     *  - a flattened component name that matched an existing provider was specified as the
14860     *    first arg: dump that one provider
14861     *  - the first arg isn't the flattened component name of an existing provider:
14862     *    dump all providers whose component contains the first arg as a substring
14863     */
14864    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14865            int opti, boolean dumpAll) {
14866        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14867    }
14868
14869    static class ItemMatcher {
14870        ArrayList<ComponentName> components;
14871        ArrayList<String> strings;
14872        ArrayList<Integer> objects;
14873        boolean all;
14874
14875        ItemMatcher() {
14876            all = true;
14877        }
14878
14879        void build(String name) {
14880            ComponentName componentName = ComponentName.unflattenFromString(name);
14881            if (componentName != null) {
14882                if (components == null) {
14883                    components = new ArrayList<ComponentName>();
14884                }
14885                components.add(componentName);
14886                all = false;
14887            } else {
14888                int objectId = 0;
14889                // Not a '/' separated full component name; maybe an object ID?
14890                try {
14891                    objectId = Integer.parseInt(name, 16);
14892                    if (objects == null) {
14893                        objects = new ArrayList<Integer>();
14894                    }
14895                    objects.add(objectId);
14896                    all = false;
14897                } catch (RuntimeException e) {
14898                    // Not an integer; just do string match.
14899                    if (strings == null) {
14900                        strings = new ArrayList<String>();
14901                    }
14902                    strings.add(name);
14903                    all = false;
14904                }
14905            }
14906        }
14907
14908        int build(String[] args, int opti) {
14909            for (; opti<args.length; opti++) {
14910                String name = args[opti];
14911                if ("--".equals(name)) {
14912                    return opti+1;
14913                }
14914                build(name);
14915            }
14916            return opti;
14917        }
14918
14919        boolean match(Object object, ComponentName comp) {
14920            if (all) {
14921                return true;
14922            }
14923            if (components != null) {
14924                for (int i=0; i<components.size(); i++) {
14925                    if (components.get(i).equals(comp)) {
14926                        return true;
14927                    }
14928                }
14929            }
14930            if (objects != null) {
14931                for (int i=0; i<objects.size(); i++) {
14932                    if (System.identityHashCode(object) == objects.get(i)) {
14933                        return true;
14934                    }
14935                }
14936            }
14937            if (strings != null) {
14938                String flat = comp.flattenToString();
14939                for (int i=0; i<strings.size(); i++) {
14940                    if (flat.contains(strings.get(i))) {
14941                        return true;
14942                    }
14943                }
14944            }
14945            return false;
14946        }
14947    }
14948
14949    /**
14950     * There are three things that cmd can be:
14951     *  - a flattened component name that matches an existing activity
14952     *  - the cmd arg isn't the flattened component name of an existing activity:
14953     *    dump all activity whose component contains the cmd as a substring
14954     *  - A hex number of the ActivityRecord object instance.
14955     */
14956    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14957            int opti, boolean dumpAll) {
14958        ArrayList<ActivityRecord> activities;
14959
14960        synchronized (this) {
14961            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14962        }
14963
14964        if (activities.size() <= 0) {
14965            return false;
14966        }
14967
14968        String[] newArgs = new String[args.length - opti];
14969        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14970
14971        TaskRecord lastTask = null;
14972        boolean needSep = false;
14973        for (int i=activities.size()-1; i>=0; i--) {
14974            ActivityRecord r = activities.get(i);
14975            if (needSep) {
14976                pw.println();
14977            }
14978            needSep = true;
14979            synchronized (this) {
14980                if (lastTask != r.task) {
14981                    lastTask = r.task;
14982                    pw.print("TASK "); pw.print(lastTask.affinity);
14983                            pw.print(" id="); pw.println(lastTask.taskId);
14984                    if (dumpAll) {
14985                        lastTask.dump(pw, "  ");
14986                    }
14987                }
14988            }
14989            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14990        }
14991        return true;
14992    }
14993
14994    /**
14995     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14996     * there is a thread associated with the activity.
14997     */
14998    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14999            final ActivityRecord r, String[] args, boolean dumpAll) {
15000        String innerPrefix = prefix + "  ";
15001        synchronized (this) {
15002            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15003                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15004                    pw.print(" pid=");
15005                    if (r.app != null) pw.println(r.app.pid);
15006                    else pw.println("(not running)");
15007            if (dumpAll) {
15008                r.dump(pw, innerPrefix);
15009            }
15010        }
15011        if (r.app != null && r.app.thread != null) {
15012            // flush anything that is already in the PrintWriter since the thread is going
15013            // to write to the file descriptor directly
15014            pw.flush();
15015            try {
15016                TransferPipe tp = new TransferPipe();
15017                try {
15018                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15019                            r.appToken, innerPrefix, args);
15020                    tp.go(fd);
15021                } finally {
15022                    tp.kill();
15023                }
15024            } catch (IOException e) {
15025                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15026            } catch (RemoteException e) {
15027                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15028            }
15029        }
15030    }
15031
15032    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15033            int opti, boolean dumpAll, String dumpPackage) {
15034        boolean needSep = false;
15035        boolean onlyHistory = false;
15036        boolean printedAnything = false;
15037
15038        if ("history".equals(dumpPackage)) {
15039            if (opti < args.length && "-s".equals(args[opti])) {
15040                dumpAll = false;
15041            }
15042            onlyHistory = true;
15043            dumpPackage = null;
15044        }
15045
15046        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15047        if (!onlyHistory && dumpAll) {
15048            if (mRegisteredReceivers.size() > 0) {
15049                boolean printed = false;
15050                Iterator it = mRegisteredReceivers.values().iterator();
15051                while (it.hasNext()) {
15052                    ReceiverList r = (ReceiverList)it.next();
15053                    if (dumpPackage != null && (r.app == null ||
15054                            !dumpPackage.equals(r.app.info.packageName))) {
15055                        continue;
15056                    }
15057                    if (!printed) {
15058                        pw.println("  Registered Receivers:");
15059                        needSep = true;
15060                        printed = true;
15061                        printedAnything = true;
15062                    }
15063                    pw.print("  * "); pw.println(r);
15064                    r.dump(pw, "    ");
15065                }
15066            }
15067
15068            if (mReceiverResolver.dump(pw, needSep ?
15069                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15070                    "    ", dumpPackage, false, false)) {
15071                needSep = true;
15072                printedAnything = true;
15073            }
15074        }
15075
15076        for (BroadcastQueue q : mBroadcastQueues) {
15077            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15078            printedAnything |= needSep;
15079        }
15080
15081        needSep = true;
15082
15083        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15084            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15085                if (needSep) {
15086                    pw.println();
15087                }
15088                needSep = true;
15089                printedAnything = true;
15090                pw.print("  Sticky broadcasts for user ");
15091                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15092                StringBuilder sb = new StringBuilder(128);
15093                for (Map.Entry<String, ArrayList<Intent>> ent
15094                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15095                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15096                    if (dumpAll) {
15097                        pw.println(":");
15098                        ArrayList<Intent> intents = ent.getValue();
15099                        final int N = intents.size();
15100                        for (int i=0; i<N; i++) {
15101                            sb.setLength(0);
15102                            sb.append("    Intent: ");
15103                            intents.get(i).toShortString(sb, false, true, false, false);
15104                            pw.println(sb.toString());
15105                            Bundle bundle = intents.get(i).getExtras();
15106                            if (bundle != null) {
15107                                pw.print("      ");
15108                                pw.println(bundle.toString());
15109                            }
15110                        }
15111                    } else {
15112                        pw.println("");
15113                    }
15114                }
15115            }
15116        }
15117
15118        if (!onlyHistory && dumpAll) {
15119            pw.println();
15120            for (BroadcastQueue queue : mBroadcastQueues) {
15121                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15122                        + queue.mBroadcastsScheduled);
15123            }
15124            pw.println("  mHandler:");
15125            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15126            needSep = true;
15127            printedAnything = true;
15128        }
15129
15130        if (!printedAnything) {
15131            pw.println("  (nothing)");
15132        }
15133    }
15134
15135    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15136            int opti, boolean dumpAll, String dumpPackage) {
15137        if (mCurBroadcastStats == null) {
15138            return;
15139        }
15140
15141        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15142        final long now = SystemClock.elapsedRealtime();
15143        if (mLastBroadcastStats != null) {
15144            pw.print("  Last stats (from ");
15145            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15146            pw.print(" to ");
15147            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15148            pw.print(", ");
15149            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15150                    - mLastBroadcastStats.mStartUptime, pw);
15151            pw.println(" uptime):");
15152            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15153                pw.println("    (nothing)");
15154            }
15155            pw.println();
15156        }
15157        pw.print("  Current stats (from ");
15158        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15159        pw.print(" to now, ");
15160        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15161                - mCurBroadcastStats.mStartUptime, pw);
15162        pw.println(" uptime):");
15163        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15164            pw.println("    (nothing)");
15165        }
15166    }
15167
15168    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15169            int opti, boolean fullCheckin, String dumpPackage) {
15170        if (mCurBroadcastStats == null) {
15171            return;
15172        }
15173
15174        if (mLastBroadcastStats != null) {
15175            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15176            if (fullCheckin) {
15177                mLastBroadcastStats = null;
15178                return;
15179            }
15180        }
15181        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15182        if (fullCheckin) {
15183            mCurBroadcastStats = null;
15184        }
15185    }
15186
15187    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15188            int opti, boolean dumpAll, String dumpPackage) {
15189        boolean needSep;
15190        boolean printedAnything = false;
15191
15192        ItemMatcher matcher = new ItemMatcher();
15193        matcher.build(args, opti);
15194
15195        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15196
15197        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15198        printedAnything |= needSep;
15199
15200        if (mLaunchingProviders.size() > 0) {
15201            boolean printed = false;
15202            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15203                ContentProviderRecord r = mLaunchingProviders.get(i);
15204                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15205                    continue;
15206                }
15207                if (!printed) {
15208                    if (needSep) pw.println();
15209                    needSep = true;
15210                    pw.println("  Launching content providers:");
15211                    printed = true;
15212                    printedAnything = true;
15213                }
15214                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15215                        pw.println(r);
15216            }
15217        }
15218
15219        if (!printedAnything) {
15220            pw.println("  (nothing)");
15221        }
15222    }
15223
15224    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15225            int opti, boolean dumpAll, String dumpPackage) {
15226        boolean needSep = false;
15227        boolean printedAnything = false;
15228
15229        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15230
15231        if (mGrantedUriPermissions.size() > 0) {
15232            boolean printed = false;
15233            int dumpUid = -2;
15234            if (dumpPackage != null) {
15235                try {
15236                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15237                            MATCH_UNINSTALLED_PACKAGES, 0);
15238                } catch (NameNotFoundException e) {
15239                    dumpUid = -1;
15240                }
15241            }
15242            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15243                int uid = mGrantedUriPermissions.keyAt(i);
15244                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15245                    continue;
15246                }
15247                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15248                if (!printed) {
15249                    if (needSep) pw.println();
15250                    needSep = true;
15251                    pw.println("  Granted Uri Permissions:");
15252                    printed = true;
15253                    printedAnything = true;
15254                }
15255                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15256                for (UriPermission perm : perms.values()) {
15257                    pw.print("    "); pw.println(perm);
15258                    if (dumpAll) {
15259                        perm.dump(pw, "      ");
15260                    }
15261                }
15262            }
15263        }
15264
15265        if (!printedAnything) {
15266            pw.println("  (nothing)");
15267        }
15268    }
15269
15270    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15271            int opti, boolean dumpAll, String dumpPackage) {
15272        boolean printed = false;
15273
15274        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15275
15276        if (mIntentSenderRecords.size() > 0) {
15277            Iterator<WeakReference<PendingIntentRecord>> it
15278                    = mIntentSenderRecords.values().iterator();
15279            while (it.hasNext()) {
15280                WeakReference<PendingIntentRecord> ref = it.next();
15281                PendingIntentRecord rec = ref != null ? ref.get(): null;
15282                if (dumpPackage != null && (rec == null
15283                        || !dumpPackage.equals(rec.key.packageName))) {
15284                    continue;
15285                }
15286                printed = true;
15287                if (rec != null) {
15288                    pw.print("  * "); pw.println(rec);
15289                    if (dumpAll) {
15290                        rec.dump(pw, "    ");
15291                    }
15292                } else {
15293                    pw.print("  * "); pw.println(ref);
15294                }
15295            }
15296        }
15297
15298        if (!printed) {
15299            pw.println("  (nothing)");
15300        }
15301    }
15302
15303    private static final int dumpProcessList(PrintWriter pw,
15304            ActivityManagerService service, List list,
15305            String prefix, String normalLabel, String persistentLabel,
15306            String dumpPackage) {
15307        int numPers = 0;
15308        final int N = list.size()-1;
15309        for (int i=N; i>=0; i--) {
15310            ProcessRecord r = (ProcessRecord)list.get(i);
15311            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15312                continue;
15313            }
15314            pw.println(String.format("%s%s #%2d: %s",
15315                    prefix, (r.persistent ? persistentLabel : normalLabel),
15316                    i, r.toString()));
15317            if (r.persistent) {
15318                numPers++;
15319            }
15320        }
15321        return numPers;
15322    }
15323
15324    private static final boolean dumpProcessOomList(PrintWriter pw,
15325            ActivityManagerService service, List<ProcessRecord> origList,
15326            String prefix, String normalLabel, String persistentLabel,
15327            boolean inclDetails, String dumpPackage) {
15328
15329        ArrayList<Pair<ProcessRecord, Integer>> list
15330                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15331        for (int i=0; i<origList.size(); i++) {
15332            ProcessRecord r = origList.get(i);
15333            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15334                continue;
15335            }
15336            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15337        }
15338
15339        if (list.size() <= 0) {
15340            return false;
15341        }
15342
15343        Comparator<Pair<ProcessRecord, Integer>> comparator
15344                = new Comparator<Pair<ProcessRecord, Integer>>() {
15345            @Override
15346            public int compare(Pair<ProcessRecord, Integer> object1,
15347                    Pair<ProcessRecord, Integer> object2) {
15348                if (object1.first.setAdj != object2.first.setAdj) {
15349                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15350                }
15351                if (object1.first.setProcState != object2.first.setProcState) {
15352                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15353                }
15354                if (object1.second.intValue() != object2.second.intValue()) {
15355                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15356                }
15357                return 0;
15358            }
15359        };
15360
15361        Collections.sort(list, comparator);
15362
15363        final long curRealtime = SystemClock.elapsedRealtime();
15364        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15365        final long curUptime = SystemClock.uptimeMillis();
15366        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15367
15368        for (int i=list.size()-1; i>=0; i--) {
15369            ProcessRecord r = list.get(i).first;
15370            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15371            char schedGroup;
15372            switch (r.setSchedGroup) {
15373                case ProcessList.SCHED_GROUP_BACKGROUND:
15374                    schedGroup = 'B';
15375                    break;
15376                case ProcessList.SCHED_GROUP_DEFAULT:
15377                    schedGroup = 'F';
15378                    break;
15379                case ProcessList.SCHED_GROUP_TOP_APP:
15380                    schedGroup = 'T';
15381                    break;
15382                default:
15383                    schedGroup = '?';
15384                    break;
15385            }
15386            char foreground;
15387            if (r.foregroundActivities) {
15388                foreground = 'A';
15389            } else if (r.foregroundServices) {
15390                foreground = 'S';
15391            } else {
15392                foreground = ' ';
15393            }
15394            String procState = ProcessList.makeProcStateString(r.curProcState);
15395            pw.print(prefix);
15396            pw.print(r.persistent ? persistentLabel : normalLabel);
15397            pw.print(" #");
15398            int num = (origList.size()-1)-list.get(i).second;
15399            if (num < 10) pw.print(' ');
15400            pw.print(num);
15401            pw.print(": ");
15402            pw.print(oomAdj);
15403            pw.print(' ');
15404            pw.print(schedGroup);
15405            pw.print('/');
15406            pw.print(foreground);
15407            pw.print('/');
15408            pw.print(procState);
15409            pw.print(" trm:");
15410            if (r.trimMemoryLevel < 10) pw.print(' ');
15411            pw.print(r.trimMemoryLevel);
15412            pw.print(' ');
15413            pw.print(r.toShortString());
15414            pw.print(" (");
15415            pw.print(r.adjType);
15416            pw.println(')');
15417            if (r.adjSource != null || r.adjTarget != null) {
15418                pw.print(prefix);
15419                pw.print("    ");
15420                if (r.adjTarget instanceof ComponentName) {
15421                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15422                } else if (r.adjTarget != null) {
15423                    pw.print(r.adjTarget.toString());
15424                } else {
15425                    pw.print("{null}");
15426                }
15427                pw.print("<=");
15428                if (r.adjSource instanceof ProcessRecord) {
15429                    pw.print("Proc{");
15430                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15431                    pw.println("}");
15432                } else if (r.adjSource != null) {
15433                    pw.println(r.adjSource.toString());
15434                } else {
15435                    pw.println("{null}");
15436                }
15437            }
15438            if (inclDetails) {
15439                pw.print(prefix);
15440                pw.print("    ");
15441                pw.print("oom: max="); pw.print(r.maxAdj);
15442                pw.print(" curRaw="); pw.print(r.curRawAdj);
15443                pw.print(" setRaw="); pw.print(r.setRawAdj);
15444                pw.print(" cur="); pw.print(r.curAdj);
15445                pw.print(" set="); pw.println(r.setAdj);
15446                pw.print(prefix);
15447                pw.print("    ");
15448                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15449                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15450                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15451                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15452                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15453                pw.println();
15454                pw.print(prefix);
15455                pw.print("    ");
15456                pw.print("cached="); pw.print(r.cached);
15457                pw.print(" empty="); pw.print(r.empty);
15458                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15459
15460                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15461                    if (r.lastWakeTime != 0) {
15462                        long wtime;
15463                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15464                        synchronized (stats) {
15465                            wtime = stats.getProcessWakeTime(r.info.uid,
15466                                    r.pid, curRealtime);
15467                        }
15468                        long timeUsed = wtime - r.lastWakeTime;
15469                        pw.print(prefix);
15470                        pw.print("    ");
15471                        pw.print("keep awake over ");
15472                        TimeUtils.formatDuration(realtimeSince, pw);
15473                        pw.print(" used ");
15474                        TimeUtils.formatDuration(timeUsed, pw);
15475                        pw.print(" (");
15476                        pw.print((timeUsed*100)/realtimeSince);
15477                        pw.println("%)");
15478                    }
15479                    if (r.lastCpuTime != 0) {
15480                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15481                        pw.print(prefix);
15482                        pw.print("    ");
15483                        pw.print("run cpu over ");
15484                        TimeUtils.formatDuration(uptimeSince, pw);
15485                        pw.print(" used ");
15486                        TimeUtils.formatDuration(timeUsed, pw);
15487                        pw.print(" (");
15488                        pw.print((timeUsed*100)/uptimeSince);
15489                        pw.println("%)");
15490                    }
15491                }
15492            }
15493        }
15494        return true;
15495    }
15496
15497    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15498            String[] args) {
15499        ArrayList<ProcessRecord> procs;
15500        synchronized (this) {
15501            if (args != null && args.length > start
15502                    && args[start].charAt(0) != '-') {
15503                procs = new ArrayList<ProcessRecord>();
15504                int pid = -1;
15505                try {
15506                    pid = Integer.parseInt(args[start]);
15507                } catch (NumberFormatException e) {
15508                }
15509                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15510                    ProcessRecord proc = mLruProcesses.get(i);
15511                    if (proc.pid == pid) {
15512                        procs.add(proc);
15513                    } else if (allPkgs && proc.pkgList != null
15514                            && proc.pkgList.containsKey(args[start])) {
15515                        procs.add(proc);
15516                    } else if (proc.processName.equals(args[start])) {
15517                        procs.add(proc);
15518                    }
15519                }
15520                if (procs.size() <= 0) {
15521                    return null;
15522                }
15523            } else {
15524                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15525            }
15526        }
15527        return procs;
15528    }
15529
15530    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15531            PrintWriter pw, String[] args) {
15532        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15533        if (procs == null) {
15534            pw.println("No process found for: " + args[0]);
15535            return;
15536        }
15537
15538        long uptime = SystemClock.uptimeMillis();
15539        long realtime = SystemClock.elapsedRealtime();
15540        pw.println("Applications Graphics Acceleration Info:");
15541        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15542
15543        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15544            ProcessRecord r = procs.get(i);
15545            if (r.thread != null) {
15546                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15547                pw.flush();
15548                try {
15549                    TransferPipe tp = new TransferPipe();
15550                    try {
15551                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15552                        tp.go(fd);
15553                    } finally {
15554                        tp.kill();
15555                    }
15556                } catch (IOException e) {
15557                    pw.println("Failure while dumping the app: " + r);
15558                    pw.flush();
15559                } catch (RemoteException e) {
15560                    pw.println("Got a RemoteException while dumping the app " + r);
15561                    pw.flush();
15562                }
15563            }
15564        }
15565    }
15566
15567    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15568        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15569        if (procs == null) {
15570            pw.println("No process found for: " + args[0]);
15571            return;
15572        }
15573
15574        pw.println("Applications Database Info:");
15575
15576        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15577            ProcessRecord r = procs.get(i);
15578            if (r.thread != null) {
15579                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15580                pw.flush();
15581                try {
15582                    TransferPipe tp = new TransferPipe();
15583                    try {
15584                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15585                        tp.go(fd);
15586                    } finally {
15587                        tp.kill();
15588                    }
15589                } catch (IOException e) {
15590                    pw.println("Failure while dumping the app: " + r);
15591                    pw.flush();
15592                } catch (RemoteException e) {
15593                    pw.println("Got a RemoteException while dumping the app " + r);
15594                    pw.flush();
15595                }
15596            }
15597        }
15598    }
15599
15600    final static class MemItem {
15601        final boolean isProc;
15602        final String label;
15603        final String shortLabel;
15604        final long pss;
15605        final long swapPss;
15606        final int id;
15607        final boolean hasActivities;
15608        ArrayList<MemItem> subitems;
15609
15610        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15611                boolean _hasActivities) {
15612            isProc = true;
15613            label = _label;
15614            shortLabel = _shortLabel;
15615            pss = _pss;
15616            swapPss = _swapPss;
15617            id = _id;
15618            hasActivities = _hasActivities;
15619        }
15620
15621        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15622            isProc = false;
15623            label = _label;
15624            shortLabel = _shortLabel;
15625            pss = _pss;
15626            swapPss = _swapPss;
15627            id = _id;
15628            hasActivities = false;
15629        }
15630    }
15631
15632    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15633            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15634        if (sort && !isCompact) {
15635            Collections.sort(items, new Comparator<MemItem>() {
15636                @Override
15637                public int compare(MemItem lhs, MemItem rhs) {
15638                    if (lhs.pss < rhs.pss) {
15639                        return 1;
15640                    } else if (lhs.pss > rhs.pss) {
15641                        return -1;
15642                    }
15643                    return 0;
15644                }
15645            });
15646        }
15647
15648        for (int i=0; i<items.size(); i++) {
15649            MemItem mi = items.get(i);
15650            if (!isCompact) {
15651                if (dumpSwapPss) {
15652                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15653                            mi.label, stringifyKBSize(mi.swapPss));
15654                } else {
15655                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15656                }
15657            } else if (mi.isProc) {
15658                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15659                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15660                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15661                pw.println(mi.hasActivities ? ",a" : ",e");
15662            } else {
15663                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15664                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15665            }
15666            if (mi.subitems != null) {
15667                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15668                        true, isCompact, dumpSwapPss);
15669            }
15670        }
15671    }
15672
15673    // These are in KB.
15674    static final long[] DUMP_MEM_BUCKETS = new long[] {
15675        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15676        120*1024, 160*1024, 200*1024,
15677        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15678        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15679    };
15680
15681    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15682            boolean stackLike) {
15683        int start = label.lastIndexOf('.');
15684        if (start >= 0) start++;
15685        else start = 0;
15686        int end = label.length();
15687        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15688            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15689                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15690                out.append(bucket);
15691                out.append(stackLike ? "MB." : "MB ");
15692                out.append(label, start, end);
15693                return;
15694            }
15695        }
15696        out.append(memKB/1024);
15697        out.append(stackLike ? "MB." : "MB ");
15698        out.append(label, start, end);
15699    }
15700
15701    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15702            ProcessList.NATIVE_ADJ,
15703            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15704            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15705            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15706            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15707            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15708            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15709    };
15710    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15711            "Native",
15712            "System", "Persistent", "Persistent Service", "Foreground",
15713            "Visible", "Perceptible",
15714            "Heavy Weight", "Backup",
15715            "A Services", "Home",
15716            "Previous", "B Services", "Cached"
15717    };
15718    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15719            "native",
15720            "sys", "pers", "persvc", "fore",
15721            "vis", "percept",
15722            "heavy", "backup",
15723            "servicea", "home",
15724            "prev", "serviceb", "cached"
15725    };
15726
15727    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15728            long realtime, boolean isCheckinRequest, boolean isCompact) {
15729        if (isCompact) {
15730            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15731        }
15732        if (isCheckinRequest || isCompact) {
15733            // short checkin version
15734            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15735        } else {
15736            pw.println("Applications Memory Usage (in Kilobytes):");
15737            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15738        }
15739    }
15740
15741    private static final int KSM_SHARED = 0;
15742    private static final int KSM_SHARING = 1;
15743    private static final int KSM_UNSHARED = 2;
15744    private static final int KSM_VOLATILE = 3;
15745
15746    private final long[] getKsmInfo() {
15747        long[] longOut = new long[4];
15748        final int[] SINGLE_LONG_FORMAT = new int[] {
15749            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15750        };
15751        long[] longTmp = new long[1];
15752        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15753                SINGLE_LONG_FORMAT, null, longTmp, null);
15754        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15755        longTmp[0] = 0;
15756        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15757                SINGLE_LONG_FORMAT, null, longTmp, null);
15758        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15759        longTmp[0] = 0;
15760        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15761                SINGLE_LONG_FORMAT, null, longTmp, null);
15762        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15763        longTmp[0] = 0;
15764        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15765                SINGLE_LONG_FORMAT, null, longTmp, null);
15766        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15767        return longOut;
15768    }
15769
15770    private static String stringifySize(long size, int order) {
15771        Locale locale = Locale.US;
15772        switch (order) {
15773            case 1:
15774                return String.format(locale, "%,13d", size);
15775            case 1024:
15776                return String.format(locale, "%,9dK", size / 1024);
15777            case 1024 * 1024:
15778                return String.format(locale, "%,5dM", size / 1024 / 1024);
15779            case 1024 * 1024 * 1024:
15780                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15781            default:
15782                throw new IllegalArgumentException("Invalid size order");
15783        }
15784    }
15785
15786    private static String stringifyKBSize(long size) {
15787        return stringifySize(size * 1024, 1024);
15788    }
15789
15790    // Update this version number in case you change the 'compact' format
15791    private static final int MEMINFO_COMPACT_VERSION = 1;
15792
15793    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15794            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15795        boolean dumpDetails = false;
15796        boolean dumpFullDetails = false;
15797        boolean dumpDalvik = false;
15798        boolean dumpSummaryOnly = false;
15799        boolean dumpUnreachable = false;
15800        boolean oomOnly = false;
15801        boolean isCompact = false;
15802        boolean localOnly = false;
15803        boolean packages = false;
15804        boolean isCheckinRequest = false;
15805        boolean dumpSwapPss = false;
15806
15807        int opti = 0;
15808        while (opti < args.length) {
15809            String opt = args[opti];
15810            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15811                break;
15812            }
15813            opti++;
15814            if ("-a".equals(opt)) {
15815                dumpDetails = true;
15816                dumpFullDetails = true;
15817                dumpDalvik = true;
15818                dumpSwapPss = true;
15819            } else if ("-d".equals(opt)) {
15820                dumpDalvik = true;
15821            } else if ("-c".equals(opt)) {
15822                isCompact = true;
15823            } else if ("-s".equals(opt)) {
15824                dumpDetails = true;
15825                dumpSummaryOnly = true;
15826            } else if ("-S".equals(opt)) {
15827                dumpSwapPss = true;
15828            } else if ("--unreachable".equals(opt)) {
15829                dumpUnreachable = true;
15830            } else if ("--oom".equals(opt)) {
15831                oomOnly = true;
15832            } else if ("--local".equals(opt)) {
15833                localOnly = true;
15834            } else if ("--package".equals(opt)) {
15835                packages = true;
15836            } else if ("--checkin".equals(opt)) {
15837                isCheckinRequest = true;
15838
15839            } else if ("-h".equals(opt)) {
15840                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15841                pw.println("  -a: include all available information for each process.");
15842                pw.println("  -d: include dalvik details.");
15843                pw.println("  -c: dump in a compact machine-parseable representation.");
15844                pw.println("  -s: dump only summary of application memory usage.");
15845                pw.println("  -S: dump also SwapPss.");
15846                pw.println("  --oom: only show processes organized by oom adj.");
15847                pw.println("  --local: only collect details locally, don't call process.");
15848                pw.println("  --package: interpret process arg as package, dumping all");
15849                pw.println("             processes that have loaded that package.");
15850                pw.println("  --checkin: dump data for a checkin");
15851                pw.println("If [process] is specified it can be the name or ");
15852                pw.println("pid of a specific process to dump.");
15853                return;
15854            } else {
15855                pw.println("Unknown argument: " + opt + "; use -h for help");
15856            }
15857        }
15858
15859        long uptime = SystemClock.uptimeMillis();
15860        long realtime = SystemClock.elapsedRealtime();
15861        final long[] tmpLong = new long[1];
15862
15863        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15864        if (procs == null) {
15865            // No Java processes.  Maybe they want to print a native process.
15866            if (args != null && args.length > opti
15867                    && args[opti].charAt(0) != '-') {
15868                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15869                        = new ArrayList<ProcessCpuTracker.Stats>();
15870                updateCpuStatsNow();
15871                int findPid = -1;
15872                try {
15873                    findPid = Integer.parseInt(args[opti]);
15874                } catch (NumberFormatException e) {
15875                }
15876                synchronized (mProcessCpuTracker) {
15877                    final int N = mProcessCpuTracker.countStats();
15878                    for (int i=0; i<N; i++) {
15879                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15880                        if (st.pid == findPid || (st.baseName != null
15881                                && st.baseName.equals(args[opti]))) {
15882                            nativeProcs.add(st);
15883                        }
15884                    }
15885                }
15886                if (nativeProcs.size() > 0) {
15887                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15888                            isCompact);
15889                    Debug.MemoryInfo mi = null;
15890                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15891                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15892                        final int pid = r.pid;
15893                        if (!isCheckinRequest && dumpDetails) {
15894                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15895                        }
15896                        if (mi == null) {
15897                            mi = new Debug.MemoryInfo();
15898                        }
15899                        if (dumpDetails || (!brief && !oomOnly)) {
15900                            Debug.getMemoryInfo(pid, mi);
15901                        } else {
15902                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15903                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15904                        }
15905                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15906                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15907                        if (isCheckinRequest) {
15908                            pw.println();
15909                        }
15910                    }
15911                    return;
15912                }
15913            }
15914            pw.println("No process found for: " + args[opti]);
15915            return;
15916        }
15917
15918        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15919            dumpDetails = true;
15920        }
15921
15922        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15923
15924        String[] innerArgs = new String[args.length-opti];
15925        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15926
15927        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15928        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15929        long nativePss = 0;
15930        long nativeSwapPss = 0;
15931        long dalvikPss = 0;
15932        long dalvikSwapPss = 0;
15933        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15934                EmptyArray.LONG;
15935        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15936                EmptyArray.LONG;
15937        long otherPss = 0;
15938        long otherSwapPss = 0;
15939        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15940        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15941
15942        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15943        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15944        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15945                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15946
15947        long totalPss = 0;
15948        long totalSwapPss = 0;
15949        long cachedPss = 0;
15950        long cachedSwapPss = 0;
15951        boolean hasSwapPss = false;
15952
15953        Debug.MemoryInfo mi = null;
15954        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15955            final ProcessRecord r = procs.get(i);
15956            final IApplicationThread thread;
15957            final int pid;
15958            final int oomAdj;
15959            final boolean hasActivities;
15960            synchronized (this) {
15961                thread = r.thread;
15962                pid = r.pid;
15963                oomAdj = r.getSetAdjWithServices();
15964                hasActivities = r.activities.size() > 0;
15965            }
15966            if (thread != null) {
15967                if (!isCheckinRequest && dumpDetails) {
15968                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15969                }
15970                if (mi == null) {
15971                    mi = new Debug.MemoryInfo();
15972                }
15973                if (dumpDetails || (!brief && !oomOnly)) {
15974                    Debug.getMemoryInfo(pid, mi);
15975                    hasSwapPss = mi.hasSwappedOutPss;
15976                } else {
15977                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15978                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15979                }
15980                if (dumpDetails) {
15981                    if (localOnly) {
15982                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15983                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15984                        if (isCheckinRequest) {
15985                            pw.println();
15986                        }
15987                    } else {
15988                        try {
15989                            pw.flush();
15990                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15991                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15992                        } catch (RemoteException e) {
15993                            if (!isCheckinRequest) {
15994                                pw.println("Got RemoteException!");
15995                                pw.flush();
15996                            }
15997                        }
15998                    }
15999                }
16000
16001                final long myTotalPss = mi.getTotalPss();
16002                final long myTotalUss = mi.getTotalUss();
16003                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16004
16005                synchronized (this) {
16006                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16007                        // Record this for posterity if the process has been stable.
16008                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16009                    }
16010                }
16011
16012                if (!isCheckinRequest && mi != null) {
16013                    totalPss += myTotalPss;
16014                    totalSwapPss += myTotalSwapPss;
16015                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16016                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16017                            myTotalSwapPss, pid, hasActivities);
16018                    procMems.add(pssItem);
16019                    procMemsMap.put(pid, pssItem);
16020
16021                    nativePss += mi.nativePss;
16022                    nativeSwapPss += mi.nativeSwappedOutPss;
16023                    dalvikPss += mi.dalvikPss;
16024                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16025                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16026                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16027                        dalvikSubitemSwapPss[j] +=
16028                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16029                    }
16030                    otherPss += mi.otherPss;
16031                    otherSwapPss += mi.otherSwappedOutPss;
16032                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16033                        long mem = mi.getOtherPss(j);
16034                        miscPss[j] += mem;
16035                        otherPss -= mem;
16036                        mem = mi.getOtherSwappedOutPss(j);
16037                        miscSwapPss[j] += mem;
16038                        otherSwapPss -= mem;
16039                    }
16040
16041                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16042                        cachedPss += myTotalPss;
16043                        cachedSwapPss += myTotalSwapPss;
16044                    }
16045
16046                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16047                        if (oomIndex == (oomPss.length - 1)
16048                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16049                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16050                            oomPss[oomIndex] += myTotalPss;
16051                            oomSwapPss[oomIndex] += myTotalSwapPss;
16052                            if (oomProcs[oomIndex] == null) {
16053                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16054                            }
16055                            oomProcs[oomIndex].add(pssItem);
16056                            break;
16057                        }
16058                    }
16059                }
16060            }
16061        }
16062
16063        long nativeProcTotalPss = 0;
16064
16065        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16066            // If we are showing aggregations, also look for native processes to
16067            // include so that our aggregations are more accurate.
16068            updateCpuStatsNow();
16069            mi = null;
16070            synchronized (mProcessCpuTracker) {
16071                final int N = mProcessCpuTracker.countStats();
16072                for (int i=0; i<N; i++) {
16073                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16074                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16075                        if (mi == null) {
16076                            mi = new Debug.MemoryInfo();
16077                        }
16078                        if (!brief && !oomOnly) {
16079                            Debug.getMemoryInfo(st.pid, mi);
16080                        } else {
16081                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16082                            mi.nativePrivateDirty = (int)tmpLong[0];
16083                        }
16084
16085                        final long myTotalPss = mi.getTotalPss();
16086                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16087                        totalPss += myTotalPss;
16088                        nativeProcTotalPss += myTotalPss;
16089
16090                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16091                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16092                        procMems.add(pssItem);
16093
16094                        nativePss += mi.nativePss;
16095                        nativeSwapPss += mi.nativeSwappedOutPss;
16096                        dalvikPss += mi.dalvikPss;
16097                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16098                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16099                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16100                            dalvikSubitemSwapPss[j] +=
16101                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16102                        }
16103                        otherPss += mi.otherPss;
16104                        otherSwapPss += mi.otherSwappedOutPss;
16105                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16106                            long mem = mi.getOtherPss(j);
16107                            miscPss[j] += mem;
16108                            otherPss -= mem;
16109                            mem = mi.getOtherSwappedOutPss(j);
16110                            miscSwapPss[j] += mem;
16111                            otherSwapPss -= mem;
16112                        }
16113                        oomPss[0] += myTotalPss;
16114                        oomSwapPss[0] += myTotalSwapPss;
16115                        if (oomProcs[0] == null) {
16116                            oomProcs[0] = new ArrayList<MemItem>();
16117                        }
16118                        oomProcs[0].add(pssItem);
16119                    }
16120                }
16121            }
16122
16123            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16124
16125            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16126            final MemItem dalvikItem =
16127                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16128            if (dalvikSubitemPss.length > 0) {
16129                dalvikItem.subitems = new ArrayList<MemItem>();
16130                for (int j=0; j<dalvikSubitemPss.length; j++) {
16131                    final String name = Debug.MemoryInfo.getOtherLabel(
16132                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16133                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16134                                    dalvikSubitemSwapPss[j], j));
16135                }
16136            }
16137            catMems.add(dalvikItem);
16138            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16139            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16140                String label = Debug.MemoryInfo.getOtherLabel(j);
16141                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16142            }
16143
16144            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16145            for (int j=0; j<oomPss.length; j++) {
16146                if (oomPss[j] != 0) {
16147                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16148                            : DUMP_MEM_OOM_LABEL[j];
16149                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16150                            DUMP_MEM_OOM_ADJ[j]);
16151                    item.subitems = oomProcs[j];
16152                    oomMems.add(item);
16153                }
16154            }
16155
16156            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16157            if (!brief && !oomOnly && !isCompact) {
16158                pw.println();
16159                pw.println("Total PSS by process:");
16160                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16161                pw.println();
16162            }
16163            if (!isCompact) {
16164                pw.println("Total PSS by OOM adjustment:");
16165            }
16166            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16167            if (!brief && !oomOnly) {
16168                PrintWriter out = categoryPw != null ? categoryPw : pw;
16169                if (!isCompact) {
16170                    out.println();
16171                    out.println("Total PSS by category:");
16172                }
16173                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16174            }
16175            if (!isCompact) {
16176                pw.println();
16177            }
16178            MemInfoReader memInfo = new MemInfoReader();
16179            memInfo.readMemInfo();
16180            if (nativeProcTotalPss > 0) {
16181                synchronized (this) {
16182                    final long cachedKb = memInfo.getCachedSizeKb();
16183                    final long freeKb = memInfo.getFreeSizeKb();
16184                    final long zramKb = memInfo.getZramTotalSizeKb();
16185                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16186                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16187                            kernelKb*1024, nativeProcTotalPss*1024);
16188                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16189                            nativeProcTotalPss);
16190                }
16191            }
16192            if (!brief) {
16193                if (!isCompact) {
16194                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16195                    pw.print(" (status ");
16196                    switch (mLastMemoryLevel) {
16197                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16198                            pw.println("normal)");
16199                            break;
16200                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16201                            pw.println("moderate)");
16202                            break;
16203                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16204                            pw.println("low)");
16205                            break;
16206                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16207                            pw.println("critical)");
16208                            break;
16209                        default:
16210                            pw.print(mLastMemoryLevel);
16211                            pw.println(")");
16212                            break;
16213                    }
16214                    pw.print(" Free RAM: ");
16215                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16216                            + memInfo.getFreeSizeKb()));
16217                    pw.print(" (");
16218                    pw.print(stringifyKBSize(cachedPss));
16219                    pw.print(" cached pss + ");
16220                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16221                    pw.print(" cached kernel + ");
16222                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16223                    pw.println(" free)");
16224                } else {
16225                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16226                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16227                            + memInfo.getFreeSizeKb()); pw.print(",");
16228                    pw.println(totalPss - cachedPss);
16229                }
16230            }
16231            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16232                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16233                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16234            if (!isCompact) {
16235                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16236                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16237                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16238                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16239                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16240            } else {
16241                pw.print("lostram,"); pw.println(lostRAM);
16242            }
16243            if (!brief) {
16244                if (memInfo.getZramTotalSizeKb() != 0) {
16245                    if (!isCompact) {
16246                        pw.print("     ZRAM: ");
16247                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16248                                pw.print(" physical used for ");
16249                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16250                                        - memInfo.getSwapFreeSizeKb()));
16251                                pw.print(" in swap (");
16252                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16253                                pw.println(" total swap)");
16254                    } else {
16255                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16256                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16257                                pw.println(memInfo.getSwapFreeSizeKb());
16258                    }
16259                }
16260                final long[] ksm = getKsmInfo();
16261                if (!isCompact) {
16262                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16263                            || ksm[KSM_VOLATILE] != 0) {
16264                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16265                                pw.print(" saved from shared ");
16266                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16267                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16268                                pw.print(" unshared; ");
16269                                pw.print(stringifyKBSize(
16270                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16271                    }
16272                    pw.print("   Tuning: ");
16273                    pw.print(ActivityManager.staticGetMemoryClass());
16274                    pw.print(" (large ");
16275                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16276                    pw.print("), oom ");
16277                    pw.print(stringifySize(
16278                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16279                    pw.print(", restore limit ");
16280                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16281                    if (ActivityManager.isLowRamDeviceStatic()) {
16282                        pw.print(" (low-ram)");
16283                    }
16284                    if (ActivityManager.isHighEndGfx()) {
16285                        pw.print(" (high-end-gfx)");
16286                    }
16287                    pw.println();
16288                } else {
16289                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16290                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16291                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16292                    pw.print("tuning,");
16293                    pw.print(ActivityManager.staticGetMemoryClass());
16294                    pw.print(',');
16295                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16296                    pw.print(',');
16297                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16298                    if (ActivityManager.isLowRamDeviceStatic()) {
16299                        pw.print(",low-ram");
16300                    }
16301                    if (ActivityManager.isHighEndGfx()) {
16302                        pw.print(",high-end-gfx");
16303                    }
16304                    pw.println();
16305                }
16306            }
16307        }
16308    }
16309
16310    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16311            long memtrack, String name) {
16312        sb.append("  ");
16313        sb.append(ProcessList.makeOomAdjString(oomAdj));
16314        sb.append(' ');
16315        sb.append(ProcessList.makeProcStateString(procState));
16316        sb.append(' ');
16317        ProcessList.appendRamKb(sb, pss);
16318        sb.append(": ");
16319        sb.append(name);
16320        if (memtrack > 0) {
16321            sb.append(" (");
16322            sb.append(stringifyKBSize(memtrack));
16323            sb.append(" memtrack)");
16324        }
16325    }
16326
16327    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16328        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16329        sb.append(" (pid ");
16330        sb.append(mi.pid);
16331        sb.append(") ");
16332        sb.append(mi.adjType);
16333        sb.append('\n');
16334        if (mi.adjReason != null) {
16335            sb.append("                      ");
16336            sb.append(mi.adjReason);
16337            sb.append('\n');
16338        }
16339    }
16340
16341    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16342        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16343        for (int i=0, N=memInfos.size(); i<N; i++) {
16344            ProcessMemInfo mi = memInfos.get(i);
16345            infoMap.put(mi.pid, mi);
16346        }
16347        updateCpuStatsNow();
16348        long[] memtrackTmp = new long[1];
16349        synchronized (mProcessCpuTracker) {
16350            final int N = mProcessCpuTracker.countStats();
16351            for (int i=0; i<N; i++) {
16352                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16353                if (st.vsize > 0) {
16354                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16355                    if (pss > 0) {
16356                        if (infoMap.indexOfKey(st.pid) < 0) {
16357                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16358                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16359                            mi.pss = pss;
16360                            mi.memtrack = memtrackTmp[0];
16361                            memInfos.add(mi);
16362                        }
16363                    }
16364                }
16365            }
16366        }
16367
16368        long totalPss = 0;
16369        long totalMemtrack = 0;
16370        for (int i=0, N=memInfos.size(); i<N; i++) {
16371            ProcessMemInfo mi = memInfos.get(i);
16372            if (mi.pss == 0) {
16373                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16374                mi.memtrack = memtrackTmp[0];
16375            }
16376            totalPss += mi.pss;
16377            totalMemtrack += mi.memtrack;
16378        }
16379        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16380            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16381                if (lhs.oomAdj != rhs.oomAdj) {
16382                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16383                }
16384                if (lhs.pss != rhs.pss) {
16385                    return lhs.pss < rhs.pss ? 1 : -1;
16386                }
16387                return 0;
16388            }
16389        });
16390
16391        StringBuilder tag = new StringBuilder(128);
16392        StringBuilder stack = new StringBuilder(128);
16393        tag.append("Low on memory -- ");
16394        appendMemBucket(tag, totalPss, "total", false);
16395        appendMemBucket(stack, totalPss, "total", true);
16396
16397        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16398        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16399        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16400
16401        boolean firstLine = true;
16402        int lastOomAdj = Integer.MIN_VALUE;
16403        long extraNativeRam = 0;
16404        long extraNativeMemtrack = 0;
16405        long cachedPss = 0;
16406        for (int i=0, N=memInfos.size(); i<N; i++) {
16407            ProcessMemInfo mi = memInfos.get(i);
16408
16409            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16410                cachedPss += mi.pss;
16411            }
16412
16413            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16414                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16415                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16416                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16417                if (lastOomAdj != mi.oomAdj) {
16418                    lastOomAdj = mi.oomAdj;
16419                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16420                        tag.append(" / ");
16421                    }
16422                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16423                        if (firstLine) {
16424                            stack.append(":");
16425                            firstLine = false;
16426                        }
16427                        stack.append("\n\t at ");
16428                    } else {
16429                        stack.append("$");
16430                    }
16431                } else {
16432                    tag.append(" ");
16433                    stack.append("$");
16434                }
16435                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16436                    appendMemBucket(tag, mi.pss, mi.name, false);
16437                }
16438                appendMemBucket(stack, mi.pss, mi.name, true);
16439                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16440                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16441                    stack.append("(");
16442                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16443                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16444                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16445                            stack.append(":");
16446                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16447                        }
16448                    }
16449                    stack.append(")");
16450                }
16451            }
16452
16453            appendMemInfo(fullNativeBuilder, mi);
16454            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16455                // The short form only has native processes that are >= 512K.
16456                if (mi.pss >= 512) {
16457                    appendMemInfo(shortNativeBuilder, mi);
16458                } else {
16459                    extraNativeRam += mi.pss;
16460                    extraNativeMemtrack += mi.memtrack;
16461                }
16462            } else {
16463                // Short form has all other details, but if we have collected RAM
16464                // from smaller native processes let's dump a summary of that.
16465                if (extraNativeRam > 0) {
16466                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16467                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16468                    shortNativeBuilder.append('\n');
16469                    extraNativeRam = 0;
16470                }
16471                appendMemInfo(fullJavaBuilder, mi);
16472            }
16473        }
16474
16475        fullJavaBuilder.append("           ");
16476        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16477        fullJavaBuilder.append(": TOTAL");
16478        if (totalMemtrack > 0) {
16479            fullJavaBuilder.append(" (");
16480            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16481            fullJavaBuilder.append(" memtrack)");
16482        } else {
16483        }
16484        fullJavaBuilder.append("\n");
16485
16486        MemInfoReader memInfo = new MemInfoReader();
16487        memInfo.readMemInfo();
16488        final long[] infos = memInfo.getRawInfo();
16489
16490        StringBuilder memInfoBuilder = new StringBuilder(1024);
16491        Debug.getMemInfo(infos);
16492        memInfoBuilder.append("  MemInfo: ");
16493        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16494        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16495        memInfoBuilder.append(stringifyKBSize(
16496                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16497        memInfoBuilder.append(stringifyKBSize(
16498                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16499        memInfoBuilder.append(stringifyKBSize(
16500                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16501        memInfoBuilder.append("           ");
16502        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16503        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16504        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16505        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16506        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16507            memInfoBuilder.append("  ZRAM: ");
16508            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16509            memInfoBuilder.append(" RAM, ");
16510            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16511            memInfoBuilder.append(" swap total, ");
16512            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16513            memInfoBuilder.append(" swap free\n");
16514        }
16515        final long[] ksm = getKsmInfo();
16516        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16517                || ksm[KSM_VOLATILE] != 0) {
16518            memInfoBuilder.append("  KSM: ");
16519            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16520            memInfoBuilder.append(" saved from shared ");
16521            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16522            memInfoBuilder.append("\n       ");
16523            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16524            memInfoBuilder.append(" unshared; ");
16525            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16526            memInfoBuilder.append(" volatile\n");
16527        }
16528        memInfoBuilder.append("  Free RAM: ");
16529        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16530                + memInfo.getFreeSizeKb()));
16531        memInfoBuilder.append("\n");
16532        memInfoBuilder.append("  Used RAM: ");
16533        memInfoBuilder.append(stringifyKBSize(
16534                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16535        memInfoBuilder.append("\n");
16536        memInfoBuilder.append("  Lost RAM: ");
16537        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16538                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16539                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16540        memInfoBuilder.append("\n");
16541        Slog.i(TAG, "Low on memory:");
16542        Slog.i(TAG, shortNativeBuilder.toString());
16543        Slog.i(TAG, fullJavaBuilder.toString());
16544        Slog.i(TAG, memInfoBuilder.toString());
16545
16546        StringBuilder dropBuilder = new StringBuilder(1024);
16547        /*
16548        StringWriter oomSw = new StringWriter();
16549        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16550        StringWriter catSw = new StringWriter();
16551        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16552        String[] emptyArgs = new String[] { };
16553        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16554        oomPw.flush();
16555        String oomString = oomSw.toString();
16556        */
16557        dropBuilder.append("Low on memory:");
16558        dropBuilder.append(stack);
16559        dropBuilder.append('\n');
16560        dropBuilder.append(fullNativeBuilder);
16561        dropBuilder.append(fullJavaBuilder);
16562        dropBuilder.append('\n');
16563        dropBuilder.append(memInfoBuilder);
16564        dropBuilder.append('\n');
16565        /*
16566        dropBuilder.append(oomString);
16567        dropBuilder.append('\n');
16568        */
16569        StringWriter catSw = new StringWriter();
16570        synchronized (ActivityManagerService.this) {
16571            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16572            String[] emptyArgs = new String[] { };
16573            catPw.println();
16574            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16575            catPw.println();
16576            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16577                    false, null).dumpLocked();
16578            catPw.println();
16579            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16580            catPw.flush();
16581        }
16582        dropBuilder.append(catSw.toString());
16583        addErrorToDropBox("lowmem", null, "system_server", null,
16584                null, tag.toString(), dropBuilder.toString(), null, null);
16585        //Slog.i(TAG, "Sent to dropbox:");
16586        //Slog.i(TAG, dropBuilder.toString());
16587        synchronized (ActivityManagerService.this) {
16588            long now = SystemClock.uptimeMillis();
16589            if (mLastMemUsageReportTime < now) {
16590                mLastMemUsageReportTime = now;
16591            }
16592        }
16593    }
16594
16595    /**
16596     * Searches array of arguments for the specified string
16597     * @param args array of argument strings
16598     * @param value value to search for
16599     * @return true if the value is contained in the array
16600     */
16601    private static boolean scanArgs(String[] args, String value) {
16602        if (args != null) {
16603            for (String arg : args) {
16604                if (value.equals(arg)) {
16605                    return true;
16606                }
16607            }
16608        }
16609        return false;
16610    }
16611
16612    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16613            ContentProviderRecord cpr, boolean always) {
16614        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16615
16616        if (!inLaunching || always) {
16617            synchronized (cpr) {
16618                cpr.launchingApp = null;
16619                cpr.notifyAll();
16620            }
16621            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16622            String names[] = cpr.info.authority.split(";");
16623            for (int j = 0; j < names.length; j++) {
16624                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16625            }
16626        }
16627
16628        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16629            ContentProviderConnection conn = cpr.connections.get(i);
16630            if (conn.waiting) {
16631                // If this connection is waiting for the provider, then we don't
16632                // need to mess with its process unless we are always removing
16633                // or for some reason the provider is not currently launching.
16634                if (inLaunching && !always) {
16635                    continue;
16636                }
16637            }
16638            ProcessRecord capp = conn.client;
16639            conn.dead = true;
16640            if (conn.stableCount > 0) {
16641                if (!capp.persistent && capp.thread != null
16642                        && capp.pid != 0
16643                        && capp.pid != MY_PID) {
16644                    capp.kill("depends on provider "
16645                            + cpr.name.flattenToShortString()
16646                            + " in dying proc " + (proc != null ? proc.processName : "??")
16647                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16648                }
16649            } else if (capp.thread != null && conn.provider.provider != null) {
16650                try {
16651                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16652                } catch (RemoteException e) {
16653                }
16654                // In the protocol here, we don't expect the client to correctly
16655                // clean up this connection, we'll just remove it.
16656                cpr.connections.remove(i);
16657                if (conn.client.conProviders.remove(conn)) {
16658                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16659                }
16660            }
16661        }
16662
16663        if (inLaunching && always) {
16664            mLaunchingProviders.remove(cpr);
16665        }
16666        return inLaunching;
16667    }
16668
16669    /**
16670     * Main code for cleaning up a process when it has gone away.  This is
16671     * called both as a result of the process dying, or directly when stopping
16672     * a process when running in single process mode.
16673     *
16674     * @return Returns true if the given process has been restarted, so the
16675     * app that was passed in must remain on the process lists.
16676     */
16677    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16678            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16679        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16680        if (index >= 0) {
16681            removeLruProcessLocked(app);
16682            ProcessList.remove(app.pid);
16683        }
16684
16685        mProcessesToGc.remove(app);
16686        mPendingPssProcesses.remove(app);
16687
16688        // Dismiss any open dialogs.
16689        if (app.crashDialog != null && !app.forceCrashReport) {
16690            app.crashDialog.dismiss();
16691            app.crashDialog = null;
16692        }
16693        if (app.anrDialog != null) {
16694            app.anrDialog.dismiss();
16695            app.anrDialog = null;
16696        }
16697        if (app.waitDialog != null) {
16698            app.waitDialog.dismiss();
16699            app.waitDialog = null;
16700        }
16701
16702        app.crashing = false;
16703        app.notResponding = false;
16704
16705        app.resetPackageList(mProcessStats);
16706        app.unlinkDeathRecipient();
16707        app.makeInactive(mProcessStats);
16708        app.waitingToKill = null;
16709        app.forcingToForeground = null;
16710        updateProcessForegroundLocked(app, false, false);
16711        app.foregroundActivities = false;
16712        app.hasShownUi = false;
16713        app.treatLikeActivity = false;
16714        app.hasAboveClient = false;
16715        app.hasClientActivities = false;
16716
16717        mServices.killServicesLocked(app, allowRestart);
16718
16719        boolean restart = false;
16720
16721        // Remove published content providers.
16722        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16723            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16724            final boolean always = app.bad || !allowRestart;
16725            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16726            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16727                // We left the provider in the launching list, need to
16728                // restart it.
16729                restart = true;
16730            }
16731
16732            cpr.provider = null;
16733            cpr.proc = null;
16734        }
16735        app.pubProviders.clear();
16736
16737        // Take care of any launching providers waiting for this process.
16738        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16739            restart = true;
16740        }
16741
16742        // Unregister from connected content providers.
16743        if (!app.conProviders.isEmpty()) {
16744            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16745                ContentProviderConnection conn = app.conProviders.get(i);
16746                conn.provider.connections.remove(conn);
16747                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16748                        conn.provider.name);
16749            }
16750            app.conProviders.clear();
16751        }
16752
16753        // At this point there may be remaining entries in mLaunchingProviders
16754        // where we were the only one waiting, so they are no longer of use.
16755        // Look for these and clean up if found.
16756        // XXX Commented out for now.  Trying to figure out a way to reproduce
16757        // the actual situation to identify what is actually going on.
16758        if (false) {
16759            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16760                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16761                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16762                    synchronized (cpr) {
16763                        cpr.launchingApp = null;
16764                        cpr.notifyAll();
16765                    }
16766                }
16767            }
16768        }
16769
16770        skipCurrentReceiverLocked(app);
16771
16772        // Unregister any receivers.
16773        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16774            removeReceiverLocked(app.receivers.valueAt(i));
16775        }
16776        app.receivers.clear();
16777
16778        // If the app is undergoing backup, tell the backup manager about it
16779        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16780            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16781                    + mBackupTarget.appInfo + " died during backup");
16782            try {
16783                IBackupManager bm = IBackupManager.Stub.asInterface(
16784                        ServiceManager.getService(Context.BACKUP_SERVICE));
16785                bm.agentDisconnected(app.info.packageName);
16786            } catch (RemoteException e) {
16787                // can't happen; backup manager is local
16788            }
16789        }
16790
16791        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16792            ProcessChangeItem item = mPendingProcessChanges.get(i);
16793            if (item.pid == app.pid) {
16794                mPendingProcessChanges.remove(i);
16795                mAvailProcessChanges.add(item);
16796            }
16797        }
16798        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16799                null).sendToTarget();
16800
16801        // If the caller is restarting this app, then leave it in its
16802        // current lists and let the caller take care of it.
16803        if (restarting) {
16804            return false;
16805        }
16806
16807        if (!app.persistent || app.isolated) {
16808            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16809                    "Removing non-persistent process during cleanup: " + app);
16810            if (!replacingPid) {
16811                removeProcessNameLocked(app.processName, app.uid);
16812            }
16813            if (mHeavyWeightProcess == app) {
16814                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16815                        mHeavyWeightProcess.userId, 0));
16816                mHeavyWeightProcess = null;
16817            }
16818        } else if (!app.removed) {
16819            // This app is persistent, so we need to keep its record around.
16820            // If it is not already on the pending app list, add it there
16821            // and start a new process for it.
16822            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16823                mPersistentStartingProcesses.add(app);
16824                restart = true;
16825            }
16826        }
16827        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16828                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16829        mProcessesOnHold.remove(app);
16830
16831        if (app == mHomeProcess) {
16832            mHomeProcess = null;
16833        }
16834        if (app == mPreviousProcess) {
16835            mPreviousProcess = null;
16836        }
16837
16838        if (restart && !app.isolated) {
16839            // We have components that still need to be running in the
16840            // process, so re-launch it.
16841            if (index < 0) {
16842                ProcessList.remove(app.pid);
16843            }
16844            addProcessNameLocked(app);
16845            startProcessLocked(app, "restart", app.processName);
16846            return true;
16847        } else if (app.pid > 0 && app.pid != MY_PID) {
16848            // Goodbye!
16849            boolean removed;
16850            synchronized (mPidsSelfLocked) {
16851                mPidsSelfLocked.remove(app.pid);
16852                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16853            }
16854            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16855            if (app.isolated) {
16856                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16857            }
16858            app.setPid(0);
16859        }
16860        return false;
16861    }
16862
16863    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16864        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16865            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16866            if (cpr.launchingApp == app) {
16867                return true;
16868            }
16869        }
16870        return false;
16871    }
16872
16873    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16874        // Look through the content providers we are waiting to have launched,
16875        // and if any run in this process then either schedule a restart of
16876        // the process or kill the client waiting for it if this process has
16877        // gone bad.
16878        boolean restart = false;
16879        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16880            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16881            if (cpr.launchingApp == app) {
16882                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16883                    restart = true;
16884                } else {
16885                    removeDyingProviderLocked(app, cpr, true);
16886                }
16887            }
16888        }
16889        return restart;
16890    }
16891
16892    // =========================================================
16893    // SERVICES
16894    // =========================================================
16895
16896    @Override
16897    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16898            int flags) {
16899        enforceNotIsolatedCaller("getServices");
16900        synchronized (this) {
16901            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16902        }
16903    }
16904
16905    @Override
16906    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16907        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16908        synchronized (this) {
16909            return mServices.getRunningServiceControlPanelLocked(name);
16910        }
16911    }
16912
16913    @Override
16914    public ComponentName startService(IApplicationThread caller, Intent service,
16915            String resolvedType, String callingPackage, int userId)
16916            throws TransactionTooLargeException {
16917        enforceNotIsolatedCaller("startService");
16918        // Refuse possible leaked file descriptors
16919        if (service != null && service.hasFileDescriptors() == true) {
16920            throw new IllegalArgumentException("File descriptors passed in Intent");
16921        }
16922
16923        if (callingPackage == null) {
16924            throw new IllegalArgumentException("callingPackage cannot be null");
16925        }
16926
16927        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16928                "startService: " + service + " type=" + resolvedType);
16929        synchronized(this) {
16930            final int callingPid = Binder.getCallingPid();
16931            final int callingUid = Binder.getCallingUid();
16932            final long origId = Binder.clearCallingIdentity();
16933            ComponentName res = mServices.startServiceLocked(caller, service,
16934                    resolvedType, callingPid, callingUid, callingPackage, userId);
16935            Binder.restoreCallingIdentity(origId);
16936            return res;
16937        }
16938    }
16939
16940    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16941            String callingPackage, int userId)
16942            throws TransactionTooLargeException {
16943        synchronized(this) {
16944            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16945                    "startServiceInPackage: " + service + " type=" + resolvedType);
16946            final long origId = Binder.clearCallingIdentity();
16947            ComponentName res = mServices.startServiceLocked(null, service,
16948                    resolvedType, -1, uid, callingPackage, userId);
16949            Binder.restoreCallingIdentity(origId);
16950            return res;
16951        }
16952    }
16953
16954    @Override
16955    public int stopService(IApplicationThread caller, Intent service,
16956            String resolvedType, int userId) {
16957        enforceNotIsolatedCaller("stopService");
16958        // Refuse possible leaked file descriptors
16959        if (service != null && service.hasFileDescriptors() == true) {
16960            throw new IllegalArgumentException("File descriptors passed in Intent");
16961        }
16962
16963        synchronized(this) {
16964            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16965        }
16966    }
16967
16968    @Override
16969    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16970        enforceNotIsolatedCaller("peekService");
16971        // Refuse possible leaked file descriptors
16972        if (service != null && service.hasFileDescriptors() == true) {
16973            throw new IllegalArgumentException("File descriptors passed in Intent");
16974        }
16975
16976        if (callingPackage == null) {
16977            throw new IllegalArgumentException("callingPackage cannot be null");
16978        }
16979
16980        synchronized(this) {
16981            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16982        }
16983    }
16984
16985    @Override
16986    public boolean stopServiceToken(ComponentName className, IBinder token,
16987            int startId) {
16988        synchronized(this) {
16989            return mServices.stopServiceTokenLocked(className, token, startId);
16990        }
16991    }
16992
16993    @Override
16994    public void setServiceForeground(ComponentName className, IBinder token,
16995            int id, Notification notification, int flags) {
16996        synchronized(this) {
16997            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16998        }
16999    }
17000
17001    @Override
17002    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17003            boolean requireFull, String name, String callerPackage) {
17004        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17005                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17006    }
17007
17008    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17009            String className, int flags) {
17010        boolean result = false;
17011        // For apps that don't have pre-defined UIDs, check for permission
17012        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17013            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17014                if (ActivityManager.checkUidPermission(
17015                        INTERACT_ACROSS_USERS,
17016                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17017                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17018                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17019                            + " requests FLAG_SINGLE_USER, but app does not hold "
17020                            + INTERACT_ACROSS_USERS;
17021                    Slog.w(TAG, msg);
17022                    throw new SecurityException(msg);
17023                }
17024                // Permission passed
17025                result = true;
17026            }
17027        } else if ("system".equals(componentProcessName)) {
17028            result = true;
17029        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17030            // Phone app and persistent apps are allowed to export singleuser providers.
17031            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17032                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17033        }
17034        if (DEBUG_MU) Slog.v(TAG_MU,
17035                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17036                + Integer.toHexString(flags) + ") = " + result);
17037        return result;
17038    }
17039
17040    /**
17041     * Checks to see if the caller is in the same app as the singleton
17042     * component, or the component is in a special app. It allows special apps
17043     * to export singleton components but prevents exporting singleton
17044     * components for regular apps.
17045     */
17046    boolean isValidSingletonCall(int callingUid, int componentUid) {
17047        int componentAppId = UserHandle.getAppId(componentUid);
17048        return UserHandle.isSameApp(callingUid, componentUid)
17049                || componentAppId == Process.SYSTEM_UID
17050                || componentAppId == Process.PHONE_UID
17051                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17052                        == PackageManager.PERMISSION_GRANTED;
17053    }
17054
17055    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17056            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17057            int userId) throws TransactionTooLargeException {
17058        enforceNotIsolatedCaller("bindService");
17059
17060        // Refuse possible leaked file descriptors
17061        if (service != null && service.hasFileDescriptors() == true) {
17062            throw new IllegalArgumentException("File descriptors passed in Intent");
17063        }
17064
17065        if (callingPackage == null) {
17066            throw new IllegalArgumentException("callingPackage cannot be null");
17067        }
17068
17069        synchronized(this) {
17070            return mServices.bindServiceLocked(caller, token, service,
17071                    resolvedType, connection, flags, callingPackage, userId);
17072        }
17073    }
17074
17075    public boolean unbindService(IServiceConnection connection) {
17076        synchronized (this) {
17077            return mServices.unbindServiceLocked(connection);
17078        }
17079    }
17080
17081    public void publishService(IBinder token, Intent intent, IBinder service) {
17082        // Refuse possible leaked file descriptors
17083        if (intent != null && intent.hasFileDescriptors() == true) {
17084            throw new IllegalArgumentException("File descriptors passed in Intent");
17085        }
17086
17087        synchronized(this) {
17088            if (!(token instanceof ServiceRecord)) {
17089                throw new IllegalArgumentException("Invalid service token");
17090            }
17091            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17092        }
17093    }
17094
17095    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17096        // Refuse possible leaked file descriptors
17097        if (intent != null && intent.hasFileDescriptors() == true) {
17098            throw new IllegalArgumentException("File descriptors passed in Intent");
17099        }
17100
17101        synchronized(this) {
17102            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17103        }
17104    }
17105
17106    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17107        synchronized(this) {
17108            if (!(token instanceof ServiceRecord)) {
17109                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17110                throw new IllegalArgumentException("Invalid service token");
17111            }
17112            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17113        }
17114    }
17115
17116    // =========================================================
17117    // BACKUP AND RESTORE
17118    // =========================================================
17119
17120    // Cause the target app to be launched if necessary and its backup agent
17121    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17122    // activity manager to announce its creation.
17123    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17124        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17125        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17126
17127        IPackageManager pm = AppGlobals.getPackageManager();
17128        ApplicationInfo app = null;
17129        try {
17130            app = pm.getApplicationInfo(packageName, 0, userId);
17131        } catch (RemoteException e) {
17132            // can't happen; package manager is process-local
17133        }
17134        if (app == null) {
17135            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17136            return false;
17137        }
17138
17139        synchronized(this) {
17140            // !!! TODO: currently no check here that we're already bound
17141            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17142            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17143            synchronized (stats) {
17144                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17145            }
17146
17147            // Backup agent is now in use, its package can't be stopped.
17148            try {
17149                AppGlobals.getPackageManager().setPackageStoppedState(
17150                        app.packageName, false, UserHandle.getUserId(app.uid));
17151            } catch (RemoteException e) {
17152            } catch (IllegalArgumentException e) {
17153                Slog.w(TAG, "Failed trying to unstop package "
17154                        + app.packageName + ": " + e);
17155            }
17156
17157            BackupRecord r = new BackupRecord(ss, app, backupMode);
17158            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17159                    ? new ComponentName(app.packageName, app.backupAgentName)
17160                    : new ComponentName("android", "FullBackupAgent");
17161            // startProcessLocked() returns existing proc's record if it's already running
17162            ProcessRecord proc = startProcessLocked(app.processName, app,
17163                    false, 0, "backup", hostingName, false, false, false);
17164            if (proc == null) {
17165                Slog.e(TAG, "Unable to start backup agent process " + r);
17166                return false;
17167            }
17168
17169            // If the app is a regular app (uid >= 10000) and not the system server or phone
17170            // process, etc, then mark it as being in full backup so that certain calls to the
17171            // process can be blocked. This is not reset to false anywhere because we kill the
17172            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17173            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17174                proc.inFullBackup = true;
17175            }
17176            r.app = proc;
17177            mBackupTarget = r;
17178            mBackupAppName = app.packageName;
17179
17180            // Try not to kill the process during backup
17181            updateOomAdjLocked(proc);
17182
17183            // If the process is already attached, schedule the creation of the backup agent now.
17184            // If it is not yet live, this will be done when it attaches to the framework.
17185            if (proc.thread != null) {
17186                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17187                try {
17188                    proc.thread.scheduleCreateBackupAgent(app,
17189                            compatibilityInfoForPackageLocked(app), backupMode);
17190                } catch (RemoteException e) {
17191                    // Will time out on the backup manager side
17192                }
17193            } else {
17194                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17195            }
17196            // Invariants: at this point, the target app process exists and the application
17197            // is either already running or in the process of coming up.  mBackupTarget and
17198            // mBackupAppName describe the app, so that when it binds back to the AM we
17199            // know that it's scheduled for a backup-agent operation.
17200        }
17201
17202        return true;
17203    }
17204
17205    @Override
17206    public void clearPendingBackup() {
17207        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17208        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17209
17210        synchronized (this) {
17211            mBackupTarget = null;
17212            mBackupAppName = null;
17213        }
17214    }
17215
17216    // A backup agent has just come up
17217    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17218        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17219                + " = " + agent);
17220
17221        synchronized(this) {
17222            if (!agentPackageName.equals(mBackupAppName)) {
17223                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17224                return;
17225            }
17226        }
17227
17228        long oldIdent = Binder.clearCallingIdentity();
17229        try {
17230            IBackupManager bm = IBackupManager.Stub.asInterface(
17231                    ServiceManager.getService(Context.BACKUP_SERVICE));
17232            bm.agentConnected(agentPackageName, agent);
17233        } catch (RemoteException e) {
17234            // can't happen; the backup manager service is local
17235        } catch (Exception e) {
17236            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17237            e.printStackTrace();
17238        } finally {
17239            Binder.restoreCallingIdentity(oldIdent);
17240        }
17241    }
17242
17243    // done with this agent
17244    public void unbindBackupAgent(ApplicationInfo appInfo) {
17245        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17246        if (appInfo == null) {
17247            Slog.w(TAG, "unbind backup agent for null app");
17248            return;
17249        }
17250
17251        synchronized(this) {
17252            try {
17253                if (mBackupAppName == null) {
17254                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17255                    return;
17256                }
17257
17258                if (!mBackupAppName.equals(appInfo.packageName)) {
17259                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17260                    return;
17261                }
17262
17263                // Not backing this app up any more; reset its OOM adjustment
17264                final ProcessRecord proc = mBackupTarget.app;
17265                updateOomAdjLocked(proc);
17266
17267                // If the app crashed during backup, 'thread' will be null here
17268                if (proc.thread != null) {
17269                    try {
17270                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17271                                compatibilityInfoForPackageLocked(appInfo));
17272                    } catch (Exception e) {
17273                        Slog.e(TAG, "Exception when unbinding backup agent:");
17274                        e.printStackTrace();
17275                    }
17276                }
17277            } finally {
17278                mBackupTarget = null;
17279                mBackupAppName = null;
17280            }
17281        }
17282    }
17283    // =========================================================
17284    // BROADCASTS
17285    // =========================================================
17286
17287    boolean isPendingBroadcastProcessLocked(int pid) {
17288        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17289                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17290    }
17291
17292    void skipPendingBroadcastLocked(int pid) {
17293            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17294            for (BroadcastQueue queue : mBroadcastQueues) {
17295                queue.skipPendingBroadcastLocked(pid);
17296            }
17297    }
17298
17299    // The app just attached; send any pending broadcasts that it should receive
17300    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17301        boolean didSomething = false;
17302        for (BroadcastQueue queue : mBroadcastQueues) {
17303            didSomething |= queue.sendPendingBroadcastsLocked(app);
17304        }
17305        return didSomething;
17306    }
17307
17308    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17309            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17310        enforceNotIsolatedCaller("registerReceiver");
17311        ArrayList<Intent> stickyIntents = null;
17312        ProcessRecord callerApp = null;
17313        int callingUid;
17314        int callingPid;
17315        synchronized(this) {
17316            if (caller != null) {
17317                callerApp = getRecordForAppLocked(caller);
17318                if (callerApp == null) {
17319                    throw new SecurityException(
17320                            "Unable to find app for caller " + caller
17321                            + " (pid=" + Binder.getCallingPid()
17322                            + ") when registering receiver " + receiver);
17323                }
17324                if (callerApp.info.uid != Process.SYSTEM_UID &&
17325                        !callerApp.pkgList.containsKey(callerPackage) &&
17326                        !"android".equals(callerPackage)) {
17327                    throw new SecurityException("Given caller package " + callerPackage
17328                            + " is not running in process " + callerApp);
17329                }
17330                callingUid = callerApp.info.uid;
17331                callingPid = callerApp.pid;
17332            } else {
17333                callerPackage = null;
17334                callingUid = Binder.getCallingUid();
17335                callingPid = Binder.getCallingPid();
17336            }
17337
17338            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17339                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17340
17341            Iterator<String> actions = filter.actionsIterator();
17342            if (actions == null) {
17343                ArrayList<String> noAction = new ArrayList<String>(1);
17344                noAction.add(null);
17345                actions = noAction.iterator();
17346            }
17347
17348            // Collect stickies of users
17349            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17350            while (actions.hasNext()) {
17351                String action = actions.next();
17352                for (int id : userIds) {
17353                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17354                    if (stickies != null) {
17355                        ArrayList<Intent> intents = stickies.get(action);
17356                        if (intents != null) {
17357                            if (stickyIntents == null) {
17358                                stickyIntents = new ArrayList<Intent>();
17359                            }
17360                            stickyIntents.addAll(intents);
17361                        }
17362                    }
17363                }
17364            }
17365        }
17366
17367        ArrayList<Intent> allSticky = null;
17368        if (stickyIntents != null) {
17369            final ContentResolver resolver = mContext.getContentResolver();
17370            // Look for any matching sticky broadcasts...
17371            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17372                Intent intent = stickyIntents.get(i);
17373                // If intent has scheme "content", it will need to acccess
17374                // provider that needs to lock mProviderMap in ActivityThread
17375                // and also it may need to wait application response, so we
17376                // cannot lock ActivityManagerService here.
17377                if (filter.match(resolver, intent, true, TAG) >= 0) {
17378                    if (allSticky == null) {
17379                        allSticky = new ArrayList<Intent>();
17380                    }
17381                    allSticky.add(intent);
17382                }
17383            }
17384        }
17385
17386        // The first sticky in the list is returned directly back to the client.
17387        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17388        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17389        if (receiver == null) {
17390            return sticky;
17391        }
17392
17393        synchronized (this) {
17394            if (callerApp != null && (callerApp.thread == null
17395                    || callerApp.thread.asBinder() != caller.asBinder())) {
17396                // Original caller already died
17397                return null;
17398            }
17399            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17400            if (rl == null) {
17401                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17402                        userId, receiver);
17403                if (rl.app != null) {
17404                    rl.app.receivers.add(rl);
17405                } else {
17406                    try {
17407                        receiver.asBinder().linkToDeath(rl, 0);
17408                    } catch (RemoteException e) {
17409                        return sticky;
17410                    }
17411                    rl.linkedToDeath = true;
17412                }
17413                mRegisteredReceivers.put(receiver.asBinder(), rl);
17414            } else if (rl.uid != callingUid) {
17415                throw new IllegalArgumentException(
17416                        "Receiver requested to register for uid " + callingUid
17417                        + " was previously registered for uid " + rl.uid);
17418            } else if (rl.pid != callingPid) {
17419                throw new IllegalArgumentException(
17420                        "Receiver requested to register for pid " + callingPid
17421                        + " was previously registered for pid " + rl.pid);
17422            } else if (rl.userId != userId) {
17423                throw new IllegalArgumentException(
17424                        "Receiver requested to register for user " + userId
17425                        + " was previously registered for user " + rl.userId);
17426            }
17427            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17428                    permission, callingUid, userId);
17429            rl.add(bf);
17430            if (!bf.debugCheck()) {
17431                Slog.w(TAG, "==> For Dynamic broadcast");
17432            }
17433            mReceiverResolver.addFilter(bf);
17434
17435            // Enqueue broadcasts for all existing stickies that match
17436            // this filter.
17437            if (allSticky != null) {
17438                ArrayList receivers = new ArrayList();
17439                receivers.add(bf);
17440
17441                final int stickyCount = allSticky.size();
17442                for (int i = 0; i < stickyCount; i++) {
17443                    Intent intent = allSticky.get(i);
17444                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17445                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17446                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17447                            null, 0, null, null, false, true, true, -1);
17448                    queue.enqueueParallelBroadcastLocked(r);
17449                    queue.scheduleBroadcastsLocked();
17450                }
17451            }
17452
17453            return sticky;
17454        }
17455    }
17456
17457    public void unregisterReceiver(IIntentReceiver receiver) {
17458        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17459
17460        final long origId = Binder.clearCallingIdentity();
17461        try {
17462            boolean doTrim = false;
17463
17464            synchronized(this) {
17465                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17466                if (rl != null) {
17467                    final BroadcastRecord r = rl.curBroadcast;
17468                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17469                        final boolean doNext = r.queue.finishReceiverLocked(
17470                                r, r.resultCode, r.resultData, r.resultExtras,
17471                                r.resultAbort, false);
17472                        if (doNext) {
17473                            doTrim = true;
17474                            r.queue.processNextBroadcast(false);
17475                        }
17476                    }
17477
17478                    if (rl.app != null) {
17479                        rl.app.receivers.remove(rl);
17480                    }
17481                    removeReceiverLocked(rl);
17482                    if (rl.linkedToDeath) {
17483                        rl.linkedToDeath = false;
17484                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17485                    }
17486                }
17487            }
17488
17489            // If we actually concluded any broadcasts, we might now be able
17490            // to trim the recipients' apps from our working set
17491            if (doTrim) {
17492                trimApplications();
17493                return;
17494            }
17495
17496        } finally {
17497            Binder.restoreCallingIdentity(origId);
17498        }
17499    }
17500
17501    void removeReceiverLocked(ReceiverList rl) {
17502        mRegisteredReceivers.remove(rl.receiver.asBinder());
17503        for (int i = rl.size() - 1; i >= 0; i--) {
17504            mReceiverResolver.removeFilter(rl.get(i));
17505        }
17506    }
17507
17508    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17509        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17510            ProcessRecord r = mLruProcesses.get(i);
17511            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17512                try {
17513                    r.thread.dispatchPackageBroadcast(cmd, packages);
17514                } catch (RemoteException ex) {
17515                }
17516            }
17517        }
17518    }
17519
17520    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17521            int callingUid, int[] users) {
17522        // TODO: come back and remove this assumption to triage all broadcasts
17523        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17524
17525        List<ResolveInfo> receivers = null;
17526        try {
17527            HashSet<ComponentName> singleUserReceivers = null;
17528            boolean scannedFirstReceivers = false;
17529            for (int user : users) {
17530                // Skip users that have Shell restrictions, with exception of always permitted
17531                // Shell broadcasts
17532                if (callingUid == Process.SHELL_UID
17533                        && mUserController.hasUserRestriction(
17534                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17535                        && !isPermittedShellBroadcast(intent)) {
17536                    continue;
17537                }
17538                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17539                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17540                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17541                    // If this is not the system user, we need to check for
17542                    // any receivers that should be filtered out.
17543                    for (int i=0; i<newReceivers.size(); i++) {
17544                        ResolveInfo ri = newReceivers.get(i);
17545                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17546                            newReceivers.remove(i);
17547                            i--;
17548                        }
17549                    }
17550                }
17551                if (newReceivers != null && newReceivers.size() == 0) {
17552                    newReceivers = null;
17553                }
17554                if (receivers == null) {
17555                    receivers = newReceivers;
17556                } else if (newReceivers != null) {
17557                    // We need to concatenate the additional receivers
17558                    // found with what we have do far.  This would be easy,
17559                    // but we also need to de-dup any receivers that are
17560                    // singleUser.
17561                    if (!scannedFirstReceivers) {
17562                        // Collect any single user receivers we had already retrieved.
17563                        scannedFirstReceivers = true;
17564                        for (int i=0; i<receivers.size(); i++) {
17565                            ResolveInfo ri = receivers.get(i);
17566                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17567                                ComponentName cn = new ComponentName(
17568                                        ri.activityInfo.packageName, ri.activityInfo.name);
17569                                if (singleUserReceivers == null) {
17570                                    singleUserReceivers = new HashSet<ComponentName>();
17571                                }
17572                                singleUserReceivers.add(cn);
17573                            }
17574                        }
17575                    }
17576                    // Add the new results to the existing results, tracking
17577                    // and de-dupping single user receivers.
17578                    for (int i=0; i<newReceivers.size(); i++) {
17579                        ResolveInfo ri = newReceivers.get(i);
17580                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17581                            ComponentName cn = new ComponentName(
17582                                    ri.activityInfo.packageName, ri.activityInfo.name);
17583                            if (singleUserReceivers == null) {
17584                                singleUserReceivers = new HashSet<ComponentName>();
17585                            }
17586                            if (!singleUserReceivers.contains(cn)) {
17587                                singleUserReceivers.add(cn);
17588                                receivers.add(ri);
17589                            }
17590                        } else {
17591                            receivers.add(ri);
17592                        }
17593                    }
17594                }
17595            }
17596        } catch (RemoteException ex) {
17597            // pm is in same process, this will never happen.
17598        }
17599        return receivers;
17600    }
17601
17602    private boolean isPermittedShellBroadcast(Intent intent) {
17603        // remote bugreport should always be allowed to be taken
17604        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17605    }
17606
17607    final int broadcastIntentLocked(ProcessRecord callerApp,
17608            String callerPackage, Intent intent, String resolvedType,
17609            IIntentReceiver resultTo, int resultCode, String resultData,
17610            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17611            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17612        intent = new Intent(intent);
17613
17614        // By default broadcasts do not go to stopped apps.
17615        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17616
17617        // If we have not finished booting, don't allow this to launch new processes.
17618        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17619            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17620        }
17621
17622        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17623                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17624                + " ordered=" + ordered + " userid=" + userId);
17625        if ((resultTo != null) && !ordered) {
17626            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17627        }
17628
17629        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17630                ALLOW_NON_FULL, "broadcast", callerPackage);
17631
17632        // Make sure that the user who is receiving this broadcast is running.
17633        // If not, we will just skip it. Make an exception for shutdown broadcasts
17634        // and upgrade steps.
17635
17636        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17637            if ((callingUid != Process.SYSTEM_UID
17638                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17639                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17640                Slog.w(TAG, "Skipping broadcast of " + intent
17641                        + ": user " + userId + " is stopped");
17642                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17643            }
17644        }
17645
17646        BroadcastOptions brOptions = null;
17647        if (bOptions != null) {
17648            brOptions = new BroadcastOptions(bOptions);
17649            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17650                // See if the caller is allowed to do this.  Note we are checking against
17651                // the actual real caller (not whoever provided the operation as say a
17652                // PendingIntent), because that who is actually supplied the arguments.
17653                if (checkComponentPermission(
17654                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17655                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17656                        != PackageManager.PERMISSION_GRANTED) {
17657                    String msg = "Permission Denial: " + intent.getAction()
17658                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17659                            + ", uid=" + callingUid + ")"
17660                            + " requires "
17661                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17662                    Slog.w(TAG, msg);
17663                    throw new SecurityException(msg);
17664                }
17665            }
17666        }
17667
17668        // Verify that protected broadcasts are only being sent by system code,
17669        // and that system code is only sending protected broadcasts.
17670        final String action = intent.getAction();
17671        final boolean isProtectedBroadcast;
17672        try {
17673            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17674        } catch (RemoteException e) {
17675            Slog.w(TAG, "Remote exception", e);
17676            return ActivityManager.BROADCAST_SUCCESS;
17677        }
17678
17679        final boolean isCallerSystem;
17680        switch (UserHandle.getAppId(callingUid)) {
17681            case Process.ROOT_UID:
17682            case Process.SYSTEM_UID:
17683            case Process.PHONE_UID:
17684            case Process.BLUETOOTH_UID:
17685            case Process.NFC_UID:
17686                isCallerSystem = true;
17687                break;
17688            default:
17689                isCallerSystem = (callerApp != null) && callerApp.persistent;
17690                break;
17691        }
17692
17693        if (isCallerSystem) {
17694            if (isProtectedBroadcast
17695                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17696                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17697                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17698                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17699                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17700                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17701                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17702                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17703                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17704                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17705                // Broadcast is either protected, or it's a public action that
17706                // we've relaxed, so it's fine for system internals to send.
17707            } else {
17708                // The vast majority of broadcasts sent from system internals
17709                // should be protected to avoid security holes, so yell loudly
17710                // to ensure we examine these cases.
17711                if (callerApp != null) {
17712                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17713                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17714                            new Throwable());
17715                } else {
17716                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17717                            + " from system uid " + UserHandle.formatUid(callingUid)
17718                            + " pkg " + callerPackage,
17719                            new Throwable());
17720                }
17721            }
17722
17723        } else {
17724            if (isProtectedBroadcast) {
17725                String msg = "Permission Denial: not allowed to send broadcast "
17726                        + action + " from pid="
17727                        + callingPid + ", uid=" + callingUid;
17728                Slog.w(TAG, msg);
17729                throw new SecurityException(msg);
17730
17731            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17732                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17733                // Special case for compatibility: we don't want apps to send this,
17734                // but historically it has not been protected and apps may be using it
17735                // to poke their own app widget.  So, instead of making it protected,
17736                // just limit it to the caller.
17737                if (callerPackage == null) {
17738                    String msg = "Permission Denial: not allowed to send broadcast "
17739                            + action + " from unknown caller.";
17740                    Slog.w(TAG, msg);
17741                    throw new SecurityException(msg);
17742                } else if (intent.getComponent() != null) {
17743                    // They are good enough to send to an explicit component...  verify
17744                    // it is being sent to the calling app.
17745                    if (!intent.getComponent().getPackageName().equals(
17746                            callerPackage)) {
17747                        String msg = "Permission Denial: not allowed to send broadcast "
17748                                + action + " to "
17749                                + intent.getComponent().getPackageName() + " from "
17750                                + callerPackage;
17751                        Slog.w(TAG, msg);
17752                        throw new SecurityException(msg);
17753                    }
17754                } else {
17755                    // Limit broadcast to their own package.
17756                    intent.setPackage(callerPackage);
17757                }
17758            }
17759        }
17760
17761        if (action != null) {
17762            switch (action) {
17763                case Intent.ACTION_UID_REMOVED:
17764                case Intent.ACTION_PACKAGE_REMOVED:
17765                case Intent.ACTION_PACKAGE_CHANGED:
17766                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17767                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17768                case Intent.ACTION_PACKAGES_SUSPENDED:
17769                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17770                    // Handle special intents: if this broadcast is from the package
17771                    // manager about a package being removed, we need to remove all of
17772                    // its activities from the history stack.
17773                    if (checkComponentPermission(
17774                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17775                            callingPid, callingUid, -1, true)
17776                            != PackageManager.PERMISSION_GRANTED) {
17777                        String msg = "Permission Denial: " + intent.getAction()
17778                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17779                                + ", uid=" + callingUid + ")"
17780                                + " requires "
17781                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17782                        Slog.w(TAG, msg);
17783                        throw new SecurityException(msg);
17784                    }
17785                    switch (action) {
17786                        case Intent.ACTION_UID_REMOVED:
17787                            final Bundle intentExtras = intent.getExtras();
17788                            final int uid = intentExtras != null
17789                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17790                            if (uid >= 0) {
17791                                mBatteryStatsService.removeUid(uid);
17792                                mAppOpsService.uidRemoved(uid);
17793                            }
17794                            break;
17795                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17796                            // If resources are unavailable just force stop all those packages
17797                            // and flush the attribute cache as well.
17798                            String list[] =
17799                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17800                            if (list != null && list.length > 0) {
17801                                for (int i = 0; i < list.length; i++) {
17802                                    forceStopPackageLocked(list[i], -1, false, true, true,
17803                                            false, false, userId, "storage unmount");
17804                                }
17805                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17806                                sendPackageBroadcastLocked(
17807                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17808                                        userId);
17809                            }
17810                            break;
17811                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17812                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17813                            break;
17814                        case Intent.ACTION_PACKAGE_REMOVED:
17815                        case Intent.ACTION_PACKAGE_CHANGED:
17816                            Uri data = intent.getData();
17817                            String ssp;
17818                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17819                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17820                                final boolean replacing =
17821                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17822                                final boolean killProcess =
17823                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17824                                final boolean fullUninstall = removed && !replacing;
17825                                if (removed) {
17826                                    if (killProcess) {
17827                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17828                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17829                                                false, true, true, false, fullUninstall, userId,
17830                                                removed ? "pkg removed" : "pkg changed");
17831                                    }
17832                                    final int cmd = killProcess
17833                                            ? IApplicationThread.PACKAGE_REMOVED
17834                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17835                                    sendPackageBroadcastLocked(cmd,
17836                                            new String[] {ssp}, userId);
17837                                    if (fullUninstall) {
17838                                        mAppOpsService.packageRemoved(
17839                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17840
17841                                        // Remove all permissions granted from/to this package
17842                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17843
17844                                        removeTasksByPackageNameLocked(ssp, userId);
17845
17846                                        // Hide the "unsupported display" dialog if necessary.
17847                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17848                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17849                                            mUnsupportedDisplaySizeDialog.dismiss();
17850                                            mUnsupportedDisplaySizeDialog = null;
17851                                        }
17852                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17853                                        mBatteryStatsService.notePackageUninstalled(ssp);
17854                                    }
17855                                } else {
17856                                    if (killProcess) {
17857                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17858                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17859                                                userId, ProcessList.INVALID_ADJ,
17860                                                false, true, true, false, "change " + ssp);
17861                                    }
17862                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17863                                            intent.getStringArrayExtra(
17864                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17865                                }
17866                            }
17867                            break;
17868                        case Intent.ACTION_PACKAGES_SUSPENDED:
17869                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17870                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17871                                    intent.getAction());
17872                            final String[] packageNames = intent.getStringArrayExtra(
17873                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17874                            final int userHandle = intent.getIntExtra(
17875                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17876
17877                            synchronized(ActivityManagerService.this) {
17878                                mRecentTasks.onPackagesSuspendedChanged(
17879                                        packageNames, suspended, userHandle);
17880                            }
17881                            break;
17882                    }
17883                    break;
17884                case Intent.ACTION_PACKAGE_REPLACED:
17885                {
17886                    final Uri data = intent.getData();
17887                    final String ssp;
17888                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17889                        final ApplicationInfo aInfo =
17890                                getPackageManagerInternalLocked().getApplicationInfo(
17891                                        ssp,
17892                                        userId);
17893                        if (aInfo == null) {
17894                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17895                                    + " ssp=" + ssp + " data=" + data);
17896                            return ActivityManager.BROADCAST_SUCCESS;
17897                        }
17898                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17899                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17900                                new String[] {ssp}, userId);
17901                    }
17902                    break;
17903                }
17904                case Intent.ACTION_PACKAGE_ADDED:
17905                {
17906                    // Special case for adding a package: by default turn on compatibility mode.
17907                    Uri data = intent.getData();
17908                    String ssp;
17909                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17910                        final boolean replacing =
17911                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17912                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17913
17914                        try {
17915                            ApplicationInfo ai = AppGlobals.getPackageManager().
17916                                    getApplicationInfo(ssp, 0, 0);
17917                            mBatteryStatsService.notePackageInstalled(ssp,
17918                                    ai != null ? ai.versionCode : 0);
17919                        } catch (RemoteException e) {
17920                        }
17921                    }
17922                    break;
17923                }
17924                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17925                {
17926                    Uri data = intent.getData();
17927                    String ssp;
17928                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17929                        // Hide the "unsupported display" dialog if necessary.
17930                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17931                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17932                            mUnsupportedDisplaySizeDialog.dismiss();
17933                            mUnsupportedDisplaySizeDialog = null;
17934                        }
17935                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17936                    }
17937                    break;
17938                }
17939                case Intent.ACTION_TIMEZONE_CHANGED:
17940                    // If this is the time zone changed action, queue up a message that will reset
17941                    // the timezone of all currently running processes. This message will get
17942                    // queued up before the broadcast happens.
17943                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17944                    break;
17945                case Intent.ACTION_TIME_CHANGED:
17946                    // If the user set the time, let all running processes know.
17947                    final int is24Hour =
17948                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17949                                    : 0;
17950                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17951                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17952                    synchronized (stats) {
17953                        stats.noteCurrentTimeChangedLocked();
17954                    }
17955                    break;
17956                case Intent.ACTION_CLEAR_DNS_CACHE:
17957                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17958                    break;
17959                case Proxy.PROXY_CHANGE_ACTION:
17960                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17961                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17962                    break;
17963                case android.hardware.Camera.ACTION_NEW_PICTURE:
17964                case android.hardware.Camera.ACTION_NEW_VIDEO:
17965                    // These broadcasts are no longer allowed by the system, since they can
17966                    // cause significant thrashing at a crictical point (using the camera).
17967                    // Apps should use JobScehduler to monitor for media provider changes.
17968                    Slog.w(TAG, action + " no longer allowed; dropping from "
17969                            + UserHandle.formatUid(callingUid));
17970                    if (resultTo != null) {
17971                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17972                        try {
17973                            queue.performReceiveLocked(callerApp, resultTo, intent,
17974                                    Activity.RESULT_CANCELED, null, null,
17975                                    false, false, userId);
17976                        } catch (RemoteException e) {
17977                            Slog.w(TAG, "Failure ["
17978                                    + queue.mQueueName + "] sending broadcast result of "
17979                                    + intent, e);
17980
17981                        }
17982                    }
17983                    // Lie; we don't want to crash the app.
17984                    return ActivityManager.BROADCAST_SUCCESS;
17985            }
17986        }
17987
17988        // Add to the sticky list if requested.
17989        if (sticky) {
17990            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17991                    callingPid, callingUid)
17992                    != PackageManager.PERMISSION_GRANTED) {
17993                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17994                        + callingPid + ", uid=" + callingUid
17995                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17996                Slog.w(TAG, msg);
17997                throw new SecurityException(msg);
17998            }
17999            if (requiredPermissions != null && requiredPermissions.length > 0) {
18000                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18001                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18002                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18003            }
18004            if (intent.getComponent() != null) {
18005                throw new SecurityException(
18006                        "Sticky broadcasts can't target a specific component");
18007            }
18008            // We use userId directly here, since the "all" target is maintained
18009            // as a separate set of sticky broadcasts.
18010            if (userId != UserHandle.USER_ALL) {
18011                // But first, if this is not a broadcast to all users, then
18012                // make sure it doesn't conflict with an existing broadcast to
18013                // all users.
18014                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18015                        UserHandle.USER_ALL);
18016                if (stickies != null) {
18017                    ArrayList<Intent> list = stickies.get(intent.getAction());
18018                    if (list != null) {
18019                        int N = list.size();
18020                        int i;
18021                        for (i=0; i<N; i++) {
18022                            if (intent.filterEquals(list.get(i))) {
18023                                throw new IllegalArgumentException(
18024                                        "Sticky broadcast " + intent + " for user "
18025                                        + userId + " conflicts with existing global broadcast");
18026                            }
18027                        }
18028                    }
18029                }
18030            }
18031            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18032            if (stickies == null) {
18033                stickies = new ArrayMap<>();
18034                mStickyBroadcasts.put(userId, stickies);
18035            }
18036            ArrayList<Intent> list = stickies.get(intent.getAction());
18037            if (list == null) {
18038                list = new ArrayList<>();
18039                stickies.put(intent.getAction(), list);
18040            }
18041            final int stickiesCount = list.size();
18042            int i;
18043            for (i = 0; i < stickiesCount; i++) {
18044                if (intent.filterEquals(list.get(i))) {
18045                    // This sticky already exists, replace it.
18046                    list.set(i, new Intent(intent));
18047                    break;
18048                }
18049            }
18050            if (i >= stickiesCount) {
18051                list.add(new Intent(intent));
18052            }
18053        }
18054
18055        int[] users;
18056        if (userId == UserHandle.USER_ALL) {
18057            // Caller wants broadcast to go to all started users.
18058            users = mUserController.getStartedUserArrayLocked();
18059        } else {
18060            // Caller wants broadcast to go to one specific user.
18061            users = new int[] {userId};
18062        }
18063
18064        // Figure out who all will receive this broadcast.
18065        List receivers = null;
18066        List<BroadcastFilter> registeredReceivers = null;
18067        // Need to resolve the intent to interested receivers...
18068        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18069                 == 0) {
18070            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18071        }
18072        if (intent.getComponent() == null) {
18073            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18074                // Query one target user at a time, excluding shell-restricted users
18075                for (int i = 0; i < users.length; i++) {
18076                    if (mUserController.hasUserRestriction(
18077                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18078                        continue;
18079                    }
18080                    List<BroadcastFilter> registeredReceiversForUser =
18081                            mReceiverResolver.queryIntent(intent,
18082                                    resolvedType, false, users[i]);
18083                    if (registeredReceivers == null) {
18084                        registeredReceivers = registeredReceiversForUser;
18085                    } else if (registeredReceiversForUser != null) {
18086                        registeredReceivers.addAll(registeredReceiversForUser);
18087                    }
18088                }
18089            } else {
18090                registeredReceivers = mReceiverResolver.queryIntent(intent,
18091                        resolvedType, false, userId);
18092            }
18093        }
18094
18095        final boolean replacePending =
18096                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18097
18098        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18099                + " replacePending=" + replacePending);
18100
18101        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18102        if (!ordered && NR > 0) {
18103            // If we are not serializing this broadcast, then send the
18104            // registered receivers separately so they don't wait for the
18105            // components to be launched.
18106            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18107            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18108                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18109                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18110                    resultExtras, ordered, sticky, false, userId);
18111            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18112            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18113            if (!replaced) {
18114                queue.enqueueParallelBroadcastLocked(r);
18115                queue.scheduleBroadcastsLocked();
18116            }
18117            registeredReceivers = null;
18118            NR = 0;
18119        }
18120
18121        // Merge into one list.
18122        int ir = 0;
18123        if (receivers != null) {
18124            // A special case for PACKAGE_ADDED: do not allow the package
18125            // being added to see this broadcast.  This prevents them from
18126            // using this as a back door to get run as soon as they are
18127            // installed.  Maybe in the future we want to have a special install
18128            // broadcast or such for apps, but we'd like to deliberately make
18129            // this decision.
18130            String skipPackages[] = null;
18131            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18132                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18133                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18134                Uri data = intent.getData();
18135                if (data != null) {
18136                    String pkgName = data.getSchemeSpecificPart();
18137                    if (pkgName != null) {
18138                        skipPackages = new String[] { pkgName };
18139                    }
18140                }
18141            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18142                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18143            }
18144            if (skipPackages != null && (skipPackages.length > 0)) {
18145                for (String skipPackage : skipPackages) {
18146                    if (skipPackage != null) {
18147                        int NT = receivers.size();
18148                        for (int it=0; it<NT; it++) {
18149                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18150                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18151                                receivers.remove(it);
18152                                it--;
18153                                NT--;
18154                            }
18155                        }
18156                    }
18157                }
18158            }
18159
18160            int NT = receivers != null ? receivers.size() : 0;
18161            int it = 0;
18162            ResolveInfo curt = null;
18163            BroadcastFilter curr = null;
18164            while (it < NT && ir < NR) {
18165                if (curt == null) {
18166                    curt = (ResolveInfo)receivers.get(it);
18167                }
18168                if (curr == null) {
18169                    curr = registeredReceivers.get(ir);
18170                }
18171                if (curr.getPriority() >= curt.priority) {
18172                    // Insert this broadcast record into the final list.
18173                    receivers.add(it, curr);
18174                    ir++;
18175                    curr = null;
18176                    it++;
18177                    NT++;
18178                } else {
18179                    // Skip to the next ResolveInfo in the final list.
18180                    it++;
18181                    curt = null;
18182                }
18183            }
18184        }
18185        while (ir < NR) {
18186            if (receivers == null) {
18187                receivers = new ArrayList();
18188            }
18189            receivers.add(registeredReceivers.get(ir));
18190            ir++;
18191        }
18192
18193        if ((receivers != null && receivers.size() > 0)
18194                || resultTo != null) {
18195            BroadcastQueue queue = broadcastQueueForIntent(intent);
18196            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18197                    callerPackage, callingPid, callingUid, resolvedType,
18198                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18199                    resultData, resultExtras, ordered, sticky, false, userId);
18200
18201            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18202                    + ": prev had " + queue.mOrderedBroadcasts.size());
18203            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18204                    "Enqueueing broadcast " + r.intent.getAction());
18205
18206            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18207            if (!replaced) {
18208                queue.enqueueOrderedBroadcastLocked(r);
18209                queue.scheduleBroadcastsLocked();
18210            }
18211        } else {
18212            // There was nobody interested in the broadcast, but we still want to record
18213            // that it happened.
18214            if (intent.getComponent() == null && intent.getPackage() == null
18215                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18216                // This was an implicit broadcast... let's record it for posterity.
18217                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18218            }
18219        }
18220
18221        return ActivityManager.BROADCAST_SUCCESS;
18222    }
18223
18224    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18225            int skipCount, long dispatchTime) {
18226        final long now = SystemClock.elapsedRealtime();
18227        if (mCurBroadcastStats == null ||
18228                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18229            mLastBroadcastStats = mCurBroadcastStats;
18230            if (mLastBroadcastStats != null) {
18231                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18232                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18233            }
18234            mCurBroadcastStats = new BroadcastStats();
18235        }
18236        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18237    }
18238
18239    final Intent verifyBroadcastLocked(Intent intent) {
18240        // Refuse possible leaked file descriptors
18241        if (intent != null && intent.hasFileDescriptors() == true) {
18242            throw new IllegalArgumentException("File descriptors passed in Intent");
18243        }
18244
18245        int flags = intent.getFlags();
18246
18247        if (!mProcessesReady) {
18248            // if the caller really truly claims to know what they're doing, go
18249            // ahead and allow the broadcast without launching any receivers
18250            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18251                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18252            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18253                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18254                        + " before boot completion");
18255                throw new IllegalStateException("Cannot broadcast before boot completed");
18256            }
18257        }
18258
18259        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18260            throw new IllegalArgumentException(
18261                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18262        }
18263
18264        return intent;
18265    }
18266
18267    public final int broadcastIntent(IApplicationThread caller,
18268            Intent intent, String resolvedType, IIntentReceiver resultTo,
18269            int resultCode, String resultData, Bundle resultExtras,
18270            String[] requiredPermissions, int appOp, Bundle bOptions,
18271            boolean serialized, boolean sticky, int userId) {
18272        enforceNotIsolatedCaller("broadcastIntent");
18273        synchronized(this) {
18274            intent = verifyBroadcastLocked(intent);
18275
18276            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18277            final int callingPid = Binder.getCallingPid();
18278            final int callingUid = Binder.getCallingUid();
18279            final long origId = Binder.clearCallingIdentity();
18280            int res = broadcastIntentLocked(callerApp,
18281                    callerApp != null ? callerApp.info.packageName : null,
18282                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18283                    requiredPermissions, appOp, bOptions, serialized, sticky,
18284                    callingPid, callingUid, userId);
18285            Binder.restoreCallingIdentity(origId);
18286            return res;
18287        }
18288    }
18289
18290
18291    int broadcastIntentInPackage(String packageName, int uid,
18292            Intent intent, String resolvedType, IIntentReceiver resultTo,
18293            int resultCode, String resultData, Bundle resultExtras,
18294            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18295            int userId) {
18296        synchronized(this) {
18297            intent = verifyBroadcastLocked(intent);
18298
18299            final long origId = Binder.clearCallingIdentity();
18300            String[] requiredPermissions = requiredPermission == null ? null
18301                    : new String[] {requiredPermission};
18302            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18303                    resultTo, resultCode, resultData, resultExtras,
18304                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18305                    sticky, -1, uid, userId);
18306            Binder.restoreCallingIdentity(origId);
18307            return res;
18308        }
18309    }
18310
18311    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18312        // Refuse possible leaked file descriptors
18313        if (intent != null && intent.hasFileDescriptors() == true) {
18314            throw new IllegalArgumentException("File descriptors passed in Intent");
18315        }
18316
18317        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18318                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18319
18320        synchronized(this) {
18321            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18322                    != PackageManager.PERMISSION_GRANTED) {
18323                String msg = "Permission Denial: unbroadcastIntent() from pid="
18324                        + Binder.getCallingPid()
18325                        + ", uid=" + Binder.getCallingUid()
18326                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18327                Slog.w(TAG, msg);
18328                throw new SecurityException(msg);
18329            }
18330            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18331            if (stickies != null) {
18332                ArrayList<Intent> list = stickies.get(intent.getAction());
18333                if (list != null) {
18334                    int N = list.size();
18335                    int i;
18336                    for (i=0; i<N; i++) {
18337                        if (intent.filterEquals(list.get(i))) {
18338                            list.remove(i);
18339                            break;
18340                        }
18341                    }
18342                    if (list.size() <= 0) {
18343                        stickies.remove(intent.getAction());
18344                    }
18345                }
18346                if (stickies.size() <= 0) {
18347                    mStickyBroadcasts.remove(userId);
18348                }
18349            }
18350        }
18351    }
18352
18353    void backgroundServicesFinishedLocked(int userId) {
18354        for (BroadcastQueue queue : mBroadcastQueues) {
18355            queue.backgroundServicesFinishedLocked(userId);
18356        }
18357    }
18358
18359    public void finishReceiver(IBinder who, int resultCode, String resultData,
18360            Bundle resultExtras, boolean resultAbort, int flags) {
18361        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18362
18363        // Refuse possible leaked file descriptors
18364        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18365            throw new IllegalArgumentException("File descriptors passed in Bundle");
18366        }
18367
18368        final long origId = Binder.clearCallingIdentity();
18369        try {
18370            boolean doNext = false;
18371            BroadcastRecord r;
18372
18373            synchronized(this) {
18374                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18375                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18376                r = queue.getMatchingOrderedReceiver(who);
18377                if (r != null) {
18378                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18379                        resultData, resultExtras, resultAbort, true);
18380                }
18381            }
18382
18383            if (doNext) {
18384                r.queue.processNextBroadcast(false);
18385            }
18386            trimApplications();
18387        } finally {
18388            Binder.restoreCallingIdentity(origId);
18389        }
18390    }
18391
18392    // =========================================================
18393    // INSTRUMENTATION
18394    // =========================================================
18395
18396    public boolean startInstrumentation(ComponentName className,
18397            String profileFile, int flags, Bundle arguments,
18398            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18399            int userId, String abiOverride) {
18400        enforceNotIsolatedCaller("startInstrumentation");
18401        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18402                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18403        // Refuse possible leaked file descriptors
18404        if (arguments != null && arguments.hasFileDescriptors()) {
18405            throw new IllegalArgumentException("File descriptors passed in Bundle");
18406        }
18407
18408        synchronized(this) {
18409            InstrumentationInfo ii = null;
18410            ApplicationInfo ai = null;
18411            try {
18412                ii = mContext.getPackageManager().getInstrumentationInfo(
18413                    className, STOCK_PM_FLAGS);
18414                ai = AppGlobals.getPackageManager().getApplicationInfo(
18415                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18416            } catch (PackageManager.NameNotFoundException e) {
18417            } catch (RemoteException e) {
18418            }
18419            if (ii == null) {
18420                reportStartInstrumentationFailureLocked(watcher, className,
18421                        "Unable to find instrumentation info for: " + className);
18422                return false;
18423            }
18424            if (ai == null) {
18425                reportStartInstrumentationFailureLocked(watcher, className,
18426                        "Unable to find instrumentation target package: " + ii.targetPackage);
18427                return false;
18428            }
18429            if (!ai.hasCode()) {
18430                reportStartInstrumentationFailureLocked(watcher, className,
18431                        "Instrumentation target has no code: " + ii.targetPackage);
18432                return false;
18433            }
18434
18435            int match = mContext.getPackageManager().checkSignatures(
18436                    ii.targetPackage, ii.packageName);
18437            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18438                String msg = "Permission Denial: starting instrumentation "
18439                        + className + " from pid="
18440                        + Binder.getCallingPid()
18441                        + ", uid=" + Binder.getCallingPid()
18442                        + " not allowed because package " + ii.packageName
18443                        + " does not have a signature matching the target "
18444                        + ii.targetPackage;
18445                reportStartInstrumentationFailureLocked(watcher, className, msg);
18446                throw new SecurityException(msg);
18447            }
18448
18449            final long origId = Binder.clearCallingIdentity();
18450            // Instrumentation can kill and relaunch even persistent processes
18451            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18452                    "start instr");
18453            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18454            app.instrumentationClass = className;
18455            app.instrumentationInfo = ai;
18456            app.instrumentationProfileFile = profileFile;
18457            app.instrumentationArguments = arguments;
18458            app.instrumentationWatcher = watcher;
18459            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18460            app.instrumentationResultClass = className;
18461            Binder.restoreCallingIdentity(origId);
18462        }
18463
18464        return true;
18465    }
18466
18467    /**
18468     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18469     * error to the logs, but if somebody is watching, send the report there too.  This enables
18470     * the "am" command to report errors with more information.
18471     *
18472     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18473     * @param cn The component name of the instrumentation.
18474     * @param report The error report.
18475     */
18476    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18477            ComponentName cn, String report) {
18478        Slog.w(TAG, report);
18479        if (watcher != null) {
18480            Bundle results = new Bundle();
18481            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18482            results.putString("Error", report);
18483            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18484        }
18485    }
18486
18487    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18488        if (app.instrumentationWatcher != null) {
18489            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18490                    app.instrumentationClass, resultCode, results);
18491        }
18492
18493        // Can't call out of the system process with a lock held, so post a message.
18494        if (app.instrumentationUiAutomationConnection != null) {
18495            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18496                    app.instrumentationUiAutomationConnection).sendToTarget();
18497        }
18498
18499        app.instrumentationWatcher = null;
18500        app.instrumentationUiAutomationConnection = null;
18501        app.instrumentationClass = null;
18502        app.instrumentationInfo = null;
18503        app.instrumentationProfileFile = null;
18504        app.instrumentationArguments = null;
18505
18506        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18507                "finished inst");
18508    }
18509
18510    public void finishInstrumentation(IApplicationThread target,
18511            int resultCode, Bundle results) {
18512        int userId = UserHandle.getCallingUserId();
18513        // Refuse possible leaked file descriptors
18514        if (results != null && results.hasFileDescriptors()) {
18515            throw new IllegalArgumentException("File descriptors passed in Intent");
18516        }
18517
18518        synchronized(this) {
18519            ProcessRecord app = getRecordForAppLocked(target);
18520            if (app == null) {
18521                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18522                return;
18523            }
18524            final long origId = Binder.clearCallingIdentity();
18525            finishInstrumentationLocked(app, resultCode, results);
18526            Binder.restoreCallingIdentity(origId);
18527        }
18528    }
18529
18530    // =========================================================
18531    // CONFIGURATION
18532    // =========================================================
18533
18534    public ConfigurationInfo getDeviceConfigurationInfo() {
18535        ConfigurationInfo config = new ConfigurationInfo();
18536        synchronized (this) {
18537            config.reqTouchScreen = mConfiguration.touchscreen;
18538            config.reqKeyboardType = mConfiguration.keyboard;
18539            config.reqNavigation = mConfiguration.navigation;
18540            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18541                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18542                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18543            }
18544            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18545                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18546                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18547            }
18548            config.reqGlEsVersion = GL_ES_VERSION;
18549        }
18550        return config;
18551    }
18552
18553    ActivityStack getFocusedStack() {
18554        return mStackSupervisor.getFocusedStack();
18555    }
18556
18557    @Override
18558    public int getFocusedStackId() throws RemoteException {
18559        ActivityStack focusedStack = getFocusedStack();
18560        if (focusedStack != null) {
18561            return focusedStack.getStackId();
18562        }
18563        return -1;
18564    }
18565
18566    public Configuration getConfiguration() {
18567        Configuration ci;
18568        synchronized(this) {
18569            ci = new Configuration(mConfiguration);
18570            ci.userSetLocale = false;
18571        }
18572        return ci;
18573    }
18574
18575    @Override
18576    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18577        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18578        synchronized (this) {
18579            mSuppressResizeConfigChanges = suppress;
18580        }
18581    }
18582
18583    @Override
18584    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18585        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18586        if (fromStackId == HOME_STACK_ID) {
18587            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18588        }
18589        synchronized (this) {
18590            final long origId = Binder.clearCallingIdentity();
18591            try {
18592                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18593            } finally {
18594                Binder.restoreCallingIdentity(origId);
18595            }
18596        }
18597    }
18598
18599    @Override
18600    public void updatePersistentConfiguration(Configuration values) {
18601        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18602                "updateConfiguration()");
18603        enforceWriteSettingsPermission("updateConfiguration()");
18604        if (values == null) {
18605            throw new NullPointerException("Configuration must not be null");
18606        }
18607
18608        int userId = UserHandle.getCallingUserId();
18609
18610        synchronized(this) {
18611            final long origId = Binder.clearCallingIdentity();
18612            updateConfigurationLocked(values, null, false, true, userId);
18613            Binder.restoreCallingIdentity(origId);
18614        }
18615    }
18616
18617    private void updateFontScaleIfNeeded() {
18618        final int currentUserId;
18619        synchronized(this) {
18620            currentUserId = mUserController.getCurrentUserIdLocked();
18621        }
18622        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18623                FONT_SCALE, 1.0f, currentUserId);
18624        if (mConfiguration.fontScale != scaleFactor) {
18625            final Configuration configuration = mWindowManager.computeNewConfiguration();
18626            configuration.fontScale = scaleFactor;
18627            updatePersistentConfiguration(configuration);
18628        }
18629    }
18630
18631    private void enforceWriteSettingsPermission(String func) {
18632        int uid = Binder.getCallingUid();
18633        if (uid == Process.ROOT_UID) {
18634            return;
18635        }
18636
18637        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18638                Settings.getPackageNameForUid(mContext, uid), false)) {
18639            return;
18640        }
18641
18642        String msg = "Permission Denial: " + func + " from pid="
18643                + Binder.getCallingPid()
18644                + ", uid=" + uid
18645                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18646        Slog.w(TAG, msg);
18647        throw new SecurityException(msg);
18648    }
18649
18650    public void updateConfiguration(Configuration values) {
18651        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18652                "updateConfiguration()");
18653
18654        synchronized(this) {
18655            if (values == null && mWindowManager != null) {
18656                // sentinel: fetch the current configuration from the window manager
18657                values = mWindowManager.computeNewConfiguration();
18658            }
18659
18660            if (mWindowManager != null) {
18661                mProcessList.applyDisplaySize(mWindowManager);
18662            }
18663
18664            final long origId = Binder.clearCallingIdentity();
18665            if (values != null) {
18666                Settings.System.clearConfiguration(values);
18667            }
18668            updateConfigurationLocked(values, null, false);
18669            Binder.restoreCallingIdentity(origId);
18670        }
18671    }
18672
18673    void updateUserConfigurationLocked() {
18674        Configuration configuration = new Configuration(mConfiguration);
18675        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18676                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18677        updateConfigurationLocked(configuration, null, false);
18678    }
18679
18680    boolean updateConfigurationLocked(Configuration values,
18681            ActivityRecord starting, boolean initLocale) {
18682        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18683        return updateConfigurationLocked(values, starting, initLocale, false,
18684                UserHandle.USER_NULL);
18685    }
18686
18687    // To cache the list of supported system locales
18688    private String[] mSupportedSystemLocales = null;
18689
18690    /**
18691     * Do either or both things: (1) change the current configuration, and (2)
18692     * make sure the given activity is running with the (now) current
18693     * configuration.  Returns true if the activity has been left running, or
18694     * false if <var>starting</var> is being destroyed to match the new
18695     * configuration.
18696     *
18697     * @param userId is only used when persistent parameter is set to true to persist configuration
18698     *               for that particular user
18699     */
18700    private boolean updateConfigurationLocked(Configuration values,
18701            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18702        int changes = 0;
18703
18704        if (mWindowManager != null) {
18705            mWindowManager.deferSurfaceLayout();
18706        }
18707        if (values != null) {
18708            Configuration newConfig = new Configuration(mConfiguration);
18709            changes = newConfig.updateFrom(values);
18710            if (changes != 0) {
18711                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18712                        "Updating configuration to: " + values);
18713
18714                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18715
18716                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18717                    final LocaleList locales = values.getLocales();
18718                    int bestLocaleIndex = 0;
18719                    if (locales.size() > 1) {
18720                        if (mSupportedSystemLocales == null) {
18721                            mSupportedSystemLocales =
18722                                    Resources.getSystem().getAssets().getLocales();
18723                        }
18724                        bestLocaleIndex = Math.max(0,
18725                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18726                    }
18727                    SystemProperties.set("persist.sys.locale",
18728                            locales.get(bestLocaleIndex).toLanguageTag());
18729                    LocaleList.setDefault(locales, bestLocaleIndex);
18730                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18731                            locales.get(bestLocaleIndex)));
18732                }
18733
18734                mConfigurationSeq++;
18735                if (mConfigurationSeq <= 0) {
18736                    mConfigurationSeq = 1;
18737                }
18738                newConfig.seq = mConfigurationSeq;
18739                mConfiguration = newConfig;
18740                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18741                mUsageStatsService.reportConfigurationChange(newConfig,
18742                        mUserController.getCurrentUserIdLocked());
18743                //mUsageStatsService.noteStartConfig(newConfig);
18744
18745                final Configuration configCopy = new Configuration(mConfiguration);
18746
18747                // TODO: If our config changes, should we auto dismiss any currently
18748                // showing dialogs?
18749                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18750
18751                AttributeCache ac = AttributeCache.instance();
18752                if (ac != null) {
18753                    ac.updateConfiguration(configCopy);
18754                }
18755
18756                // Make sure all resources in our process are updated
18757                // right now, so that anyone who is going to retrieve
18758                // resource values after we return will be sure to get
18759                // the new ones.  This is especially important during
18760                // boot, where the first config change needs to guarantee
18761                // all resources have that config before following boot
18762                // code is executed.
18763                mSystemThread.applyConfigurationToResources(configCopy);
18764
18765                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18766                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18767                    msg.obj = new Configuration(configCopy);
18768                    msg.arg1 = userId;
18769                    mHandler.sendMessage(msg);
18770                }
18771
18772                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18773                if (isDensityChange) {
18774                    // Reset the unsupported display size dialog.
18775                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18776
18777                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18778                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18779                }
18780
18781                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18782                    ProcessRecord app = mLruProcesses.get(i);
18783                    try {
18784                        if (app.thread != null) {
18785                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18786                                    + app.processName + " new config " + mConfiguration);
18787                            app.thread.scheduleConfigurationChanged(configCopy);
18788                        }
18789                    } catch (Exception e) {
18790                    }
18791                }
18792                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18793                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18794                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18795                        | Intent.FLAG_RECEIVER_FOREGROUND);
18796                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18797                        null, AppOpsManager.OP_NONE, null, false, false,
18798                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18799                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18800                    // Tell the shortcut manager that the system locale changed.  It needs to know
18801                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18802                    // we "push" from here, rather than having the service listen to the broadcast.
18803                    final ShortcutServiceInternal shortcutService =
18804                            LocalServices.getService(ShortcutServiceInternal.class);
18805                    if (shortcutService != null) {
18806                        shortcutService.onSystemLocaleChangedNoLock();
18807                    }
18808
18809                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18810                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18811                    if (!mProcessesReady) {
18812                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18813                    }
18814                    broadcastIntentLocked(null, null, intent,
18815                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18816                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18817                }
18818            }
18819            // Update the configuration with WM first and check if any of the stacks need to be
18820            // resized due to the configuration change. If so, resize the stacks now and do any
18821            // relaunches if necessary. This way we don't need to relaunch again below in
18822            // ensureActivityConfigurationLocked().
18823            if (mWindowManager != null) {
18824                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18825                if (resizedStacks != null) {
18826                    for (int stackId : resizedStacks) {
18827                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18828                        mStackSupervisor.resizeStackLocked(
18829                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18830                    }
18831                }
18832            }
18833        }
18834
18835        boolean kept = true;
18836        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18837        // mainStack is null during startup.
18838        if (mainStack != null) {
18839            if (changes != 0 && starting == null) {
18840                // If the configuration changed, and the caller is not already
18841                // in the process of starting an activity, then find the top
18842                // activity to check if its configuration needs to change.
18843                starting = mainStack.topRunningActivityLocked();
18844            }
18845
18846            if (starting != null) {
18847                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18848                // And we need to make sure at this point that all other activities
18849                // are made visible with the correct configuration.
18850                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18851                        !PRESERVE_WINDOWS);
18852            }
18853        }
18854        if (mWindowManager != null) {
18855            mWindowManager.continueSurfaceLayout();
18856        }
18857        return kept;
18858    }
18859
18860    /**
18861     * Decide based on the configuration whether we should shouw the ANR,
18862     * crash, etc dialogs.  The idea is that if there is no affordnace to
18863     * press the on-screen buttons, we shouldn't show the dialog.
18864     *
18865     * A thought: SystemUI might also want to get told about this, the Power
18866     * dialog / global actions also might want different behaviors.
18867     */
18868    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18869        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18870                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18871                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18872        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18873                                    == Configuration.UI_MODE_TYPE_CAR);
18874        return inputMethodExists && uiIsNotCarType && !inVrMode;
18875    }
18876
18877    @Override
18878    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18879        synchronized (this) {
18880            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18881            if (srec != null) {
18882                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18883            }
18884        }
18885        return false;
18886    }
18887
18888    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18889            Intent resultData) {
18890
18891        synchronized (this) {
18892            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18893            if (r != null) {
18894                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18895            }
18896            return false;
18897        }
18898    }
18899
18900    public int getLaunchedFromUid(IBinder activityToken) {
18901        ActivityRecord srec;
18902        synchronized (this) {
18903            srec = ActivityRecord.forTokenLocked(activityToken);
18904        }
18905        if (srec == null) {
18906            return -1;
18907        }
18908        return srec.launchedFromUid;
18909    }
18910
18911    public String getLaunchedFromPackage(IBinder activityToken) {
18912        ActivityRecord srec;
18913        synchronized (this) {
18914            srec = ActivityRecord.forTokenLocked(activityToken);
18915        }
18916        if (srec == null) {
18917            return null;
18918        }
18919        return srec.launchedFromPackage;
18920    }
18921
18922    // =========================================================
18923    // LIFETIME MANAGEMENT
18924    // =========================================================
18925
18926    // Returns which broadcast queue the app is the current [or imminent] receiver
18927    // on, or 'null' if the app is not an active broadcast recipient.
18928    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18929        BroadcastRecord r = app.curReceiver;
18930        if (r != null) {
18931            return r.queue;
18932        }
18933
18934        // It's not the current receiver, but it might be starting up to become one
18935        synchronized (this) {
18936            for (BroadcastQueue queue : mBroadcastQueues) {
18937                r = queue.mPendingBroadcast;
18938                if (r != null && r.curApp == app) {
18939                    // found it; report which queue it's in
18940                    return queue;
18941                }
18942            }
18943        }
18944
18945        return null;
18946    }
18947
18948    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18949            int targetUid, ComponentName targetComponent, String targetProcess) {
18950        if (!mTrackingAssociations) {
18951            return null;
18952        }
18953        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18954                = mAssociations.get(targetUid);
18955        if (components == null) {
18956            components = new ArrayMap<>();
18957            mAssociations.put(targetUid, components);
18958        }
18959        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18960        if (sourceUids == null) {
18961            sourceUids = new SparseArray<>();
18962            components.put(targetComponent, sourceUids);
18963        }
18964        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18965        if (sourceProcesses == null) {
18966            sourceProcesses = new ArrayMap<>();
18967            sourceUids.put(sourceUid, sourceProcesses);
18968        }
18969        Association ass = sourceProcesses.get(sourceProcess);
18970        if (ass == null) {
18971            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18972                    targetProcess);
18973            sourceProcesses.put(sourceProcess, ass);
18974        }
18975        ass.mCount++;
18976        ass.mNesting++;
18977        if (ass.mNesting == 1) {
18978            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18979            ass.mLastState = sourceState;
18980        }
18981        return ass;
18982    }
18983
18984    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18985            ComponentName targetComponent) {
18986        if (!mTrackingAssociations) {
18987            return;
18988        }
18989        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18990                = mAssociations.get(targetUid);
18991        if (components == null) {
18992            return;
18993        }
18994        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18995        if (sourceUids == null) {
18996            return;
18997        }
18998        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18999        if (sourceProcesses == null) {
19000            return;
19001        }
19002        Association ass = sourceProcesses.get(sourceProcess);
19003        if (ass == null || ass.mNesting <= 0) {
19004            return;
19005        }
19006        ass.mNesting--;
19007        if (ass.mNesting == 0) {
19008            long uptime = SystemClock.uptimeMillis();
19009            ass.mTime += uptime - ass.mStartTime;
19010            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19011                    += uptime - ass.mLastStateUptime;
19012            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19013        }
19014    }
19015
19016    private void noteUidProcessState(final int uid, final int state) {
19017        mBatteryStatsService.noteUidProcessState(uid, state);
19018        if (mTrackingAssociations) {
19019            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19020                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19021                        = mAssociations.valueAt(i1);
19022                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19023                    SparseArray<ArrayMap<String, Association>> sourceUids
19024                            = targetComponents.valueAt(i2);
19025                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19026                    if (sourceProcesses != null) {
19027                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19028                            Association ass = sourceProcesses.valueAt(i4);
19029                            if (ass.mNesting >= 1) {
19030                                // currently associated
19031                                long uptime = SystemClock.uptimeMillis();
19032                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19033                                        += uptime - ass.mLastStateUptime;
19034                                ass.mLastState = state;
19035                                ass.mLastStateUptime = uptime;
19036                            }
19037                        }
19038                    }
19039                }
19040            }
19041        }
19042    }
19043
19044    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19045            boolean doingAll, long now) {
19046        if (mAdjSeq == app.adjSeq) {
19047            // This adjustment has already been computed.
19048            return app.curRawAdj;
19049        }
19050
19051        if (app.thread == null) {
19052            app.adjSeq = mAdjSeq;
19053            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19054            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19055            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19056        }
19057
19058        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19059        app.adjSource = null;
19060        app.adjTarget = null;
19061        app.empty = false;
19062        app.cached = false;
19063
19064        final int activitiesSize = app.activities.size();
19065
19066        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19067            // The max adjustment doesn't allow this app to be anything
19068            // below foreground, so it is not worth doing work for it.
19069            app.adjType = "fixed";
19070            app.adjSeq = mAdjSeq;
19071            app.curRawAdj = app.maxAdj;
19072            app.foregroundActivities = false;
19073            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19074            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19075            // System processes can do UI, and when they do we want to have
19076            // them trim their memory after the user leaves the UI.  To
19077            // facilitate this, here we need to determine whether or not it
19078            // is currently showing UI.
19079            app.systemNoUi = true;
19080            if (app == TOP_APP) {
19081                app.systemNoUi = false;
19082                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19083                app.adjType = "pers-top-activity";
19084            } else if (activitiesSize > 0) {
19085                for (int j = 0; j < activitiesSize; j++) {
19086                    final ActivityRecord r = app.activities.get(j);
19087                    if (r.visible) {
19088                        app.systemNoUi = false;
19089                    }
19090                }
19091            }
19092            if (!app.systemNoUi) {
19093                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19094            }
19095            return (app.curAdj=app.maxAdj);
19096        }
19097
19098        app.systemNoUi = false;
19099
19100        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19101
19102        // Determine the importance of the process, starting with most
19103        // important to least, and assign an appropriate OOM adjustment.
19104        int adj;
19105        int schedGroup;
19106        int procState;
19107        boolean foregroundActivities = false;
19108        BroadcastQueue queue;
19109        if (app == TOP_APP) {
19110            // The last app on the list is the foreground app.
19111            adj = ProcessList.FOREGROUND_APP_ADJ;
19112            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19113            app.adjType = "top-activity";
19114            foregroundActivities = true;
19115            procState = PROCESS_STATE_CUR_TOP;
19116        } else if (app.instrumentationClass != null) {
19117            // Don't want to kill running instrumentation.
19118            adj = ProcessList.FOREGROUND_APP_ADJ;
19119            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19120            app.adjType = "instrumentation";
19121            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19122        } else if ((queue = isReceivingBroadcast(app)) != null) {
19123            // An app that is currently receiving a broadcast also
19124            // counts as being in the foreground for OOM killer purposes.
19125            // It's placed in a sched group based on the nature of the
19126            // broadcast as reflected by which queue it's active in.
19127            adj = ProcessList.FOREGROUND_APP_ADJ;
19128            schedGroup = (queue == mFgBroadcastQueue)
19129                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19130            app.adjType = "broadcast";
19131            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19132        } else if (app.executingServices.size() > 0) {
19133            // An app that is currently executing a service callback also
19134            // counts as being in the foreground.
19135            adj = ProcessList.FOREGROUND_APP_ADJ;
19136            schedGroup = app.execServicesFg ?
19137                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19138            app.adjType = "exec-service";
19139            procState = ActivityManager.PROCESS_STATE_SERVICE;
19140            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19141        } else {
19142            // As far as we know the process is empty.  We may change our mind later.
19143            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19144            // At this point we don't actually know the adjustment.  Use the cached adj
19145            // value that the caller wants us to.
19146            adj = cachedAdj;
19147            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19148            app.cached = true;
19149            app.empty = true;
19150            app.adjType = "cch-empty";
19151        }
19152
19153        // Examine all activities if not already foreground.
19154        if (!foregroundActivities && activitiesSize > 0) {
19155            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19156            for (int j = 0; j < activitiesSize; j++) {
19157                final ActivityRecord r = app.activities.get(j);
19158                if (r.app != app) {
19159                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19160                            + " instead of expected " + app);
19161                    if (r.app == null || (r.app.uid == app.uid)) {
19162                        // Only fix things up when they look sane
19163                        r.app = app;
19164                    } else {
19165                        continue;
19166                    }
19167                }
19168                if (r.visible) {
19169                    // App has a visible activity; only upgrade adjustment.
19170                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19171                        adj = ProcessList.VISIBLE_APP_ADJ;
19172                        app.adjType = "visible";
19173                    }
19174                    if (procState > PROCESS_STATE_CUR_TOP) {
19175                        procState = PROCESS_STATE_CUR_TOP;
19176                    }
19177                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19178                    app.cached = false;
19179                    app.empty = false;
19180                    foregroundActivities = true;
19181                    if (r.task != null && minLayer > 0) {
19182                        final int layer = r.task.mLayerRank;
19183                        if (layer >= 0 && minLayer > layer) {
19184                            minLayer = layer;
19185                        }
19186                    }
19187                    break;
19188                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19189                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19190                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19191                        app.adjType = "pausing";
19192                    }
19193                    if (procState > PROCESS_STATE_CUR_TOP) {
19194                        procState = PROCESS_STATE_CUR_TOP;
19195                    }
19196                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19197                    app.cached = false;
19198                    app.empty = false;
19199                    foregroundActivities = true;
19200                } else if (r.state == ActivityState.STOPPING) {
19201                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19202                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19203                        app.adjType = "stopping";
19204                    }
19205                    // For the process state, we will at this point consider the
19206                    // process to be cached.  It will be cached either as an activity
19207                    // or empty depending on whether the activity is finishing.  We do
19208                    // this so that we can treat the process as cached for purposes of
19209                    // memory trimming (determing current memory level, trim command to
19210                    // send to process) since there can be an arbitrary number of stopping
19211                    // processes and they should soon all go into the cached state.
19212                    if (!r.finishing) {
19213                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19214                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19215                        }
19216                    }
19217                    app.cached = false;
19218                    app.empty = false;
19219                    foregroundActivities = true;
19220                } else {
19221                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19222                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19223                        app.adjType = "cch-act";
19224                    }
19225                }
19226            }
19227            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19228                adj += minLayer;
19229            }
19230        }
19231
19232        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19233                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19234            if (app.foregroundServices) {
19235                // The user is aware of this app, so make it visible.
19236                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19237                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19238                app.cached = false;
19239                app.adjType = "fg-service";
19240                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19241            } else if (app.forcingToForeground != null) {
19242                // The user is aware of this app, so make it visible.
19243                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19244                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19245                app.cached = false;
19246                app.adjType = "force-fg";
19247                app.adjSource = app.forcingToForeground;
19248                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19249            }
19250        }
19251
19252        if (app == mHeavyWeightProcess) {
19253            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19254                // We don't want to kill the current heavy-weight process.
19255                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19256                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19257                app.cached = false;
19258                app.adjType = "heavy";
19259            }
19260            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19261                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19262            }
19263        }
19264
19265        if (app == mHomeProcess) {
19266            if (adj > ProcessList.HOME_APP_ADJ) {
19267                // This process is hosting what we currently consider to be the
19268                // home app, so we don't want to let it go into the background.
19269                adj = ProcessList.HOME_APP_ADJ;
19270                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19271                app.cached = false;
19272                app.adjType = "home";
19273            }
19274            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19275                procState = ActivityManager.PROCESS_STATE_HOME;
19276            }
19277        }
19278
19279        if (app == mPreviousProcess && app.activities.size() > 0) {
19280            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19281                // This was the previous process that showed UI to the user.
19282                // We want to try to keep it around more aggressively, to give
19283                // a good experience around switching between two apps.
19284                adj = ProcessList.PREVIOUS_APP_ADJ;
19285                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19286                app.cached = false;
19287                app.adjType = "previous";
19288            }
19289            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19290                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19291            }
19292        }
19293
19294        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19295                + " reason=" + app.adjType);
19296
19297        // By default, we use the computed adjustment.  It may be changed if
19298        // there are applications dependent on our services or providers, but
19299        // this gives us a baseline and makes sure we don't get into an
19300        // infinite recursion.
19301        app.adjSeq = mAdjSeq;
19302        app.curRawAdj = adj;
19303        app.hasStartedServices = false;
19304
19305        if (mBackupTarget != null && app == mBackupTarget.app) {
19306            // If possible we want to avoid killing apps while they're being backed up
19307            if (adj > ProcessList.BACKUP_APP_ADJ) {
19308                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19309                adj = ProcessList.BACKUP_APP_ADJ;
19310                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19311                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19312                }
19313                app.adjType = "backup";
19314                app.cached = false;
19315            }
19316            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19317                procState = ActivityManager.PROCESS_STATE_BACKUP;
19318            }
19319        }
19320
19321        boolean mayBeTop = false;
19322
19323        for (int is = app.services.size()-1;
19324                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19325                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19326                        || procState > ActivityManager.PROCESS_STATE_TOP);
19327                is--) {
19328            ServiceRecord s = app.services.valueAt(is);
19329            if (s.startRequested) {
19330                app.hasStartedServices = true;
19331                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19332                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19333                }
19334                if (app.hasShownUi && app != mHomeProcess) {
19335                    // If this process has shown some UI, let it immediately
19336                    // go to the LRU list because it may be pretty heavy with
19337                    // UI stuff.  We'll tag it with a label just to help
19338                    // debug and understand what is going on.
19339                    if (adj > ProcessList.SERVICE_ADJ) {
19340                        app.adjType = "cch-started-ui-services";
19341                    }
19342                } else {
19343                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19344                        // This service has seen some activity within
19345                        // recent memory, so we will keep its process ahead
19346                        // of the background processes.
19347                        if (adj > ProcessList.SERVICE_ADJ) {
19348                            adj = ProcessList.SERVICE_ADJ;
19349                            app.adjType = "started-services";
19350                            app.cached = false;
19351                        }
19352                    }
19353                    // If we have let the service slide into the background
19354                    // state, still have some text describing what it is doing
19355                    // even though the service no longer has an impact.
19356                    if (adj > ProcessList.SERVICE_ADJ) {
19357                        app.adjType = "cch-started-services";
19358                    }
19359                }
19360            }
19361
19362            for (int conni = s.connections.size()-1;
19363                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19364                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19365                            || procState > ActivityManager.PROCESS_STATE_TOP);
19366                    conni--) {
19367                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19368                for (int i = 0;
19369                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19370                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19371                                || procState > ActivityManager.PROCESS_STATE_TOP);
19372                        i++) {
19373                    // XXX should compute this based on the max of
19374                    // all connected clients.
19375                    ConnectionRecord cr = clist.get(i);
19376                    if (cr.binding.client == app) {
19377                        // Binding to ourself is not interesting.
19378                        continue;
19379                    }
19380
19381                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19382                        ProcessRecord client = cr.binding.client;
19383                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19384                                TOP_APP, doingAll, now);
19385                        int clientProcState = client.curProcState;
19386                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19387                            // If the other app is cached for any reason, for purposes here
19388                            // we are going to consider it empty.  The specific cached state
19389                            // doesn't propagate except under certain conditions.
19390                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19391                        }
19392                        String adjType = null;
19393                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19394                            // Not doing bind OOM management, so treat
19395                            // this guy more like a started service.
19396                            if (app.hasShownUi && app != mHomeProcess) {
19397                                // If this process has shown some UI, let it immediately
19398                                // go to the LRU list because it may be pretty heavy with
19399                                // UI stuff.  We'll tag it with a label just to help
19400                                // debug and understand what is going on.
19401                                if (adj > clientAdj) {
19402                                    adjType = "cch-bound-ui-services";
19403                                }
19404                                app.cached = false;
19405                                clientAdj = adj;
19406                                clientProcState = procState;
19407                            } else {
19408                                if (now >= (s.lastActivity
19409                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19410                                    // This service has not seen activity within
19411                                    // recent memory, so allow it to drop to the
19412                                    // LRU list if there is no other reason to keep
19413                                    // it around.  We'll also tag it with a label just
19414                                    // to help debug and undertand what is going on.
19415                                    if (adj > clientAdj) {
19416                                        adjType = "cch-bound-services";
19417                                    }
19418                                    clientAdj = adj;
19419                                }
19420                            }
19421                        }
19422                        if (adj > clientAdj) {
19423                            // If this process has recently shown UI, and
19424                            // the process that is binding to it is less
19425                            // important than being visible, then we don't
19426                            // care about the binding as much as we care
19427                            // about letting this process get into the LRU
19428                            // list to be killed and restarted if needed for
19429                            // memory.
19430                            if (app.hasShownUi && app != mHomeProcess
19431                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19432                                adjType = "cch-bound-ui-services";
19433                            } else {
19434                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19435                                        |Context.BIND_IMPORTANT)) != 0) {
19436                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19437                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19438                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19439                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19440                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19441                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19442                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19443                                    adj = clientAdj;
19444                                } else {
19445                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19446                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19447                                    }
19448                                }
19449                                if (!client.cached) {
19450                                    app.cached = false;
19451                                }
19452                                adjType = "service";
19453                            }
19454                        }
19455                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19456                            // This will treat important bound services identically to
19457                            // the top app, which may behave differently than generic
19458                            // foreground work.
19459                            if (client.curSchedGroup > schedGroup) {
19460                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19461                                    schedGroup = client.curSchedGroup;
19462                                } else {
19463                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19464                                }
19465                            }
19466                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19467                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19468                                    // Special handling of clients who are in the top state.
19469                                    // We *may* want to consider this process to be in the
19470                                    // top state as well, but only if there is not another
19471                                    // reason for it to be running.  Being on the top is a
19472                                    // special state, meaning you are specifically running
19473                                    // for the current top app.  If the process is already
19474                                    // running in the background for some other reason, it
19475                                    // is more important to continue considering it to be
19476                                    // in the background state.
19477                                    mayBeTop = true;
19478                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19479                                } else {
19480                                    // Special handling for above-top states (persistent
19481                                    // processes).  These should not bring the current process
19482                                    // into the top state, since they are not on top.  Instead
19483                                    // give them the best state after that.
19484                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19485                                        clientProcState =
19486                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19487                                    } else if (mWakefulness
19488                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19489                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19490                                                    != 0) {
19491                                        clientProcState =
19492                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19493                                    } else {
19494                                        clientProcState =
19495                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19496                                    }
19497                                }
19498                            }
19499                        } else {
19500                            if (clientProcState <
19501                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19502                                clientProcState =
19503                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19504                            }
19505                        }
19506                        if (procState > clientProcState) {
19507                            procState = clientProcState;
19508                        }
19509                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19510                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19511                            app.pendingUiClean = true;
19512                        }
19513                        if (adjType != null) {
19514                            app.adjType = adjType;
19515                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19516                                    .REASON_SERVICE_IN_USE;
19517                            app.adjSource = cr.binding.client;
19518                            app.adjSourceProcState = clientProcState;
19519                            app.adjTarget = s.name;
19520                        }
19521                    }
19522                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19523                        app.treatLikeActivity = true;
19524                    }
19525                    final ActivityRecord a = cr.activity;
19526                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19527                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19528                            (a.visible || a.state == ActivityState.RESUMED ||
19529                             a.state == ActivityState.PAUSING)) {
19530                            adj = ProcessList.FOREGROUND_APP_ADJ;
19531                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19532                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19533                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19534                                } else {
19535                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19536                                }
19537                            }
19538                            app.cached = false;
19539                            app.adjType = "service";
19540                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19541                                    .REASON_SERVICE_IN_USE;
19542                            app.adjSource = a;
19543                            app.adjSourceProcState = procState;
19544                            app.adjTarget = s.name;
19545                        }
19546                    }
19547                }
19548            }
19549        }
19550
19551        for (int provi = app.pubProviders.size()-1;
19552                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19553                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19554                        || procState > ActivityManager.PROCESS_STATE_TOP);
19555                provi--) {
19556            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19557            for (int i = cpr.connections.size()-1;
19558                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19559                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19560                            || procState > ActivityManager.PROCESS_STATE_TOP);
19561                    i--) {
19562                ContentProviderConnection conn = cpr.connections.get(i);
19563                ProcessRecord client = conn.client;
19564                if (client == app) {
19565                    // Being our own client is not interesting.
19566                    continue;
19567                }
19568                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19569                int clientProcState = client.curProcState;
19570                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19571                    // If the other app is cached for any reason, for purposes here
19572                    // we are going to consider it empty.
19573                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19574                }
19575                if (adj > clientAdj) {
19576                    if (app.hasShownUi && app != mHomeProcess
19577                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19578                        app.adjType = "cch-ui-provider";
19579                    } else {
19580                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19581                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19582                        app.adjType = "provider";
19583                    }
19584                    app.cached &= client.cached;
19585                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19586                            .REASON_PROVIDER_IN_USE;
19587                    app.adjSource = client;
19588                    app.adjSourceProcState = clientProcState;
19589                    app.adjTarget = cpr.name;
19590                }
19591                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19592                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19593                        // Special handling of clients who are in the top state.
19594                        // We *may* want to consider this process to be in the
19595                        // top state as well, but only if there is not another
19596                        // reason for it to be running.  Being on the top is a
19597                        // special state, meaning you are specifically running
19598                        // for the current top app.  If the process is already
19599                        // running in the background for some other reason, it
19600                        // is more important to continue considering it to be
19601                        // in the background state.
19602                        mayBeTop = true;
19603                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19604                    } else {
19605                        // Special handling for above-top states (persistent
19606                        // processes).  These should not bring the current process
19607                        // into the top state, since they are not on top.  Instead
19608                        // give them the best state after that.
19609                        clientProcState =
19610                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19611                    }
19612                }
19613                if (procState > clientProcState) {
19614                    procState = clientProcState;
19615                }
19616                if (client.curSchedGroup > schedGroup) {
19617                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19618                }
19619            }
19620            // If the provider has external (non-framework) process
19621            // dependencies, ensure that its adjustment is at least
19622            // FOREGROUND_APP_ADJ.
19623            if (cpr.hasExternalProcessHandles()) {
19624                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19625                    adj = ProcessList.FOREGROUND_APP_ADJ;
19626                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19627                    app.cached = false;
19628                    app.adjType = "provider";
19629                    app.adjTarget = cpr.name;
19630                }
19631                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19632                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19633                }
19634            }
19635        }
19636
19637        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19638            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19639                adj = ProcessList.PREVIOUS_APP_ADJ;
19640                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19641                app.cached = false;
19642                app.adjType = "provider";
19643            }
19644            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19645                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19646            }
19647        }
19648
19649        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19650            // A client of one of our services or providers is in the top state.  We
19651            // *may* want to be in the top state, but not if we are already running in
19652            // the background for some other reason.  For the decision here, we are going
19653            // to pick out a few specific states that we want to remain in when a client
19654            // is top (states that tend to be longer-term) and otherwise allow it to go
19655            // to the top state.
19656            switch (procState) {
19657                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19658                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19659                case ActivityManager.PROCESS_STATE_SERVICE:
19660                    // These all are longer-term states, so pull them up to the top
19661                    // of the background states, but not all the way to the top state.
19662                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19663                    break;
19664                default:
19665                    // Otherwise, top is a better choice, so take it.
19666                    procState = ActivityManager.PROCESS_STATE_TOP;
19667                    break;
19668            }
19669        }
19670
19671        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19672            if (app.hasClientActivities) {
19673                // This is a cached process, but with client activities.  Mark it so.
19674                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19675                app.adjType = "cch-client-act";
19676            } else if (app.treatLikeActivity) {
19677                // This is a cached process, but somebody wants us to treat it like it has
19678                // an activity, okay!
19679                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19680                app.adjType = "cch-as-act";
19681            }
19682        }
19683
19684        if (adj == ProcessList.SERVICE_ADJ) {
19685            if (doingAll) {
19686                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19687                mNewNumServiceProcs++;
19688                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19689                if (!app.serviceb) {
19690                    // This service isn't far enough down on the LRU list to
19691                    // normally be a B service, but if we are low on RAM and it
19692                    // is large we want to force it down since we would prefer to
19693                    // keep launcher over it.
19694                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19695                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19696                        app.serviceHighRam = true;
19697                        app.serviceb = true;
19698                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19699                    } else {
19700                        mNewNumAServiceProcs++;
19701                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19702                    }
19703                } else {
19704                    app.serviceHighRam = false;
19705                }
19706            }
19707            if (app.serviceb) {
19708                adj = ProcessList.SERVICE_B_ADJ;
19709            }
19710        }
19711
19712        app.curRawAdj = adj;
19713
19714        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19715        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19716        if (adj > app.maxAdj) {
19717            adj = app.maxAdj;
19718            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19719                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19720            }
19721        }
19722
19723        // Do final modification to adj.  Everything we do between here and applying
19724        // the final setAdj must be done in this function, because we will also use
19725        // it when computing the final cached adj later.  Note that we don't need to
19726        // worry about this for max adj above, since max adj will always be used to
19727        // keep it out of the cached vaues.
19728        app.curAdj = app.modifyRawOomAdj(adj);
19729        app.curSchedGroup = schedGroup;
19730        app.curProcState = procState;
19731        app.foregroundActivities = foregroundActivities;
19732
19733        return app.curRawAdj;
19734    }
19735
19736    /**
19737     * Record new PSS sample for a process.
19738     */
19739    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19740            long now) {
19741        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19742                swapPss * 1024);
19743        proc.lastPssTime = now;
19744        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19745        if (DEBUG_PSS) Slog.d(TAG_PSS,
19746                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19747                + " state=" + ProcessList.makeProcStateString(procState));
19748        if (proc.initialIdlePss == 0) {
19749            proc.initialIdlePss = pss;
19750        }
19751        proc.lastPss = pss;
19752        proc.lastSwapPss = swapPss;
19753        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19754            proc.lastCachedPss = pss;
19755            proc.lastCachedSwapPss = swapPss;
19756        }
19757
19758        final SparseArray<Pair<Long, String>> watchUids
19759                = mMemWatchProcesses.getMap().get(proc.processName);
19760        Long check = null;
19761        if (watchUids != null) {
19762            Pair<Long, String> val = watchUids.get(proc.uid);
19763            if (val == null) {
19764                val = watchUids.get(0);
19765            }
19766            if (val != null) {
19767                check = val.first;
19768            }
19769        }
19770        if (check != null) {
19771            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19772                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19773                if (!isDebuggable) {
19774                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19775                        isDebuggable = true;
19776                    }
19777                }
19778                if (isDebuggable) {
19779                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19780                    final ProcessRecord myProc = proc;
19781                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19782                    mMemWatchDumpProcName = proc.processName;
19783                    mMemWatchDumpFile = heapdumpFile.toString();
19784                    mMemWatchDumpPid = proc.pid;
19785                    mMemWatchDumpUid = proc.uid;
19786                    BackgroundThread.getHandler().post(new Runnable() {
19787                        @Override
19788                        public void run() {
19789                            revokeUriPermission(ActivityThread.currentActivityThread()
19790                                            .getApplicationThread(),
19791                                    DumpHeapActivity.JAVA_URI,
19792                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19793                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19794                                    UserHandle.myUserId());
19795                            ParcelFileDescriptor fd = null;
19796                            try {
19797                                heapdumpFile.delete();
19798                                fd = ParcelFileDescriptor.open(heapdumpFile,
19799                                        ParcelFileDescriptor.MODE_CREATE |
19800                                                ParcelFileDescriptor.MODE_TRUNCATE |
19801                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19802                                                ParcelFileDescriptor.MODE_APPEND);
19803                                IApplicationThread thread = myProc.thread;
19804                                if (thread != null) {
19805                                    try {
19806                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19807                                                "Requesting dump heap from "
19808                                                + myProc + " to " + heapdumpFile);
19809                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19810                                    } catch (RemoteException e) {
19811                                    }
19812                                }
19813                            } catch (FileNotFoundException e) {
19814                                e.printStackTrace();
19815                            } finally {
19816                                if (fd != null) {
19817                                    try {
19818                                        fd.close();
19819                                    } catch (IOException e) {
19820                                    }
19821                                }
19822                            }
19823                        }
19824                    });
19825                } else {
19826                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19827                            + ", but debugging not enabled");
19828                }
19829            }
19830        }
19831    }
19832
19833    /**
19834     * Schedule PSS collection of a process.
19835     */
19836    void requestPssLocked(ProcessRecord proc, int procState) {
19837        if (mPendingPssProcesses.contains(proc)) {
19838            return;
19839        }
19840        if (mPendingPssProcesses.size() == 0) {
19841            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19842        }
19843        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19844        proc.pssProcState = procState;
19845        mPendingPssProcesses.add(proc);
19846    }
19847
19848    /**
19849     * Schedule PSS collection of all processes.
19850     */
19851    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19852        if (!always) {
19853            if (now < (mLastFullPssTime +
19854                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19855                return;
19856            }
19857        }
19858        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19859        mLastFullPssTime = now;
19860        mFullPssPending = true;
19861        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19862        mPendingPssProcesses.clear();
19863        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19864            ProcessRecord app = mLruProcesses.get(i);
19865            if (app.thread == null
19866                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19867                continue;
19868            }
19869            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19870                app.pssProcState = app.setProcState;
19871                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19872                        mTestPssMode, isSleepingLocked(), now);
19873                mPendingPssProcesses.add(app);
19874            }
19875        }
19876        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19877    }
19878
19879    public void setTestPssMode(boolean enabled) {
19880        synchronized (this) {
19881            mTestPssMode = enabled;
19882            if (enabled) {
19883                // Whenever we enable the mode, we want to take a snapshot all of current
19884                // process mem use.
19885                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19886            }
19887        }
19888    }
19889
19890    /**
19891     * Ask a given process to GC right now.
19892     */
19893    final void performAppGcLocked(ProcessRecord app) {
19894        try {
19895            app.lastRequestedGc = SystemClock.uptimeMillis();
19896            if (app.thread != null) {
19897                if (app.reportLowMemory) {
19898                    app.reportLowMemory = false;
19899                    app.thread.scheduleLowMemory();
19900                } else {
19901                    app.thread.processInBackground();
19902                }
19903            }
19904        } catch (Exception e) {
19905            // whatever.
19906        }
19907    }
19908
19909    /**
19910     * Returns true if things are idle enough to perform GCs.
19911     */
19912    private final boolean canGcNowLocked() {
19913        boolean processingBroadcasts = false;
19914        for (BroadcastQueue q : mBroadcastQueues) {
19915            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19916                processingBroadcasts = true;
19917            }
19918        }
19919        return !processingBroadcasts
19920                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19921    }
19922
19923    /**
19924     * Perform GCs on all processes that are waiting for it, but only
19925     * if things are idle.
19926     */
19927    final void performAppGcsLocked() {
19928        final int N = mProcessesToGc.size();
19929        if (N <= 0) {
19930            return;
19931        }
19932        if (canGcNowLocked()) {
19933            while (mProcessesToGc.size() > 0) {
19934                ProcessRecord proc = mProcessesToGc.remove(0);
19935                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19936                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19937                            <= SystemClock.uptimeMillis()) {
19938                        // To avoid spamming the system, we will GC processes one
19939                        // at a time, waiting a few seconds between each.
19940                        performAppGcLocked(proc);
19941                        scheduleAppGcsLocked();
19942                        return;
19943                    } else {
19944                        // It hasn't been long enough since we last GCed this
19945                        // process...  put it in the list to wait for its time.
19946                        addProcessToGcListLocked(proc);
19947                        break;
19948                    }
19949                }
19950            }
19951
19952            scheduleAppGcsLocked();
19953        }
19954    }
19955
19956    /**
19957     * If all looks good, perform GCs on all processes waiting for them.
19958     */
19959    final void performAppGcsIfAppropriateLocked() {
19960        if (canGcNowLocked()) {
19961            performAppGcsLocked();
19962            return;
19963        }
19964        // Still not idle, wait some more.
19965        scheduleAppGcsLocked();
19966    }
19967
19968    /**
19969     * Schedule the execution of all pending app GCs.
19970     */
19971    final void scheduleAppGcsLocked() {
19972        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19973
19974        if (mProcessesToGc.size() > 0) {
19975            // Schedule a GC for the time to the next process.
19976            ProcessRecord proc = mProcessesToGc.get(0);
19977            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19978
19979            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19980            long now = SystemClock.uptimeMillis();
19981            if (when < (now+GC_TIMEOUT)) {
19982                when = now + GC_TIMEOUT;
19983            }
19984            mHandler.sendMessageAtTime(msg, when);
19985        }
19986    }
19987
19988    /**
19989     * Add a process to the array of processes waiting to be GCed.  Keeps the
19990     * list in sorted order by the last GC time.  The process can't already be
19991     * on the list.
19992     */
19993    final void addProcessToGcListLocked(ProcessRecord proc) {
19994        boolean added = false;
19995        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19996            if (mProcessesToGc.get(i).lastRequestedGc <
19997                    proc.lastRequestedGc) {
19998                added = true;
19999                mProcessesToGc.add(i+1, proc);
20000                break;
20001            }
20002        }
20003        if (!added) {
20004            mProcessesToGc.add(0, proc);
20005        }
20006    }
20007
20008    /**
20009     * Set up to ask a process to GC itself.  This will either do it
20010     * immediately, or put it on the list of processes to gc the next
20011     * time things are idle.
20012     */
20013    final void scheduleAppGcLocked(ProcessRecord app) {
20014        long now = SystemClock.uptimeMillis();
20015        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20016            return;
20017        }
20018        if (!mProcessesToGc.contains(app)) {
20019            addProcessToGcListLocked(app);
20020            scheduleAppGcsLocked();
20021        }
20022    }
20023
20024    final void checkExcessivePowerUsageLocked(boolean doKills) {
20025        updateCpuStatsNow();
20026
20027        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20028        boolean doWakeKills = doKills;
20029        boolean doCpuKills = doKills;
20030        if (mLastPowerCheckRealtime == 0) {
20031            doWakeKills = false;
20032        }
20033        if (mLastPowerCheckUptime == 0) {
20034            doCpuKills = false;
20035        }
20036        if (stats.isScreenOn()) {
20037            doWakeKills = false;
20038        }
20039        final long curRealtime = SystemClock.elapsedRealtime();
20040        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20041        final long curUptime = SystemClock.uptimeMillis();
20042        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20043        mLastPowerCheckRealtime = curRealtime;
20044        mLastPowerCheckUptime = curUptime;
20045        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20046            doWakeKills = false;
20047        }
20048        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20049            doCpuKills = false;
20050        }
20051        int i = mLruProcesses.size();
20052        while (i > 0) {
20053            i--;
20054            ProcessRecord app = mLruProcesses.get(i);
20055            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20056                long wtime;
20057                synchronized (stats) {
20058                    wtime = stats.getProcessWakeTime(app.info.uid,
20059                            app.pid, curRealtime);
20060                }
20061                long wtimeUsed = wtime - app.lastWakeTime;
20062                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20063                if (DEBUG_POWER) {
20064                    StringBuilder sb = new StringBuilder(128);
20065                    sb.append("Wake for ");
20066                    app.toShortString(sb);
20067                    sb.append(": over ");
20068                    TimeUtils.formatDuration(realtimeSince, sb);
20069                    sb.append(" used ");
20070                    TimeUtils.formatDuration(wtimeUsed, sb);
20071                    sb.append(" (");
20072                    sb.append((wtimeUsed*100)/realtimeSince);
20073                    sb.append("%)");
20074                    Slog.i(TAG_POWER, sb.toString());
20075                    sb.setLength(0);
20076                    sb.append("CPU for ");
20077                    app.toShortString(sb);
20078                    sb.append(": over ");
20079                    TimeUtils.formatDuration(uptimeSince, sb);
20080                    sb.append(" used ");
20081                    TimeUtils.formatDuration(cputimeUsed, sb);
20082                    sb.append(" (");
20083                    sb.append((cputimeUsed*100)/uptimeSince);
20084                    sb.append("%)");
20085                    Slog.i(TAG_POWER, sb.toString());
20086                }
20087                // If a process has held a wake lock for more
20088                // than 50% of the time during this period,
20089                // that sounds bad.  Kill!
20090                if (doWakeKills && realtimeSince > 0
20091                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20092                    synchronized (stats) {
20093                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20094                                realtimeSince, wtimeUsed);
20095                    }
20096                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20097                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20098                } else if (doCpuKills && uptimeSince > 0
20099                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20100                    synchronized (stats) {
20101                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20102                                uptimeSince, cputimeUsed);
20103                    }
20104                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20105                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20106                } else {
20107                    app.lastWakeTime = wtime;
20108                    app.lastCpuTime = app.curCpuTime;
20109                }
20110            }
20111        }
20112    }
20113
20114    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20115            long nowElapsed) {
20116        boolean success = true;
20117
20118        if (app.curRawAdj != app.setRawAdj) {
20119            app.setRawAdj = app.curRawAdj;
20120        }
20121
20122        int changes = 0;
20123
20124        if (app.curAdj != app.setAdj) {
20125            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20126            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20127                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20128                    + app.adjType);
20129            app.setAdj = app.curAdj;
20130            app.verifiedAdj = ProcessList.INVALID_ADJ;
20131        }
20132
20133        if (app.setSchedGroup != app.curSchedGroup) {
20134            app.setSchedGroup = app.curSchedGroup;
20135            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20136                    "Setting sched group of " + app.processName
20137                    + " to " + app.curSchedGroup);
20138            if (app.waitingToKill != null && app.curReceiver == null
20139                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20140                app.kill(app.waitingToKill, true);
20141                success = false;
20142            } else {
20143                int processGroup;
20144                switch (app.curSchedGroup) {
20145                    case ProcessList.SCHED_GROUP_BACKGROUND:
20146                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20147                        break;
20148                    case ProcessList.SCHED_GROUP_TOP_APP:
20149                        processGroup = Process.THREAD_GROUP_TOP_APP;
20150                        break;
20151                    default:
20152                        processGroup = Process.THREAD_GROUP_DEFAULT;
20153                        break;
20154                }
20155                if (true) {
20156                    long oldId = Binder.clearCallingIdentity();
20157                    try {
20158                        Process.setProcessGroup(app.pid, processGroup);
20159                    } catch (Exception e) {
20160                        Slog.w(TAG, "Failed setting process group of " + app.pid
20161                                + " to " + app.curSchedGroup);
20162                        e.printStackTrace();
20163                    } finally {
20164                        Binder.restoreCallingIdentity(oldId);
20165                    }
20166                } else {
20167                    if (app.thread != null) {
20168                        try {
20169                            app.thread.setSchedulingGroup(processGroup);
20170                        } catch (RemoteException e) {
20171                        }
20172                    }
20173                }
20174            }
20175        }
20176        if (app.repForegroundActivities != app.foregroundActivities) {
20177            app.repForegroundActivities = app.foregroundActivities;
20178            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20179        }
20180        if (app.repProcState != app.curProcState) {
20181            app.repProcState = app.curProcState;
20182            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20183            if (app.thread != null) {
20184                try {
20185                    if (false) {
20186                        //RuntimeException h = new RuntimeException("here");
20187                        Slog.i(TAG, "Sending new process state " + app.repProcState
20188                                + " to " + app /*, h*/);
20189                    }
20190                    app.thread.setProcessState(app.repProcState);
20191                } catch (RemoteException e) {
20192                }
20193            }
20194        }
20195        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20196                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20197            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20198                // Experimental code to more aggressively collect pss while
20199                // running test...  the problem is that this tends to collect
20200                // the data right when a process is transitioning between process
20201                // states, which well tend to give noisy data.
20202                long start = SystemClock.uptimeMillis();
20203                long pss = Debug.getPss(app.pid, mTmpLong, null);
20204                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20205                mPendingPssProcesses.remove(app);
20206                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20207                        + " to " + app.curProcState + ": "
20208                        + (SystemClock.uptimeMillis()-start) + "ms");
20209            }
20210            app.lastStateTime = now;
20211            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20212                    mTestPssMode, isSleepingLocked(), now);
20213            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20214                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20215                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20216                    + (app.nextPssTime-now) + ": " + app);
20217        } else {
20218            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20219                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20220                    mTestPssMode)))) {
20221                requestPssLocked(app, app.setProcState);
20222                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20223                        mTestPssMode, isSleepingLocked(), now);
20224            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20225                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20226        }
20227        if (app.setProcState != app.curProcState) {
20228            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20229                    "Proc state change of " + app.processName
20230                            + " to " + app.curProcState);
20231            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20232            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20233            if (setImportant && !curImportant) {
20234                // This app is no longer something we consider important enough to allow to
20235                // use arbitrary amounts of battery power.  Note
20236                // its current wake lock time to later know to kill it if
20237                // it is not behaving well.
20238                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20239                synchronized (stats) {
20240                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20241                            app.pid, nowElapsed);
20242                }
20243                app.lastCpuTime = app.curCpuTime;
20244
20245            }
20246            // Inform UsageStats of important process state change
20247            // Must be called before updating setProcState
20248            maybeUpdateUsageStatsLocked(app, nowElapsed);
20249
20250            app.setProcState = app.curProcState;
20251            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20252                app.notCachedSinceIdle = false;
20253            }
20254            if (!doingAll) {
20255                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20256            } else {
20257                app.procStateChanged = true;
20258            }
20259        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20260                > USAGE_STATS_INTERACTION_INTERVAL) {
20261            // For apps that sit around for a long time in the interactive state, we need
20262            // to report this at least once a day so they don't go idle.
20263            maybeUpdateUsageStatsLocked(app, nowElapsed);
20264        }
20265
20266        if (changes != 0) {
20267            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20268                    "Changes in " + app + ": " + changes);
20269            int i = mPendingProcessChanges.size()-1;
20270            ProcessChangeItem item = null;
20271            while (i >= 0) {
20272                item = mPendingProcessChanges.get(i);
20273                if (item.pid == app.pid) {
20274                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20275                            "Re-using existing item: " + item);
20276                    break;
20277                }
20278                i--;
20279            }
20280            if (i < 0) {
20281                // No existing item in pending changes; need a new one.
20282                final int NA = mAvailProcessChanges.size();
20283                if (NA > 0) {
20284                    item = mAvailProcessChanges.remove(NA-1);
20285                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20286                            "Retrieving available item: " + item);
20287                } else {
20288                    item = new ProcessChangeItem();
20289                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20290                            "Allocating new item: " + item);
20291                }
20292                item.changes = 0;
20293                item.pid = app.pid;
20294                item.uid = app.info.uid;
20295                if (mPendingProcessChanges.size() == 0) {
20296                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20297                            "*** Enqueueing dispatch processes changed!");
20298                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20299                }
20300                mPendingProcessChanges.add(item);
20301            }
20302            item.changes |= changes;
20303            item.processState = app.repProcState;
20304            item.foregroundActivities = app.repForegroundActivities;
20305            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20306                    "Item " + Integer.toHexString(System.identityHashCode(item))
20307                    + " " + app.toShortString() + ": changes=" + item.changes
20308                    + " procState=" + item.processState
20309                    + " foreground=" + item.foregroundActivities
20310                    + " type=" + app.adjType + " source=" + app.adjSource
20311                    + " target=" + app.adjTarget);
20312        }
20313
20314        return success;
20315    }
20316
20317    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20318        final UidRecord.ChangeItem pendingChange;
20319        if (uidRec == null || uidRec.pendingChange == null) {
20320            if (mPendingUidChanges.size() == 0) {
20321                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20322                        "*** Enqueueing dispatch uid changed!");
20323                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20324            }
20325            final int NA = mAvailUidChanges.size();
20326            if (NA > 0) {
20327                pendingChange = mAvailUidChanges.remove(NA-1);
20328                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20329                        "Retrieving available item: " + pendingChange);
20330            } else {
20331                pendingChange = new UidRecord.ChangeItem();
20332                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20333                        "Allocating new item: " + pendingChange);
20334            }
20335            if (uidRec != null) {
20336                uidRec.pendingChange = pendingChange;
20337                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20338                    // If this uid is going away, and we haven't yet reported it is gone,
20339                    // then do so now.
20340                    change = UidRecord.CHANGE_GONE_IDLE;
20341                }
20342            } else if (uid < 0) {
20343                throw new IllegalArgumentException("No UidRecord or uid");
20344            }
20345            pendingChange.uidRecord = uidRec;
20346            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20347            mPendingUidChanges.add(pendingChange);
20348        } else {
20349            pendingChange = uidRec.pendingChange;
20350            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20351                change = UidRecord.CHANGE_GONE_IDLE;
20352            }
20353        }
20354        pendingChange.change = change;
20355        pendingChange.processState = uidRec != null
20356                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20357    }
20358
20359    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20360            String authority) {
20361        if (app == null) return;
20362        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20363            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20364            if (userState == null) return;
20365            final long now = SystemClock.elapsedRealtime();
20366            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20367            if (lastReported == null || lastReported < now - 60 * 1000L) {
20368                mUsageStatsService.reportContentProviderUsage(
20369                        authority, providerPkgName, app.userId);
20370                userState.mProviderLastReportedFg.put(authority, now);
20371            }
20372        }
20373    }
20374
20375    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20376        if (DEBUG_USAGE_STATS) {
20377            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20378                    + "] state changes: old = " + app.setProcState + ", new = "
20379                    + app.curProcState);
20380        }
20381        if (mUsageStatsService == null) {
20382            return;
20383        }
20384        boolean isInteraction;
20385        // To avoid some abuse patterns, we are going to be careful about what we consider
20386        // to be an app interaction.  Being the top activity doesn't count while the display
20387        // is sleeping, nor do short foreground services.
20388        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20389            isInteraction = true;
20390            app.fgInteractionTime = 0;
20391        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20392            if (app.fgInteractionTime == 0) {
20393                app.fgInteractionTime = nowElapsed;
20394                isInteraction = false;
20395            } else {
20396                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20397            }
20398        } else {
20399            isInteraction = app.curProcState
20400                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20401            app.fgInteractionTime = 0;
20402        }
20403        if (isInteraction && (!app.reportedInteraction
20404                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20405            app.interactionEventTime = nowElapsed;
20406            String[] packages = app.getPackageList();
20407            if (packages != null) {
20408                for (int i = 0; i < packages.length; i++) {
20409                    mUsageStatsService.reportEvent(packages[i], app.userId,
20410                            UsageEvents.Event.SYSTEM_INTERACTION);
20411                }
20412            }
20413        }
20414        app.reportedInteraction = isInteraction;
20415        if (!isInteraction) {
20416            app.interactionEventTime = 0;
20417        }
20418    }
20419
20420    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20421        if (proc.thread != null) {
20422            if (proc.baseProcessTracker != null) {
20423                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20424            }
20425        }
20426    }
20427
20428    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20429            ProcessRecord TOP_APP, boolean doingAll, long now) {
20430        if (app.thread == null) {
20431            return false;
20432        }
20433
20434        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20435
20436        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20437    }
20438
20439    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20440            boolean oomAdj) {
20441        if (isForeground != proc.foregroundServices) {
20442            proc.foregroundServices = isForeground;
20443            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20444                    proc.info.uid);
20445            if (isForeground) {
20446                if (curProcs == null) {
20447                    curProcs = new ArrayList<ProcessRecord>();
20448                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20449                }
20450                if (!curProcs.contains(proc)) {
20451                    curProcs.add(proc);
20452                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20453                            proc.info.packageName, proc.info.uid);
20454                }
20455            } else {
20456                if (curProcs != null) {
20457                    if (curProcs.remove(proc)) {
20458                        mBatteryStatsService.noteEvent(
20459                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20460                                proc.info.packageName, proc.info.uid);
20461                        if (curProcs.size() <= 0) {
20462                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20463                        }
20464                    }
20465                }
20466            }
20467            if (oomAdj) {
20468                updateOomAdjLocked();
20469            }
20470        }
20471    }
20472
20473    private final ActivityRecord resumedAppLocked() {
20474        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20475        String pkg;
20476        int uid;
20477        if (act != null) {
20478            pkg = act.packageName;
20479            uid = act.info.applicationInfo.uid;
20480        } else {
20481            pkg = null;
20482            uid = -1;
20483        }
20484        // Has the UID or resumed package name changed?
20485        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20486                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20487            if (mCurResumedPackage != null) {
20488                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20489                        mCurResumedPackage, mCurResumedUid);
20490            }
20491            mCurResumedPackage = pkg;
20492            mCurResumedUid = uid;
20493            if (mCurResumedPackage != null) {
20494                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20495                        mCurResumedPackage, mCurResumedUid);
20496            }
20497        }
20498        return act;
20499    }
20500
20501    final boolean updateOomAdjLocked(ProcessRecord app) {
20502        final ActivityRecord TOP_ACT = resumedAppLocked();
20503        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20504        final boolean wasCached = app.cached;
20505
20506        mAdjSeq++;
20507
20508        // This is the desired cached adjusment we want to tell it to use.
20509        // If our app is currently cached, we know it, and that is it.  Otherwise,
20510        // we don't know it yet, and it needs to now be cached we will then
20511        // need to do a complete oom adj.
20512        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20513                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20514        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20515                SystemClock.uptimeMillis());
20516        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20517            // Changed to/from cached state, so apps after it in the LRU
20518            // list may also be changed.
20519            updateOomAdjLocked();
20520        }
20521        return success;
20522    }
20523
20524    final void updateOomAdjLocked() {
20525        final ActivityRecord TOP_ACT = resumedAppLocked();
20526        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20527        final long now = SystemClock.uptimeMillis();
20528        final long nowElapsed = SystemClock.elapsedRealtime();
20529        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20530        final int N = mLruProcesses.size();
20531
20532        if (false) {
20533            RuntimeException e = new RuntimeException();
20534            e.fillInStackTrace();
20535            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20536        }
20537
20538        // Reset state in all uid records.
20539        for (int i=mActiveUids.size()-1; i>=0; i--) {
20540            final UidRecord uidRec = mActiveUids.valueAt(i);
20541            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20542                    "Starting update of " + uidRec);
20543            uidRec.reset();
20544        }
20545
20546        mStackSupervisor.rankTaskLayersIfNeeded();
20547
20548        mAdjSeq++;
20549        mNewNumServiceProcs = 0;
20550        mNewNumAServiceProcs = 0;
20551
20552        final int emptyProcessLimit;
20553        final int cachedProcessLimit;
20554        if (mProcessLimit <= 0) {
20555            emptyProcessLimit = cachedProcessLimit = 0;
20556        } else if (mProcessLimit == 1) {
20557            emptyProcessLimit = 1;
20558            cachedProcessLimit = 0;
20559        } else {
20560            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20561            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20562        }
20563
20564        // Let's determine how many processes we have running vs.
20565        // how many slots we have for background processes; we may want
20566        // to put multiple processes in a slot of there are enough of
20567        // them.
20568        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20569                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20570        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20571        if (numEmptyProcs > cachedProcessLimit) {
20572            // If there are more empty processes than our limit on cached
20573            // processes, then use the cached process limit for the factor.
20574            // This ensures that the really old empty processes get pushed
20575            // down to the bottom, so if we are running low on memory we will
20576            // have a better chance at keeping around more cached processes
20577            // instead of a gazillion empty processes.
20578            numEmptyProcs = cachedProcessLimit;
20579        }
20580        int emptyFactor = numEmptyProcs/numSlots;
20581        if (emptyFactor < 1) emptyFactor = 1;
20582        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20583        if (cachedFactor < 1) cachedFactor = 1;
20584        int stepCached = 0;
20585        int stepEmpty = 0;
20586        int numCached = 0;
20587        int numEmpty = 0;
20588        int numTrimming = 0;
20589
20590        mNumNonCachedProcs = 0;
20591        mNumCachedHiddenProcs = 0;
20592
20593        // First update the OOM adjustment for each of the
20594        // application processes based on their current state.
20595        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20596        int nextCachedAdj = curCachedAdj+1;
20597        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20598        int nextEmptyAdj = curEmptyAdj+2;
20599        for (int i=N-1; i>=0; i--) {
20600            ProcessRecord app = mLruProcesses.get(i);
20601            if (!app.killedByAm && app.thread != null) {
20602                app.procStateChanged = false;
20603                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20604
20605                // If we haven't yet assigned the final cached adj
20606                // to the process, do that now.
20607                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20608                    switch (app.curProcState) {
20609                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20610                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20611                            // This process is a cached process holding activities...
20612                            // assign it the next cached value for that type, and then
20613                            // step that cached level.
20614                            app.curRawAdj = curCachedAdj;
20615                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20616                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20617                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20618                                    + ")");
20619                            if (curCachedAdj != nextCachedAdj) {
20620                                stepCached++;
20621                                if (stepCached >= cachedFactor) {
20622                                    stepCached = 0;
20623                                    curCachedAdj = nextCachedAdj;
20624                                    nextCachedAdj += 2;
20625                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20626                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20627                                    }
20628                                }
20629                            }
20630                            break;
20631                        default:
20632                            // For everything else, assign next empty cached process
20633                            // level and bump that up.  Note that this means that
20634                            // long-running services that have dropped down to the
20635                            // cached level will be treated as empty (since their process
20636                            // state is still as a service), which is what we want.
20637                            app.curRawAdj = curEmptyAdj;
20638                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20639                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20640                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20641                                    + ")");
20642                            if (curEmptyAdj != nextEmptyAdj) {
20643                                stepEmpty++;
20644                                if (stepEmpty >= emptyFactor) {
20645                                    stepEmpty = 0;
20646                                    curEmptyAdj = nextEmptyAdj;
20647                                    nextEmptyAdj += 2;
20648                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20649                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20650                                    }
20651                                }
20652                            }
20653                            break;
20654                    }
20655                }
20656
20657                applyOomAdjLocked(app, true, now, nowElapsed);
20658
20659                // Count the number of process types.
20660                switch (app.curProcState) {
20661                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20662                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20663                        mNumCachedHiddenProcs++;
20664                        numCached++;
20665                        if (numCached > cachedProcessLimit) {
20666                            app.kill("cached #" + numCached, true);
20667                        }
20668                        break;
20669                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20670                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20671                                && app.lastActivityTime < oldTime) {
20672                            app.kill("empty for "
20673                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20674                                    / 1000) + "s", true);
20675                        } else {
20676                            numEmpty++;
20677                            if (numEmpty > emptyProcessLimit) {
20678                                app.kill("empty #" + numEmpty, true);
20679                            }
20680                        }
20681                        break;
20682                    default:
20683                        mNumNonCachedProcs++;
20684                        break;
20685                }
20686
20687                if (app.isolated && app.services.size() <= 0) {
20688                    // If this is an isolated process, and there are no
20689                    // services running in it, then the process is no longer
20690                    // needed.  We agressively kill these because we can by
20691                    // definition not re-use the same process again, and it is
20692                    // good to avoid having whatever code was running in them
20693                    // left sitting around after no longer needed.
20694                    app.kill("isolated not needed", true);
20695                } else {
20696                    // Keeping this process, update its uid.
20697                    final UidRecord uidRec = app.uidRecord;
20698                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20699                        uidRec.curProcState = app.curProcState;
20700                    }
20701                }
20702
20703                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20704                        && !app.killedByAm) {
20705                    numTrimming++;
20706                }
20707            }
20708        }
20709
20710        mNumServiceProcs = mNewNumServiceProcs;
20711
20712        // Now determine the memory trimming level of background processes.
20713        // Unfortunately we need to start at the back of the list to do this
20714        // properly.  We only do this if the number of background apps we
20715        // are managing to keep around is less than half the maximum we desire;
20716        // if we are keeping a good number around, we'll let them use whatever
20717        // memory they want.
20718        final int numCachedAndEmpty = numCached + numEmpty;
20719        int memFactor;
20720        if (numCached <= ProcessList.TRIM_CACHED_APPS
20721                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20722            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20723                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20724            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20725                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20726            } else {
20727                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20728            }
20729        } else {
20730            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20731        }
20732        // We always allow the memory level to go up (better).  We only allow it to go
20733        // down if we are in a state where that is allowed, *and* the total number of processes
20734        // has gone down since last time.
20735        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20736                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20737                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20738        if (memFactor > mLastMemoryLevel) {
20739            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20740                memFactor = mLastMemoryLevel;
20741                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20742            }
20743        }
20744        if (memFactor != mLastMemoryLevel) {
20745            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20746        }
20747        mLastMemoryLevel = memFactor;
20748        mLastNumProcesses = mLruProcesses.size();
20749        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20750        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20751        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20752            if (mLowRamStartTime == 0) {
20753                mLowRamStartTime = now;
20754            }
20755            int step = 0;
20756            int fgTrimLevel;
20757            switch (memFactor) {
20758                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20759                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20760                    break;
20761                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20762                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20763                    break;
20764                default:
20765                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20766                    break;
20767            }
20768            int factor = numTrimming/3;
20769            int minFactor = 2;
20770            if (mHomeProcess != null) minFactor++;
20771            if (mPreviousProcess != null) minFactor++;
20772            if (factor < minFactor) factor = minFactor;
20773            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20774            for (int i=N-1; i>=0; i--) {
20775                ProcessRecord app = mLruProcesses.get(i);
20776                if (allChanged || app.procStateChanged) {
20777                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20778                    app.procStateChanged = false;
20779                }
20780                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20781                        && !app.killedByAm) {
20782                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20783                        try {
20784                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20785                                    "Trimming memory of " + app.processName + " to " + curLevel);
20786                            app.thread.scheduleTrimMemory(curLevel);
20787                        } catch (RemoteException e) {
20788                        }
20789                        if (false) {
20790                            // For now we won't do this; our memory trimming seems
20791                            // to be good enough at this point that destroying
20792                            // activities causes more harm than good.
20793                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20794                                    && app != mHomeProcess && app != mPreviousProcess) {
20795                                // Need to do this on its own message because the stack may not
20796                                // be in a consistent state at this point.
20797                                // For these apps we will also finish their activities
20798                                // to help them free memory.
20799                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20800                            }
20801                        }
20802                    }
20803                    app.trimMemoryLevel = curLevel;
20804                    step++;
20805                    if (step >= factor) {
20806                        step = 0;
20807                        switch (curLevel) {
20808                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20809                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20810                                break;
20811                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20812                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20813                                break;
20814                        }
20815                    }
20816                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20817                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20818                            && app.thread != null) {
20819                        try {
20820                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20821                                    "Trimming memory of heavy-weight " + app.processName
20822                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20823                            app.thread.scheduleTrimMemory(
20824                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20825                        } catch (RemoteException e) {
20826                        }
20827                    }
20828                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20829                } else {
20830                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20831                            || app.systemNoUi) && app.pendingUiClean) {
20832                        // If this application is now in the background and it
20833                        // had done UI, then give it the special trim level to
20834                        // have it free UI resources.
20835                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20836                        if (app.trimMemoryLevel < level && app.thread != null) {
20837                            try {
20838                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20839                                        "Trimming memory of bg-ui " + app.processName
20840                                        + " to " + level);
20841                                app.thread.scheduleTrimMemory(level);
20842                            } catch (RemoteException e) {
20843                            }
20844                        }
20845                        app.pendingUiClean = false;
20846                    }
20847                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20848                        try {
20849                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20850                                    "Trimming memory of fg " + app.processName
20851                                    + " to " + fgTrimLevel);
20852                            app.thread.scheduleTrimMemory(fgTrimLevel);
20853                        } catch (RemoteException e) {
20854                        }
20855                    }
20856                    app.trimMemoryLevel = fgTrimLevel;
20857                }
20858            }
20859        } else {
20860            if (mLowRamStartTime != 0) {
20861                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20862                mLowRamStartTime = 0;
20863            }
20864            for (int i=N-1; i>=0; i--) {
20865                ProcessRecord app = mLruProcesses.get(i);
20866                if (allChanged || app.procStateChanged) {
20867                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20868                    app.procStateChanged = false;
20869                }
20870                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20871                        || app.systemNoUi) && app.pendingUiClean) {
20872                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20873                            && app.thread != null) {
20874                        try {
20875                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20876                                    "Trimming memory of ui hidden " + app.processName
20877                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20878                            app.thread.scheduleTrimMemory(
20879                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20880                        } catch (RemoteException e) {
20881                        }
20882                    }
20883                    app.pendingUiClean = false;
20884                }
20885                app.trimMemoryLevel = 0;
20886            }
20887        }
20888
20889        if (mAlwaysFinishActivities) {
20890            // Need to do this on its own message because the stack may not
20891            // be in a consistent state at this point.
20892            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20893        }
20894
20895        if (allChanged) {
20896            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20897        }
20898
20899        // Update from any uid changes.
20900        for (int i=mActiveUids.size()-1; i>=0; i--) {
20901            final UidRecord uidRec = mActiveUids.valueAt(i);
20902            int uidChange = UidRecord.CHANGE_PROCSTATE;
20903            if (uidRec.setProcState != uidRec.curProcState) {
20904                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20905                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20906                        + " to " + uidRec.curProcState);
20907                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20908                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20909                        uidRec.lastBackgroundTime = nowElapsed;
20910                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20911                            // Note: the background settle time is in elapsed realtime, while
20912                            // the handler time base is uptime.  All this means is that we may
20913                            // stop background uids later than we had intended, but that only
20914                            // happens because the device was sleeping so we are okay anyway.
20915                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20916                        }
20917                    }
20918                } else {
20919                    if (uidRec.idle) {
20920                        uidChange = UidRecord.CHANGE_ACTIVE;
20921                        uidRec.idle = false;
20922                    }
20923                    uidRec.lastBackgroundTime = 0;
20924                }
20925                uidRec.setProcState = uidRec.curProcState;
20926                enqueueUidChangeLocked(uidRec, -1, uidChange);
20927                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20928            }
20929        }
20930
20931        if (mProcessStats.shouldWriteNowLocked(now)) {
20932            mHandler.post(new Runnable() {
20933                @Override public void run() {
20934                    synchronized (ActivityManagerService.this) {
20935                        mProcessStats.writeStateAsyncLocked();
20936                    }
20937                }
20938            });
20939        }
20940
20941        if (DEBUG_OOM_ADJ) {
20942            final long duration = SystemClock.uptimeMillis() - now;
20943            if (false) {
20944                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20945                        new RuntimeException("here").fillInStackTrace());
20946            } else {
20947                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20948            }
20949        }
20950    }
20951
20952    final void idleUids() {
20953        synchronized (this) {
20954            final long nowElapsed = SystemClock.elapsedRealtime();
20955            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20956            long nextTime = 0;
20957            for (int i=mActiveUids.size()-1; i>=0; i--) {
20958                final UidRecord uidRec = mActiveUids.valueAt(i);
20959                final long bgTime = uidRec.lastBackgroundTime;
20960                if (bgTime > 0 && !uidRec.idle) {
20961                    if (bgTime <= maxBgTime) {
20962                        uidRec.idle = true;
20963                        doStopUidLocked(uidRec.uid, uidRec);
20964                    } else {
20965                        if (nextTime == 0 || nextTime > bgTime) {
20966                            nextTime = bgTime;
20967                        }
20968                    }
20969                }
20970            }
20971            if (nextTime > 0) {
20972                mHandler.removeMessages(IDLE_UIDS_MSG);
20973                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20974                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20975            }
20976        }
20977    }
20978
20979    final void runInBackgroundDisabled(int uid) {
20980        synchronized (this) {
20981            UidRecord uidRec = mActiveUids.get(uid);
20982            if (uidRec != null) {
20983                // This uid is actually running...  should it be considered background now?
20984                if (uidRec.idle) {
20985                    doStopUidLocked(uidRec.uid, uidRec);
20986                }
20987            } else {
20988                // This uid isn't actually running...  still send a report about it being "stopped".
20989                doStopUidLocked(uid, null);
20990            }
20991        }
20992    }
20993
20994    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20995        mServices.stopInBackgroundLocked(uid);
20996        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20997    }
20998
20999    final void trimApplications() {
21000        synchronized (this) {
21001            int i;
21002
21003            // First remove any unused application processes whose package
21004            // has been removed.
21005            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21006                final ProcessRecord app = mRemovedProcesses.get(i);
21007                if (app.activities.size() == 0
21008                        && app.curReceiver == null && app.services.size() == 0) {
21009                    Slog.i(
21010                        TAG, "Exiting empty application process "
21011                        + app.toShortString() + " ("
21012                        + (app.thread != null ? app.thread.asBinder() : null)
21013                        + ")\n");
21014                    if (app.pid > 0 && app.pid != MY_PID) {
21015                        app.kill("empty", false);
21016                    } else {
21017                        try {
21018                            app.thread.scheduleExit();
21019                        } catch (Exception e) {
21020                            // Ignore exceptions.
21021                        }
21022                    }
21023                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21024                    mRemovedProcesses.remove(i);
21025
21026                    if (app.persistent) {
21027                        addAppLocked(app.info, false, null /* ABI override */);
21028                    }
21029                }
21030            }
21031
21032            // Now update the oom adj for all processes.
21033            updateOomAdjLocked();
21034        }
21035    }
21036
21037    /** This method sends the specified signal to each of the persistent apps */
21038    public void signalPersistentProcesses(int sig) throws RemoteException {
21039        if (sig != Process.SIGNAL_USR1) {
21040            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21041        }
21042
21043        synchronized (this) {
21044            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21045                    != PackageManager.PERMISSION_GRANTED) {
21046                throw new SecurityException("Requires permission "
21047                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21048            }
21049
21050            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21051                ProcessRecord r = mLruProcesses.get(i);
21052                if (r.thread != null && r.persistent) {
21053                    Process.sendSignal(r.pid, sig);
21054                }
21055            }
21056        }
21057    }
21058
21059    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21060        if (proc == null || proc == mProfileProc) {
21061            proc = mProfileProc;
21062            profileType = mProfileType;
21063            clearProfilerLocked();
21064        }
21065        if (proc == null) {
21066            return;
21067        }
21068        try {
21069            proc.thread.profilerControl(false, null, profileType);
21070        } catch (RemoteException e) {
21071            throw new IllegalStateException("Process disappeared");
21072        }
21073    }
21074
21075    private void clearProfilerLocked() {
21076        if (mProfileFd != null) {
21077            try {
21078                mProfileFd.close();
21079            } catch (IOException e) {
21080            }
21081        }
21082        mProfileApp = null;
21083        mProfileProc = null;
21084        mProfileFile = null;
21085        mProfileType = 0;
21086        mAutoStopProfiler = false;
21087        mSamplingInterval = 0;
21088    }
21089
21090    public boolean profileControl(String process, int userId, boolean start,
21091            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21092
21093        try {
21094            synchronized (this) {
21095                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21096                // its own permission.
21097                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21098                        != PackageManager.PERMISSION_GRANTED) {
21099                    throw new SecurityException("Requires permission "
21100                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21101                }
21102
21103                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21104                    throw new IllegalArgumentException("null profile info or fd");
21105                }
21106
21107                ProcessRecord proc = null;
21108                if (process != null) {
21109                    proc = findProcessLocked(process, userId, "profileControl");
21110                }
21111
21112                if (start && (proc == null || proc.thread == null)) {
21113                    throw new IllegalArgumentException("Unknown process: " + process);
21114                }
21115
21116                if (start) {
21117                    stopProfilerLocked(null, 0);
21118                    setProfileApp(proc.info, proc.processName, profilerInfo);
21119                    mProfileProc = proc;
21120                    mProfileType = profileType;
21121                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21122                    try {
21123                        fd = fd.dup();
21124                    } catch (IOException e) {
21125                        fd = null;
21126                    }
21127                    profilerInfo.profileFd = fd;
21128                    proc.thread.profilerControl(start, profilerInfo, profileType);
21129                    fd = null;
21130                    mProfileFd = null;
21131                } else {
21132                    stopProfilerLocked(proc, profileType);
21133                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21134                        try {
21135                            profilerInfo.profileFd.close();
21136                        } catch (IOException e) {
21137                        }
21138                    }
21139                }
21140
21141                return true;
21142            }
21143        } catch (RemoteException e) {
21144            throw new IllegalStateException("Process disappeared");
21145        } finally {
21146            if (profilerInfo != null && profilerInfo.profileFd != null) {
21147                try {
21148                    profilerInfo.profileFd.close();
21149                } catch (IOException e) {
21150                }
21151            }
21152        }
21153    }
21154
21155    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21156        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21157                userId, true, ALLOW_FULL_ONLY, callName, null);
21158        ProcessRecord proc = null;
21159        try {
21160            int pid = Integer.parseInt(process);
21161            synchronized (mPidsSelfLocked) {
21162                proc = mPidsSelfLocked.get(pid);
21163            }
21164        } catch (NumberFormatException e) {
21165        }
21166
21167        if (proc == null) {
21168            ArrayMap<String, SparseArray<ProcessRecord>> all
21169                    = mProcessNames.getMap();
21170            SparseArray<ProcessRecord> procs = all.get(process);
21171            if (procs != null && procs.size() > 0) {
21172                proc = procs.valueAt(0);
21173                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21174                    for (int i=1; i<procs.size(); i++) {
21175                        ProcessRecord thisProc = procs.valueAt(i);
21176                        if (thisProc.userId == userId) {
21177                            proc = thisProc;
21178                            break;
21179                        }
21180                    }
21181                }
21182            }
21183        }
21184
21185        return proc;
21186    }
21187
21188    public boolean dumpHeap(String process, int userId, boolean managed,
21189            String path, ParcelFileDescriptor fd) throws RemoteException {
21190
21191        try {
21192            synchronized (this) {
21193                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21194                // its own permission (same as profileControl).
21195                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21196                        != PackageManager.PERMISSION_GRANTED) {
21197                    throw new SecurityException("Requires permission "
21198                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21199                }
21200
21201                if (fd == null) {
21202                    throw new IllegalArgumentException("null fd");
21203                }
21204
21205                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21206                if (proc == null || proc.thread == null) {
21207                    throw new IllegalArgumentException("Unknown process: " + process);
21208                }
21209
21210                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21211                if (!isDebuggable) {
21212                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21213                        throw new SecurityException("Process not debuggable: " + proc);
21214                    }
21215                }
21216
21217                proc.thread.dumpHeap(managed, path, fd);
21218                fd = null;
21219                return true;
21220            }
21221        } catch (RemoteException e) {
21222            throw new IllegalStateException("Process disappeared");
21223        } finally {
21224            if (fd != null) {
21225                try {
21226                    fd.close();
21227                } catch (IOException e) {
21228                }
21229            }
21230        }
21231    }
21232
21233    @Override
21234    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21235            String reportPackage) {
21236        if (processName != null) {
21237            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21238                    "setDumpHeapDebugLimit()");
21239        } else {
21240            synchronized (mPidsSelfLocked) {
21241                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21242                if (proc == null) {
21243                    throw new SecurityException("No process found for calling pid "
21244                            + Binder.getCallingPid());
21245                }
21246                if (!Build.IS_DEBUGGABLE
21247                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21248                    throw new SecurityException("Not running a debuggable build");
21249                }
21250                processName = proc.processName;
21251                uid = proc.uid;
21252                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21253                    throw new SecurityException("Package " + reportPackage + " is not running in "
21254                            + proc);
21255                }
21256            }
21257        }
21258        synchronized (this) {
21259            if (maxMemSize > 0) {
21260                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21261            } else {
21262                if (uid != 0) {
21263                    mMemWatchProcesses.remove(processName, uid);
21264                } else {
21265                    mMemWatchProcesses.getMap().remove(processName);
21266                }
21267            }
21268        }
21269    }
21270
21271    @Override
21272    public void dumpHeapFinished(String path) {
21273        synchronized (this) {
21274            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21275                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21276                        + " does not match last pid " + mMemWatchDumpPid);
21277                return;
21278            }
21279            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21280                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21281                        + " does not match last path " + mMemWatchDumpFile);
21282                return;
21283            }
21284            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21285            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21286        }
21287    }
21288
21289    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21290    public void monitor() {
21291        synchronized (this) { }
21292    }
21293
21294    void onCoreSettingsChange(Bundle settings) {
21295        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21296            ProcessRecord processRecord = mLruProcesses.get(i);
21297            try {
21298                if (processRecord.thread != null) {
21299                    processRecord.thread.setCoreSettings(settings);
21300                }
21301            } catch (RemoteException re) {
21302                /* ignore */
21303            }
21304        }
21305    }
21306
21307    // Multi-user methods
21308
21309    /**
21310     * Start user, if its not already running, but don't bring it to foreground.
21311     */
21312    @Override
21313    public boolean startUserInBackground(final int userId) {
21314        return mUserController.startUser(userId, /* foreground */ false);
21315    }
21316
21317    @Override
21318    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21319        return mUserController.unlockUser(userId, token, secret, listener);
21320    }
21321
21322    @Override
21323    public boolean switchUser(final int targetUserId) {
21324        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21325        UserInfo currentUserInfo;
21326        UserInfo targetUserInfo;
21327        synchronized (this) {
21328            int currentUserId = mUserController.getCurrentUserIdLocked();
21329            currentUserInfo = mUserController.getUserInfo(currentUserId);
21330            targetUserInfo = mUserController.getUserInfo(targetUserId);
21331            if (targetUserInfo == null) {
21332                Slog.w(TAG, "No user info for user #" + targetUserId);
21333                return false;
21334            }
21335            if (!targetUserInfo.supportsSwitchTo()) {
21336                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21337                return false;
21338            }
21339            if (targetUserInfo.isManagedProfile()) {
21340                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21341                return false;
21342            }
21343            mUserController.setTargetUserIdLocked(targetUserId);
21344        }
21345        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21346        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21347        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21348        return true;
21349    }
21350
21351    void scheduleStartProfilesLocked() {
21352        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21353            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21354                    DateUtils.SECOND_IN_MILLIS);
21355        }
21356    }
21357
21358    @Override
21359    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21360        return mUserController.stopUser(userId, force, callback);
21361    }
21362
21363    @Override
21364    public UserInfo getCurrentUser() {
21365        return mUserController.getCurrentUser();
21366    }
21367
21368    @Override
21369    public boolean isUserRunning(int userId, int flags) {
21370        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21371                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21372            String msg = "Permission Denial: isUserRunning() from pid="
21373                    + Binder.getCallingPid()
21374                    + ", uid=" + Binder.getCallingUid()
21375                    + " requires " + INTERACT_ACROSS_USERS;
21376            Slog.w(TAG, msg);
21377            throw new SecurityException(msg);
21378        }
21379        synchronized (this) {
21380            return mUserController.isUserRunningLocked(userId, flags);
21381        }
21382    }
21383
21384    @Override
21385    public int[] getRunningUserIds() {
21386        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21387                != PackageManager.PERMISSION_GRANTED) {
21388            String msg = "Permission Denial: isUserRunning() from pid="
21389                    + Binder.getCallingPid()
21390                    + ", uid=" + Binder.getCallingUid()
21391                    + " requires " + INTERACT_ACROSS_USERS;
21392            Slog.w(TAG, msg);
21393            throw new SecurityException(msg);
21394        }
21395        synchronized (this) {
21396            return mUserController.getStartedUserArrayLocked();
21397        }
21398    }
21399
21400    @Override
21401    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21402        mUserController.registerUserSwitchObserver(observer);
21403    }
21404
21405    @Override
21406    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21407        mUserController.unregisterUserSwitchObserver(observer);
21408    }
21409
21410    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21411        if (info == null) return null;
21412        ApplicationInfo newInfo = new ApplicationInfo(info);
21413        newInfo.initForUser(userId);
21414        return newInfo;
21415    }
21416
21417    public boolean isUserStopped(int userId) {
21418        synchronized (this) {
21419            return mUserController.getStartedUserStateLocked(userId) == null;
21420        }
21421    }
21422
21423    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21424        if (aInfo == null
21425                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21426            return aInfo;
21427        }
21428
21429        ActivityInfo info = new ActivityInfo(aInfo);
21430        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21431        return info;
21432    }
21433
21434    private boolean processSanityChecksLocked(ProcessRecord process) {
21435        if (process == null || process.thread == null) {
21436            return false;
21437        }
21438
21439        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21440        if (!isDebuggable) {
21441            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21442                return false;
21443            }
21444        }
21445
21446        return true;
21447    }
21448
21449    public boolean startBinderTracking() throws RemoteException {
21450        synchronized (this) {
21451            mBinderTransactionTrackingEnabled = true;
21452            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21453            // permission (same as profileControl).
21454            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21455                    != PackageManager.PERMISSION_GRANTED) {
21456                throw new SecurityException("Requires permission "
21457                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21458            }
21459
21460            for (int i = 0; i < mLruProcesses.size(); i++) {
21461                ProcessRecord process = mLruProcesses.get(i);
21462                if (!processSanityChecksLocked(process)) {
21463                    continue;
21464                }
21465                try {
21466                    process.thread.startBinderTracking();
21467                } catch (RemoteException e) {
21468                    Log.v(TAG, "Process disappared");
21469                }
21470            }
21471            return true;
21472        }
21473    }
21474
21475    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21476        try {
21477            synchronized (this) {
21478                mBinderTransactionTrackingEnabled = false;
21479                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21480                // permission (same as profileControl).
21481                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21482                        != PackageManager.PERMISSION_GRANTED) {
21483                    throw new SecurityException("Requires permission "
21484                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21485                }
21486
21487                if (fd == null) {
21488                    throw new IllegalArgumentException("null fd");
21489                }
21490
21491                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21492                pw.println("Binder transaction traces for all processes.\n");
21493                for (ProcessRecord process : mLruProcesses) {
21494                    if (!processSanityChecksLocked(process)) {
21495                        continue;
21496                    }
21497
21498                    pw.println("Traces for process: " + process.processName);
21499                    pw.flush();
21500                    try {
21501                        TransferPipe tp = new TransferPipe();
21502                        try {
21503                            process.thread.stopBinderTrackingAndDump(
21504                                    tp.getWriteFd().getFileDescriptor());
21505                            tp.go(fd.getFileDescriptor());
21506                        } finally {
21507                            tp.kill();
21508                        }
21509                    } catch (IOException e) {
21510                        pw.println("Failure while dumping IPC traces from " + process +
21511                                ".  Exception: " + e);
21512                        pw.flush();
21513                    } catch (RemoteException e) {
21514                        pw.println("Got a RemoteException while dumping IPC traces from " +
21515                                process + ".  Exception: " + e);
21516                        pw.flush();
21517                    }
21518                }
21519                fd = null;
21520                return true;
21521            }
21522        } finally {
21523            if (fd != null) {
21524                try {
21525                    fd.close();
21526                } catch (IOException e) {
21527                }
21528            }
21529        }
21530    }
21531
21532    private final class LocalService extends ActivityManagerInternal {
21533        @Override
21534        public void onWakefulnessChanged(int wakefulness) {
21535            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21536        }
21537
21538        @Override
21539        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21540                String processName, String abiOverride, int uid, Runnable crashHandler) {
21541            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21542                    processName, abiOverride, uid, crashHandler);
21543        }
21544
21545        @Override
21546        public SleepToken acquireSleepToken(String tag) {
21547            Preconditions.checkNotNull(tag);
21548
21549            ComponentName requestedVrService = null;
21550            ComponentName callingVrActivity = null;
21551            int userId = -1;
21552            synchronized (ActivityManagerService.this) {
21553                if (mFocusedActivity != null) {
21554                    requestedVrService = mFocusedActivity.requestedVrComponent;
21555                    callingVrActivity = mFocusedActivity.info.getComponentName();
21556                    userId = mFocusedActivity.userId;
21557                }
21558            }
21559
21560            if (requestedVrService != null) {
21561                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21562            }
21563
21564            synchronized (ActivityManagerService.this) {
21565                SleepTokenImpl token = new SleepTokenImpl(tag);
21566                mSleepTokens.add(token);
21567                updateSleepIfNeededLocked();
21568                return token;
21569            }
21570        }
21571
21572        @Override
21573        public ComponentName getHomeActivityForUser(int userId) {
21574            synchronized (ActivityManagerService.this) {
21575                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21576                return homeActivity == null ? null : homeActivity.realActivity;
21577            }
21578        }
21579
21580        @Override
21581        public void onUserRemoved(int userId) {
21582            synchronized (ActivityManagerService.this) {
21583                ActivityManagerService.this.onUserStoppedLocked(userId);
21584            }
21585        }
21586
21587        @Override
21588        public void onLocalVoiceInteractionStarted(IBinder activity,
21589                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21590            synchronized (ActivityManagerService.this) {
21591                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21592                        voiceSession, voiceInteractor);
21593            }
21594        }
21595
21596        @Override
21597        public void notifyStartingWindowDrawn() {
21598            synchronized (ActivityManagerService.this) {
21599                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21600            }
21601        }
21602
21603        @Override
21604        public void notifyAppTransitionStarting(int reason) {
21605            synchronized (ActivityManagerService.this) {
21606                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21607            }
21608        }
21609
21610        @Override
21611        public void notifyAppTransitionFinished() {
21612            synchronized (ActivityManagerService.this) {
21613                mStackSupervisor.notifyAppTransitionDone();
21614            }
21615        }
21616
21617        @Override
21618        public void notifyAppTransitionCancelled() {
21619            synchronized (ActivityManagerService.this) {
21620                mStackSupervisor.notifyAppTransitionDone();
21621            }
21622        }
21623
21624        @Override
21625        public List<IBinder> getTopVisibleActivities() {
21626            synchronized (ActivityManagerService.this) {
21627                return mStackSupervisor.getTopVisibleActivities();
21628            }
21629        }
21630
21631        @Override
21632        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21633            synchronized (ActivityManagerService.this) {
21634                mStackSupervisor.setDockedStackMinimized(minimized);
21635            }
21636        }
21637
21638        @Override
21639        public void killForegroundAppsForUser(int userHandle) {
21640            synchronized (ActivityManagerService.this) {
21641                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21642                final int NP = mProcessNames.getMap().size();
21643                for (int ip = 0; ip < NP; ip++) {
21644                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21645                    final int NA = apps.size();
21646                    for (int ia = 0; ia < NA; ia++) {
21647                        final ProcessRecord app = apps.valueAt(ia);
21648                        if (app.persistent) {
21649                            // We don't kill persistent processes.
21650                            continue;
21651                        }
21652                        if (app.removed) {
21653                            procs.add(app);
21654                        } else if (app.userId == userHandle && app.foregroundActivities) {
21655                            app.removed = true;
21656                            procs.add(app);
21657                        }
21658                    }
21659                }
21660
21661                final int N = procs.size();
21662                for (int i = 0; i < N; i++) {
21663                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21664                }
21665            }
21666        }
21667
21668        @Override
21669        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21670            if (!(target instanceof PendingIntentRecord)) {
21671                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21672                return;
21673            }
21674            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21675        }
21676    }
21677
21678    private final class SleepTokenImpl extends SleepToken {
21679        private final String mTag;
21680        private final long mAcquireTime;
21681
21682        public SleepTokenImpl(String tag) {
21683            mTag = tag;
21684            mAcquireTime = SystemClock.uptimeMillis();
21685        }
21686
21687        @Override
21688        public void release() {
21689            synchronized (ActivityManagerService.this) {
21690                if (mSleepTokens.remove(this)) {
21691                    updateSleepIfNeededLocked();
21692                }
21693            }
21694        }
21695
21696        @Override
21697        public String toString() {
21698            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21699        }
21700    }
21701
21702    /**
21703     * An implementation of IAppTask, that allows an app to manage its own tasks via
21704     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21705     * only the process that calls getAppTasks() can call the AppTask methods.
21706     */
21707    class AppTaskImpl extends IAppTask.Stub {
21708        private int mTaskId;
21709        private int mCallingUid;
21710
21711        public AppTaskImpl(int taskId, int callingUid) {
21712            mTaskId = taskId;
21713            mCallingUid = callingUid;
21714        }
21715
21716        private void checkCaller() {
21717            if (mCallingUid != Binder.getCallingUid()) {
21718                throw new SecurityException("Caller " + mCallingUid
21719                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21720            }
21721        }
21722
21723        @Override
21724        public void finishAndRemoveTask() {
21725            checkCaller();
21726
21727            synchronized (ActivityManagerService.this) {
21728                long origId = Binder.clearCallingIdentity();
21729                try {
21730                    // We remove the task from recents to preserve backwards
21731                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21732                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21733                    }
21734                } finally {
21735                    Binder.restoreCallingIdentity(origId);
21736                }
21737            }
21738        }
21739
21740        @Override
21741        public ActivityManager.RecentTaskInfo getTaskInfo() {
21742            checkCaller();
21743
21744            synchronized (ActivityManagerService.this) {
21745                long origId = Binder.clearCallingIdentity();
21746                try {
21747                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21748                    if (tr == null) {
21749                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21750                    }
21751                    return createRecentTaskInfoFromTaskRecord(tr);
21752                } finally {
21753                    Binder.restoreCallingIdentity(origId);
21754                }
21755            }
21756        }
21757
21758        @Override
21759        public void moveToFront() {
21760            checkCaller();
21761            // Will bring task to front if it already has a root activity.
21762            final long origId = Binder.clearCallingIdentity();
21763            try {
21764                synchronized (this) {
21765                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21766                }
21767            } finally {
21768                Binder.restoreCallingIdentity(origId);
21769            }
21770        }
21771
21772        @Override
21773        public int startActivity(IBinder whoThread, String callingPackage,
21774                Intent intent, String resolvedType, Bundle bOptions) {
21775            checkCaller();
21776
21777            int callingUser = UserHandle.getCallingUserId();
21778            TaskRecord tr;
21779            IApplicationThread appThread;
21780            synchronized (ActivityManagerService.this) {
21781                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21782                if (tr == null) {
21783                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21784                }
21785                appThread = ApplicationThreadNative.asInterface(whoThread);
21786                if (appThread == null) {
21787                    throw new IllegalArgumentException("Bad app thread " + appThread);
21788                }
21789            }
21790            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21791                    resolvedType, null, null, null, null, 0, 0, null, null,
21792                    null, bOptions, false, callingUser, null, tr);
21793        }
21794
21795        @Override
21796        public void setExcludeFromRecents(boolean exclude) {
21797            checkCaller();
21798
21799            synchronized (ActivityManagerService.this) {
21800                long origId = Binder.clearCallingIdentity();
21801                try {
21802                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21803                    if (tr == null) {
21804                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21805                    }
21806                    Intent intent = tr.getBaseIntent();
21807                    if (exclude) {
21808                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21809                    } else {
21810                        intent.setFlags(intent.getFlags()
21811                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21812                    }
21813                } finally {
21814                    Binder.restoreCallingIdentity(origId);
21815                }
21816            }
21817        }
21818    }
21819
21820    /**
21821     * Kill processes for the user with id userId and that depend on the package named packageName
21822     */
21823    @Override
21824    public void killPackageDependents(String packageName, int userId) {
21825        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21826        if (packageName == null) {
21827            throw new NullPointerException(
21828                    "Cannot kill the dependents of a package without its name.");
21829        }
21830
21831        long callingId = Binder.clearCallingIdentity();
21832        IPackageManager pm = AppGlobals.getPackageManager();
21833        int pkgUid = -1;
21834        try {
21835            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21836        } catch (RemoteException e) {
21837        }
21838        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21839            throw new IllegalArgumentException(
21840                    "Cannot kill dependents of non-existing package " + packageName);
21841        }
21842        try {
21843            synchronized(this) {
21844                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21845                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21846                        "dep: " + packageName);
21847            }
21848        } finally {
21849            Binder.restoreCallingIdentity(callingId);
21850        }
21851    }
21852}
21853