ActivityManagerService.java revision 4332dda9a76191b0f055dedbea8d509a20d5c455
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.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.text.format.DateUtils;
203import android.text.format.Time;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
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.FIRST_STATIC_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
266import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
346import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
348import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
349import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
350import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
351import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
352import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
353import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
354import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
355import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
356import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
359import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
361import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
364import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
365import static org.xmlpull.v1.XmlPullParser.START_TAG;
366
367public final class ActivityManagerService extends ActivityManagerNative
368        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
369
370    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
371    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
372    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
373    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
374    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
375    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
376    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
377    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
378    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
379    private static final String TAG_LRU = TAG + POSTFIX_LRU;
380    private static final String TAG_MU = TAG + POSTFIX_MU;
381    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
382    private static final String TAG_POWER = TAG + POSTFIX_POWER;
383    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
384    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
385    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
386    private static final String TAG_PSS = TAG + POSTFIX_PSS;
387    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
388    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
389    private static final String TAG_STACK = TAG + POSTFIX_STACK;
390    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
391    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
392    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
393    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
394    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
395
396    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
397    // here so that while the job scheduler can depend on AMS, the other way around
398    // need not be the case.
399    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
400
401    /** Control over CPU and battery monitoring */
402    // write battery stats every 30 minutes.
403    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
404    static final boolean MONITOR_CPU_USAGE = true;
405    // don't sample cpu less than every 5 seconds.
406    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
407    // wait possibly forever for next cpu sample.
408    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
409    static final boolean MONITOR_THREAD_CPU_USAGE = false;
410
411    // The flags that are set for all calls we make to the package manager.
412    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
413
414    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
415
416    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
417
418    // Amount of time after a call to stopAppSwitches() during which we will
419    // prevent further untrusted switches from happening.
420    static final long APP_SWITCH_DELAY_TIME = 5*1000;
421
422    // How long we wait for a launched process to attach to the activity manager
423    // before we decide it's never going to come up for real.
424    static final int PROC_START_TIMEOUT = 10*1000;
425    // How long we wait for an attached process to publish its content providers
426    // before we decide it must be hung.
427    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
428
429    // How long we will retain processes hosting content providers in the "last activity"
430    // state before allowing them to drop down to the regular cached LRU list.  This is
431    // to avoid thrashing of provider processes under low memory situations.
432    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
433
434    // How long we wait for a launched process to attach to the activity manager
435    // before we decide it's never going to come up for real, when the process was
436    // started with a wrapper for instrumentation (such as Valgrind) because it
437    // could take much longer than usual.
438    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
439
440    // How long to wait after going idle before forcing apps to GC.
441    static final int GC_TIMEOUT = 5*1000;
442
443    // The minimum amount of time between successive GC requests for a process.
444    static final int GC_MIN_INTERVAL = 60*1000;
445
446    // The minimum amount of time between successive PSS requests for a process.
447    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
448
449    // The minimum amount of time between successive PSS requests for a process
450    // when the request is due to the memory state being lowered.
451    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
452
453    // The rate at which we check for apps using excessive power -- 15 mins.
454    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
455
456    // The minimum sample duration we will allow before deciding we have
457    // enough data on wake locks to start killing things.
458    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
459
460    // The minimum sample duration we will allow before deciding we have
461    // enough data on CPU usage to start killing things.
462    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
463
464    // How long we allow a receiver to run before giving up on it.
465    static final int BROADCAST_FG_TIMEOUT = 10*1000;
466    static final int BROADCAST_BG_TIMEOUT = 60*1000;
467
468    // How long we wait until we timeout on key dispatching.
469    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
470
471    // How long we wait until we timeout on key dispatching during instrumentation.
472    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
473
474    // This is the amount of time an app needs to be running a foreground service before
475    // we will consider it to be doing interaction for usage stats.
476    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
477
478    // Maximum amount of time we will allow to elapse before re-reporting usage stats
479    // interaction with foreground processes.
480    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
481
482    // This is the amount of time we allow an app to settle after it goes into the background,
483    // before we start restricting what it can do.
484    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
485
486    // How long to wait in getAssistContextExtras for the activity and foreground services
487    // to respond with the result.
488    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
489
490    // How long top wait when going through the modern assist (which doesn't need to block
491    // on getting this result before starting to launch its UI).
492    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
493
494    // Maximum number of persisted Uri grants a package is allowed
495    static final int MAX_PERSISTED_URI_GRANTS = 128;
496
497    static final int MY_PID = Process.myPid();
498
499    static final String[] EMPTY_STRING_ARRAY = new String[0];
500
501    // How many bytes to write into the dropbox log before truncating
502    static final int DROPBOX_MAX_SIZE = 256 * 1024;
503
504    // Access modes for handleIncomingUser.
505    static final int ALLOW_NON_FULL = 0;
506    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
507    static final int ALLOW_FULL_ONLY = 2;
508
509    // Delay in notifying task stack change listeners (in millis)
510    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
511
512    // Necessary ApplicationInfo flags to mark an app as persistent
513    private static final int PERSISTENT_MASK =
514            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
515
516    // Intent sent when remote bugreport collection has been completed
517    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
518            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
519
520    // Delay to disable app launch boost
521    static final int APP_BOOST_MESSAGE_DELAY = 3000;
522    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
523    static final int APP_BOOST_TIMEOUT = 2500;
524
525    // Used to indicate that a task is removed it should also be removed from recents.
526    private static final boolean REMOVE_FROM_RECENTS = true;
527    // Used to indicate that an app transition should be animated.
528    static final boolean ANIMATE = true;
529
530    // Determines whether to take full screen screenshots
531    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
532    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
533
534    private static native int nativeMigrateToBoost();
535    private static native int nativeMigrateFromBoost();
536    private boolean mIsBoosted = false;
537    private long mBoostStartTime = 0;
538
539    /** All system services */
540    SystemServiceManager mSystemServiceManager;
541
542    private Installer mInstaller;
543
544    /** Run all ActivityStacks through this */
545    final ActivityStackSupervisor mStackSupervisor;
546
547    final ActivityStarter mActivityStarter;
548
549    /** Task stack change listeners. */
550    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
551            new RemoteCallbackList<ITaskStackListener>();
552
553    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
554
555    public IntentFirewall mIntentFirewall;
556
557    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
558    // default actuion automatically.  Important for devices without direct input
559    // devices.
560    private boolean mShowDialogs = true;
561    private boolean mInVrMode = false;
562
563    BroadcastQueue mFgBroadcastQueue;
564    BroadcastQueue mBgBroadcastQueue;
565    // Convenient for easy iteration over the queues. Foreground is first
566    // so that dispatch of foreground broadcasts gets precedence.
567    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
568
569    BroadcastQueue broadcastQueueForIntent(Intent intent) {
570        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
571        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
572                "Broadcast intent " + intent + " on "
573                + (isFg ? "foreground" : "background") + " queue");
574        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
575    }
576
577    /**
578     * Activity we have told the window manager to have key focus.
579     */
580    ActivityRecord mFocusedActivity = null;
581
582    /**
583     * User id of the last activity mFocusedActivity was set to.
584     */
585    private int mLastFocusedUserId;
586
587    /**
588     * If non-null, we are tracking the time the user spends in the currently focused app.
589     */
590    private AppTimeTracker mCurAppTimeTracker;
591
592    /**
593     * List of intents that were used to start the most recent tasks.
594     */
595    final RecentTasks mRecentTasks;
596
597    /**
598     * For addAppTask: cached of the last activity component that was added.
599     */
600    ComponentName mLastAddedTaskComponent;
601
602    /**
603     * For addAppTask: cached of the last activity uid that was added.
604     */
605    int mLastAddedTaskUid;
606
607    /**
608     * For addAppTask: cached of the last ActivityInfo that was added.
609     */
610    ActivityInfo mLastAddedTaskActivity;
611
612    /**
613     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
614     */
615    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
616
617    /**
618     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
619     */
620    String mDeviceOwnerName;
621
622    final UserController mUserController;
623
624    final AppErrors mAppErrors;
625
626    boolean mDoingSetFocusedActivity;
627
628    public boolean canShowErrorDialogs() {
629        return mShowDialogs && !mSleeping && !mShuttingDown;
630    }
631
632    // it's a semaphore; boost when 0->1, reset when 1->0
633    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
634        @Override protected Integer initialValue() {
635            return 0;
636        }
637    };
638
639    static void boostPriorityForLockedSection() {
640        if (sIsBoosted.get() == 0) {
641            // boost to prio 118 while holding a global lock
642            Process.setThreadPriority(Process.myTid(), -2);
643            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
644        }
645        int cur = sIsBoosted.get();
646        sIsBoosted.set(cur + 1);
647    }
648
649    static void resetPriorityAfterLockedSection() {
650        sIsBoosted.set(sIsBoosted.get() - 1);
651        if (sIsBoosted.get() == 0) {
652            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
653            Process.setThreadPriority(Process.myTid(), 0);
654        }
655    }
656    public class PendingAssistExtras extends Binder implements Runnable {
657        public final ActivityRecord activity;
658        public final Bundle extras;
659        public final Intent intent;
660        public final String hint;
661        public final IResultReceiver receiver;
662        public final int userHandle;
663        public boolean haveResult = false;
664        public Bundle result = null;
665        public AssistStructure structure = null;
666        public AssistContent content = null;
667        public Bundle receiverExtras;
668
669        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
670                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
671            activity = _activity;
672            extras = _extras;
673            intent = _intent;
674            hint = _hint;
675            receiver = _receiver;
676            receiverExtras = _receiverExtras;
677            userHandle = _userHandle;
678        }
679        @Override
680        public void run() {
681            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
682            synchronized (this) {
683                haveResult = true;
684                notifyAll();
685            }
686            pendingAssistExtrasTimedOut(this);
687        }
688    }
689
690    final ArrayList<PendingAssistExtras> mPendingAssistExtras
691            = new ArrayList<PendingAssistExtras>();
692
693    /**
694     * Process management.
695     */
696    final ProcessList mProcessList = new ProcessList();
697
698    /**
699     * All of the applications we currently have running organized by name.
700     * The keys are strings of the application package name (as
701     * returned by the package manager), and the keys are ApplicationRecord
702     * objects.
703     */
704    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
705
706    /**
707     * Tracking long-term execution of processes to look for abuse and other
708     * bad app behavior.
709     */
710    final ProcessStatsService mProcessStats;
711
712    /**
713     * The currently running isolated processes.
714     */
715    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
716
717    /**
718     * Counter for assigning isolated process uids, to avoid frequently reusing the
719     * same ones.
720     */
721    int mNextIsolatedProcessUid = 0;
722
723    /**
724     * The currently running heavy-weight process, if any.
725     */
726    ProcessRecord mHeavyWeightProcess = null;
727
728    /**
729     * All of the processes we currently have running organized by pid.
730     * The keys are the pid running the application.
731     *
732     * <p>NOTE: This object is protected by its own lock, NOT the global
733     * activity manager lock!
734     */
735    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
736
737    /**
738     * All of the processes that have been forced to be foreground.  The key
739     * is the pid of the caller who requested it (we hold a death
740     * link on it).
741     */
742    abstract class ForegroundToken implements IBinder.DeathRecipient {
743        int pid;
744        IBinder token;
745    }
746    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
747
748    /**
749     * List of records for processes that someone had tried to start before the
750     * system was ready.  We don't start them at that point, but ensure they
751     * are started by the time booting is complete.
752     */
753    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
754
755    /**
756     * List of persistent applications that are in the process
757     * of being started.
758     */
759    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
760
761    /**
762     * Processes that are being forcibly torn down.
763     */
764    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of running applications, sorted by recent usage.
768     * The first entry in the list is the least recently used.
769     */
770    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Where in mLruProcesses that the processes hosting activities start.
774     */
775    int mLruProcessActivityStart = 0;
776
777    /**
778     * Where in mLruProcesses that the processes hosting services start.
779     * This is after (lower index) than mLruProcessesActivityStart.
780     */
781    int mLruProcessServiceStart = 0;
782
783    /**
784     * List of processes that should gc as soon as things are idle.
785     */
786    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
787
788    /**
789     * Processes we want to collect PSS data from.
790     */
791    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
792
793    private boolean mBinderTransactionTrackingEnabled = false;
794
795    /**
796     * Last time we requested PSS data of all processes.
797     */
798    long mLastFullPssTime = SystemClock.uptimeMillis();
799
800    /**
801     * If set, the next time we collect PSS data we should do a full collection
802     * with data from native processes and the kernel.
803     */
804    boolean mFullPssPending = false;
805
806    /**
807     * This is the process holding what we currently consider to be
808     * the "home" activity.
809     */
810    ProcessRecord mHomeProcess;
811
812    /**
813     * This is the process holding the activity the user last visited that
814     * is in a different process from the one they are currently in.
815     */
816    ProcessRecord mPreviousProcess;
817
818    /**
819     * The time at which the previous process was last visible.
820     */
821    long mPreviousProcessVisibleTime;
822
823    /**
824     * Track all uids that have actively running processes.
825     */
826    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
827
828    /**
829     * This is for verifying the UID report flow.
830     */
831    static final boolean VALIDATE_UID_STATES = true;
832    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
833
834    /**
835     * Packages that the user has asked to have run in screen size
836     * compatibility mode instead of filling the screen.
837     */
838    final CompatModePackages mCompatModePackages;
839
840    /**
841     * Set of IntentSenderRecord objects that are currently active.
842     */
843    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
844            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
845
846    /**
847     * Fingerprints (hashCode()) of stack traces that we've
848     * already logged DropBox entries for.  Guarded by itself.  If
849     * something (rogue user app) forces this over
850     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
851     */
852    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
853    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
854
855    /**
856     * Strict Mode background batched logging state.
857     *
858     * The string buffer is guarded by itself, and its lock is also
859     * used to determine if another batched write is already
860     * in-flight.
861     */
862    private final StringBuilder mStrictModeBuffer = new StringBuilder();
863
864    /**
865     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
866     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
867     */
868    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
869
870    /**
871     * Resolver for broadcast intents to registered receivers.
872     * Holds BroadcastFilter (subclass of IntentFilter).
873     */
874    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
875            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
876        @Override
877        protected boolean allowFilterResult(
878                BroadcastFilter filter, List<BroadcastFilter> dest) {
879            IBinder target = filter.receiverList.receiver.asBinder();
880            for (int i = dest.size() - 1; i >= 0; i--) {
881                if (dest.get(i).receiverList.receiver.asBinder() == target) {
882                    return false;
883                }
884            }
885            return true;
886        }
887
888        @Override
889        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
890            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
891                    || userId == filter.owningUserId) {
892                return super.newResult(filter, match, userId);
893            }
894            return null;
895        }
896
897        @Override
898        protected BroadcastFilter[] newArray(int size) {
899            return new BroadcastFilter[size];
900        }
901
902        @Override
903        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
904            return packageName.equals(filter.packageName);
905        }
906    };
907
908    /**
909     * State of all active sticky broadcasts per user.  Keys are the action of the
910     * sticky Intent, values are an ArrayList of all broadcasted intents with
911     * that action (which should usually be one).  The SparseArray is keyed
912     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
913     * for stickies that are sent to all users.
914     */
915    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
916            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
917
918    final ActiveServices mServices;
919
920    final static class Association {
921        final int mSourceUid;
922        final String mSourceProcess;
923        final int mTargetUid;
924        final ComponentName mTargetComponent;
925        final String mTargetProcess;
926
927        int mCount;
928        long mTime;
929
930        int mNesting;
931        long mStartTime;
932
933        // states of the source process when the bind occurred.
934        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
935        long mLastStateUptime;
936        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
937                - ActivityManager.MIN_PROCESS_STATE+1];
938
939        Association(int sourceUid, String sourceProcess, int targetUid,
940                ComponentName targetComponent, String targetProcess) {
941            mSourceUid = sourceUid;
942            mSourceProcess = sourceProcess;
943            mTargetUid = targetUid;
944            mTargetComponent = targetComponent;
945            mTargetProcess = targetProcess;
946        }
947    }
948
949    /**
950     * When service association tracking is enabled, this is all of the associations we
951     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
952     * -> association data.
953     */
954    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
955            mAssociations = new SparseArray<>();
956    boolean mTrackingAssociations;
957
958    /**
959     * Backup/restore process management
960     */
961    String mBackupAppName = null;
962    BackupRecord mBackupTarget = null;
963
964    final ProviderMap mProviderMap;
965
966    /**
967     * List of content providers who have clients waiting for them.  The
968     * application is currently being launched and the provider will be
969     * removed from this list once it is published.
970     */
971    final ArrayList<ContentProviderRecord> mLaunchingProviders
972            = new ArrayList<ContentProviderRecord>();
973
974    /**
975     * File storing persisted {@link #mGrantedUriPermissions}.
976     */
977    private final AtomicFile mGrantFile;
978
979    /** XML constants used in {@link #mGrantFile} */
980    private static final String TAG_URI_GRANTS = "uri-grants";
981    private static final String TAG_URI_GRANT = "uri-grant";
982    private static final String ATTR_USER_HANDLE = "userHandle";
983    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
984    private static final String ATTR_TARGET_USER_ID = "targetUserId";
985    private static final String ATTR_SOURCE_PKG = "sourcePkg";
986    private static final String ATTR_TARGET_PKG = "targetPkg";
987    private static final String ATTR_URI = "uri";
988    private static final String ATTR_MODE_FLAGS = "modeFlags";
989    private static final String ATTR_CREATED_TIME = "createdTime";
990    private static final String ATTR_PREFIX = "prefix";
991
992    /**
993     * Global set of specific {@link Uri} permissions that have been granted.
994     * This optimized lookup structure maps from {@link UriPermission#targetUid}
995     * to {@link UriPermission#uri} to {@link UriPermission}.
996     */
997    @GuardedBy("this")
998    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
999            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1000
1001    public static class GrantUri {
1002        public final int sourceUserId;
1003        public final Uri uri;
1004        public boolean prefix;
1005
1006        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1007            this.sourceUserId = sourceUserId;
1008            this.uri = uri;
1009            this.prefix = prefix;
1010        }
1011
1012        @Override
1013        public int hashCode() {
1014            int hashCode = 1;
1015            hashCode = 31 * hashCode + sourceUserId;
1016            hashCode = 31 * hashCode + uri.hashCode();
1017            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1018            return hashCode;
1019        }
1020
1021        @Override
1022        public boolean equals(Object o) {
1023            if (o instanceof GrantUri) {
1024                GrantUri other = (GrantUri) o;
1025                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1026                        && prefix == other.prefix;
1027            }
1028            return false;
1029        }
1030
1031        @Override
1032        public String toString() {
1033            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1034            if (prefix) result += " [prefix]";
1035            return result;
1036        }
1037
1038        public String toSafeString() {
1039            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1040            if (prefix) result += " [prefix]";
1041            return result;
1042        }
1043
1044        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1045            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1046                    ContentProvider.getUriWithoutUserId(uri), false);
1047        }
1048    }
1049
1050    CoreSettingsObserver mCoreSettingsObserver;
1051
1052    FontScaleSettingObserver mFontScaleSettingObserver;
1053
1054    private final class FontScaleSettingObserver extends ContentObserver {
1055        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1056
1057        public FontScaleSettingObserver() {
1058            super(mHandler);
1059            ContentResolver resolver = mContext.getContentResolver();
1060            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1061        }
1062
1063        @Override
1064        public void onChange(boolean selfChange, Uri uri) {
1065            if (mFontScaleUri.equals(uri)) {
1066                updateFontScaleIfNeeded();
1067            }
1068        }
1069    }
1070
1071    /**
1072     * Thread-local storage used to carry caller permissions over through
1073     * indirect content-provider access.
1074     */
1075    private class Identity {
1076        public final IBinder token;
1077        public final int pid;
1078        public final int uid;
1079
1080        Identity(IBinder _token, int _pid, int _uid) {
1081            token = _token;
1082            pid = _pid;
1083            uid = _uid;
1084        }
1085    }
1086
1087    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1088
1089    /**
1090     * All information we have collected about the runtime performance of
1091     * any user id that can impact battery performance.
1092     */
1093    final BatteryStatsService mBatteryStatsService;
1094
1095    /**
1096     * Information about component usage
1097     */
1098    UsageStatsManagerInternal mUsageStatsService;
1099
1100    /**
1101     * Access to DeviceIdleController service.
1102     */
1103    DeviceIdleController.LocalService mLocalDeviceIdleController;
1104
1105    /**
1106     * Information about and control over application operations
1107     */
1108    final AppOpsService mAppOpsService;
1109
1110    /**
1111     * Current configuration information.  HistoryRecord objects are given
1112     * a reference to this object to indicate which configuration they are
1113     * currently running in, so this object must be kept immutable.
1114     */
1115    Configuration mConfiguration = new Configuration();
1116
1117    /**
1118     * Current sequencing integer of the configuration, for skipping old
1119     * configurations.
1120     */
1121    int mConfigurationSeq = 0;
1122
1123    boolean mSuppressResizeConfigChanges = false;
1124
1125    /**
1126     * Hardware-reported OpenGLES version.
1127     */
1128    final int GL_ES_VERSION;
1129
1130    /**
1131     * List of initialization arguments to pass to all processes when binding applications to them.
1132     * For example, references to the commonly used services.
1133     */
1134    HashMap<String, IBinder> mAppBindArgs;
1135
1136    /**
1137     * Temporary to avoid allocations.  Protected by main lock.
1138     */
1139    final StringBuilder mStringBuilder = new StringBuilder(256);
1140
1141    /**
1142     * Used to control how we initialize the service.
1143     */
1144    ComponentName mTopComponent;
1145    String mTopAction = Intent.ACTION_MAIN;
1146    String mTopData;
1147
1148    volatile boolean mProcessesReady = false;
1149    volatile boolean mSystemReady = false;
1150    volatile boolean mOnBattery = false;
1151    volatile int mFactoryTest;
1152
1153    @GuardedBy("this") boolean mBooting = false;
1154    @GuardedBy("this") boolean mCallFinishBooting = false;
1155    @GuardedBy("this") boolean mBootAnimationComplete = false;
1156    @GuardedBy("this") boolean mLaunchWarningShown = false;
1157    @GuardedBy("this") boolean mCheckedForSetup = false;
1158
1159    Context mContext;
1160
1161    /**
1162     * The time at which we will allow normal application switches again,
1163     * after a call to {@link #stopAppSwitches()}.
1164     */
1165    long mAppSwitchesAllowedTime;
1166
1167    /**
1168     * This is set to true after the first switch after mAppSwitchesAllowedTime
1169     * is set; any switches after that will clear the time.
1170     */
1171    boolean mDidAppSwitch;
1172
1173    /**
1174     * Last time (in realtime) at which we checked for power usage.
1175     */
1176    long mLastPowerCheckRealtime;
1177
1178    /**
1179     * Last time (in uptime) at which we checked for power usage.
1180     */
1181    long mLastPowerCheckUptime;
1182
1183    /**
1184     * Set while we are wanting to sleep, to prevent any
1185     * activities from being started/resumed.
1186     */
1187    private boolean mSleeping = false;
1188
1189    /**
1190     * The process state used for processes that are running the top activities.
1191     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1192     */
1193    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1194
1195    /**
1196     * Set while we are running a voice interaction.  This overrides
1197     * sleeping while it is active.
1198     */
1199    private IVoiceInteractionSession mRunningVoice;
1200
1201    /**
1202     * For some direct access we need to power manager.
1203     */
1204    PowerManagerInternal mLocalPowerManager;
1205
1206    /**
1207     * We want to hold a wake lock while running a voice interaction session, since
1208     * this may happen with the screen off and we need to keep the CPU running to
1209     * be able to continue to interact with the user.
1210     */
1211    PowerManager.WakeLock mVoiceWakeLock;
1212
1213    /**
1214     * State of external calls telling us if the device is awake or asleep.
1215     */
1216    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1217
1218    /**
1219     * A list of tokens that cause the top activity to be put to sleep.
1220     * They are used by components that may hide and block interaction with underlying
1221     * activities.
1222     */
1223    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1224
1225    static final int LOCK_SCREEN_HIDDEN = 0;
1226    static final int LOCK_SCREEN_LEAVING = 1;
1227    static final int LOCK_SCREEN_SHOWN = 2;
1228    /**
1229     * State of external call telling us if the lock screen is shown.
1230     */
1231    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1232
1233    /**
1234     * Set if we are shutting down the system, similar to sleeping.
1235     */
1236    boolean mShuttingDown = false;
1237
1238    /**
1239     * Current sequence id for oom_adj computation traversal.
1240     */
1241    int mAdjSeq = 0;
1242
1243    /**
1244     * Current sequence id for process LRU updating.
1245     */
1246    int mLruSeq = 0;
1247
1248    /**
1249     * Keep track of the non-cached/empty process we last found, to help
1250     * determine how to distribute cached/empty processes next time.
1251     */
1252    int mNumNonCachedProcs = 0;
1253
1254    /**
1255     * Keep track of the number of cached hidden procs, to balance oom adj
1256     * distribution between those and empty procs.
1257     */
1258    int mNumCachedHiddenProcs = 0;
1259
1260    /**
1261     * Keep track of the number of service processes we last found, to
1262     * determine on the next iteration which should be B services.
1263     */
1264    int mNumServiceProcs = 0;
1265    int mNewNumAServiceProcs = 0;
1266    int mNewNumServiceProcs = 0;
1267
1268    /**
1269     * Allow the current computed overall memory level of the system to go down?
1270     * This is set to false when we are killing processes for reasons other than
1271     * memory management, so that the now smaller process list will not be taken as
1272     * an indication that memory is tighter.
1273     */
1274    boolean mAllowLowerMemLevel = false;
1275
1276    /**
1277     * The last computed memory level, for holding when we are in a state that
1278     * processes are going away for other reasons.
1279     */
1280    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1281
1282    /**
1283     * The last total number of process we have, to determine if changes actually look
1284     * like a shrinking number of process due to lower RAM.
1285     */
1286    int mLastNumProcesses;
1287
1288    /**
1289     * The uptime of the last time we performed idle maintenance.
1290     */
1291    long mLastIdleTime = SystemClock.uptimeMillis();
1292
1293    /**
1294     * Total time spent with RAM that has been added in the past since the last idle time.
1295     */
1296    long mLowRamTimeSinceLastIdle = 0;
1297
1298    /**
1299     * If RAM is currently low, when that horrible situation started.
1300     */
1301    long mLowRamStartTime = 0;
1302
1303    /**
1304     * For reporting to battery stats the current top application.
1305     */
1306    private String mCurResumedPackage = null;
1307    private int mCurResumedUid = -1;
1308
1309    /**
1310     * For reporting to battery stats the apps currently running foreground
1311     * service.  The ProcessMap is package/uid tuples; each of these contain
1312     * an array of the currently foreground processes.
1313     */
1314    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1315            = new ProcessMap<ArrayList<ProcessRecord>>();
1316
1317    /**
1318     * This is set if we had to do a delayed dexopt of an app before launching
1319     * it, to increase the ANR timeouts in that case.
1320     */
1321    boolean mDidDexOpt;
1322
1323    /**
1324     * Set if the systemServer made a call to enterSafeMode.
1325     */
1326    boolean mSafeMode;
1327
1328    /**
1329     * If true, we are running under a test environment so will sample PSS from processes
1330     * much more rapidly to try to collect better data when the tests are rapidly
1331     * running through apps.
1332     */
1333    boolean mTestPssMode = false;
1334
1335    String mDebugApp = null;
1336    boolean mWaitForDebugger = false;
1337    boolean mDebugTransient = false;
1338    String mOrigDebugApp = null;
1339    boolean mOrigWaitForDebugger = false;
1340    boolean mAlwaysFinishActivities = false;
1341    boolean mLenientBackgroundCheck = false;
1342    boolean mForceResizableActivities;
1343    boolean mSupportsMultiWindow;
1344    boolean mSupportsFreeformWindowManagement;
1345    boolean mSupportsPictureInPicture;
1346    Rect mDefaultPinnedStackBounds;
1347    IActivityController mController = null;
1348    boolean mControllerIsAMonkey = false;
1349    String mProfileApp = null;
1350    ProcessRecord mProfileProc = null;
1351    String mProfileFile;
1352    ParcelFileDescriptor mProfileFd;
1353    int mSamplingInterval = 0;
1354    boolean mAutoStopProfiler = false;
1355    int mProfileType = 0;
1356    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1357    String mMemWatchDumpProcName;
1358    String mMemWatchDumpFile;
1359    int mMemWatchDumpPid;
1360    int mMemWatchDumpUid;
1361    String mTrackAllocationApp = null;
1362    String mNativeDebuggingApp = null;
1363
1364    final long[] mTmpLong = new long[2];
1365
1366    static final class ProcessChangeItem {
1367        static final int CHANGE_ACTIVITIES = 1<<0;
1368        static final int CHANGE_PROCESS_STATE = 1<<1;
1369        int changes;
1370        int uid;
1371        int pid;
1372        int processState;
1373        boolean foregroundActivities;
1374    }
1375
1376    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1377    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1378
1379    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1380    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1381
1382    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1383    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1384
1385    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1386    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1387
1388    /**
1389     * Runtime CPU use collection thread.  This object's lock is used to
1390     * perform synchronization with the thread (notifying it to run).
1391     */
1392    final Thread mProcessCpuThread;
1393
1394    /**
1395     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1396     * Must acquire this object's lock when accessing it.
1397     * NOTE: this lock will be held while doing long operations (trawling
1398     * through all processes in /proc), so it should never be acquired by
1399     * any critical paths such as when holding the main activity manager lock.
1400     */
1401    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1402            MONITOR_THREAD_CPU_USAGE);
1403    final AtomicLong mLastCpuTime = new AtomicLong(0);
1404    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1405
1406    long mLastWriteTime = 0;
1407
1408    /**
1409     * Used to retain an update lock when the foreground activity is in
1410     * immersive mode.
1411     */
1412    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1413
1414    /**
1415     * Set to true after the system has finished booting.
1416     */
1417    boolean mBooted = false;
1418
1419    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1420    int mProcessLimitOverride = -1;
1421
1422    WindowManagerService mWindowManager;
1423    final ActivityThread mSystemThread;
1424
1425    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1426        final ProcessRecord mApp;
1427        final int mPid;
1428        final IApplicationThread mAppThread;
1429
1430        AppDeathRecipient(ProcessRecord app, int pid,
1431                IApplicationThread thread) {
1432            if (DEBUG_ALL) Slog.v(
1433                TAG, "New death recipient " + this
1434                + " for thread " + thread.asBinder());
1435            mApp = app;
1436            mPid = pid;
1437            mAppThread = thread;
1438        }
1439
1440        @Override
1441        public void binderDied() {
1442            if (DEBUG_ALL) Slog.v(
1443                TAG, "Death received in " + this
1444                + " for thread " + mAppThread.asBinder());
1445            synchronized(ActivityManagerService.this) {
1446                appDiedLocked(mApp, mPid, mAppThread, true);
1447            }
1448        }
1449    }
1450
1451    static final int SHOW_ERROR_UI_MSG = 1;
1452    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1453    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1454    static final int UPDATE_CONFIGURATION_MSG = 4;
1455    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1456    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1457    static final int SERVICE_TIMEOUT_MSG = 12;
1458    static final int UPDATE_TIME_ZONE = 13;
1459    static final int SHOW_UID_ERROR_UI_MSG = 14;
1460    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1461    static final int PROC_START_TIMEOUT_MSG = 20;
1462    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1463    static final int KILL_APPLICATION_MSG = 22;
1464    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1465    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1466    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1467    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1468    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1469    static final int CLEAR_DNS_CACHE_MSG = 28;
1470    static final int UPDATE_HTTP_PROXY_MSG = 29;
1471    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1472    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1473    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1474    static final int REPORT_MEM_USAGE_MSG = 33;
1475    static final int REPORT_USER_SWITCH_MSG = 34;
1476    static final int CONTINUE_USER_SWITCH_MSG = 35;
1477    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1478    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1479    static final int PERSIST_URI_GRANTS_MSG = 38;
1480    static final int REQUEST_ALL_PSS_MSG = 39;
1481    static final int START_PROFILES_MSG = 40;
1482    static final int UPDATE_TIME = 41;
1483    static final int SYSTEM_USER_START_MSG = 42;
1484    static final int SYSTEM_USER_CURRENT_MSG = 43;
1485    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1486    static final int FINISH_BOOTING_MSG = 45;
1487    static final int START_USER_SWITCH_UI_MSG = 46;
1488    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1489    static final int DISMISS_DIALOG_UI_MSG = 48;
1490    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1491    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1492    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1493    static final int DELETE_DUMPHEAP_MSG = 52;
1494    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1495    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1496    static final int REPORT_TIME_TRACKER_MSG = 55;
1497    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1498    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1499    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1500    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1501    static final int IDLE_UIDS_MSG = 60;
1502    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1503    static final int LOG_STACK_STATE = 62;
1504    static final int VR_MODE_CHANGE_MSG = 63;
1505    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1506    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1507    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1508    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1509    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1510    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1511
1512    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1513    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1514    static final int FIRST_COMPAT_MODE_MSG = 300;
1515    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1516
1517    static ServiceThread sKillThread = null;
1518    static KillHandler sKillHandler = null;
1519
1520    CompatModeDialog mCompatModeDialog;
1521    long mLastMemUsageReportTime = 0;
1522
1523    /**
1524     * Flag whether the current user is a "monkey", i.e. whether
1525     * the UI is driven by a UI automation tool.
1526     */
1527    private boolean mUserIsMonkey;
1528
1529    /** Flag whether the device has a Recents UI */
1530    boolean mHasRecents;
1531
1532    /** The dimensions of the thumbnails in the Recents UI. */
1533    int mThumbnailWidth;
1534    int mThumbnailHeight;
1535    float mFullscreenThumbnailScale;
1536
1537    final ServiceThread mHandlerThread;
1538    final MainHandler mHandler;
1539    final UiHandler mUiHandler;
1540
1541    PackageManagerInternal mPackageManagerInt;
1542
1543    // VoiceInteraction session ID that changes for each new request except when
1544    // being called for multiwindow assist in a single session.
1545    private int mViSessionId = 1000;
1546
1547    final class KillHandler extends Handler {
1548        static final int KILL_PROCESS_GROUP_MSG = 4000;
1549
1550        public KillHandler(Looper looper) {
1551            super(looper, null, true);
1552        }
1553
1554        @Override
1555        public void handleMessage(Message msg) {
1556            switch (msg.what) {
1557                case KILL_PROCESS_GROUP_MSG:
1558                {
1559                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1560                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1561                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1562                }
1563                break;
1564
1565                default:
1566                    super.handleMessage(msg);
1567            }
1568        }
1569    }
1570
1571    final class UiHandler extends Handler {
1572        public UiHandler() {
1573            super(com.android.server.UiThread.get().getLooper(), null, true);
1574        }
1575
1576        @Override
1577        public void handleMessage(Message msg) {
1578            switch (msg.what) {
1579            case SHOW_ERROR_UI_MSG: {
1580                mAppErrors.handleShowAppErrorUi(msg);
1581                ensureBootCompleted();
1582            } break;
1583            case SHOW_NOT_RESPONDING_UI_MSG: {
1584                mAppErrors.handleShowAnrUi(msg);
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1588                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1589                synchronized (ActivityManagerService.this) {
1590                    ProcessRecord proc = (ProcessRecord) data.get("app");
1591                    if (proc == null) {
1592                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1593                        break;
1594                    }
1595                    if (proc.crashDialog != null) {
1596                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1597                        return;
1598                    }
1599                    AppErrorResult res = (AppErrorResult) data.get("result");
1600                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1601                        Dialog d = new StrictModeViolationDialog(mContext,
1602                                ActivityManagerService.this, res, proc);
1603                        d.show();
1604                        proc.crashDialog = d;
1605                    } else {
1606                        // The device is asleep, so just pretend that the user
1607                        // saw a crash dialog and hit "force quit".
1608                        res.set(0);
1609                    }
1610                }
1611                ensureBootCompleted();
1612            } break;
1613            case SHOW_FACTORY_ERROR_UI_MSG: {
1614                Dialog d = new FactoryErrorDialog(
1615                    mContext, msg.getData().getCharSequence("msg"));
1616                d.show();
1617                ensureBootCompleted();
1618            } break;
1619            case WAIT_FOR_DEBUGGER_UI_MSG: {
1620                synchronized (ActivityManagerService.this) {
1621                    ProcessRecord app = (ProcessRecord)msg.obj;
1622                    if (msg.arg1 != 0) {
1623                        if (!app.waitedForDebugger) {
1624                            Dialog d = new AppWaitingForDebuggerDialog(
1625                                    ActivityManagerService.this,
1626                                    mContext, app);
1627                            app.waitDialog = d;
1628                            app.waitedForDebugger = true;
1629                            d.show();
1630                        }
1631                    } else {
1632                        if (app.waitDialog != null) {
1633                            app.waitDialog.dismiss();
1634                            app.waitDialog = null;
1635                        }
1636                    }
1637                }
1638            } break;
1639            case SHOW_UID_ERROR_UI_MSG: {
1640                if (mShowDialogs) {
1641                    AlertDialog d = new BaseErrorDialog(mContext);
1642                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1643                    d.setCancelable(false);
1644                    d.setTitle(mContext.getText(R.string.android_system_label));
1645                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1646                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1647                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1648                    d.show();
1649                }
1650            } break;
1651            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1652                if (mShowDialogs) {
1653                    AlertDialog d = new BaseErrorDialog(mContext);
1654                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1655                    d.setCancelable(false);
1656                    d.setTitle(mContext.getText(R.string.android_system_label));
1657                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1658                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1659                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1660                    d.show();
1661                }
1662            } break;
1663            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1664                synchronized (ActivityManagerService.this) {
1665                    ActivityRecord ar = (ActivityRecord) msg.obj;
1666                    if (mCompatModeDialog != null) {
1667                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1668                                ar.info.applicationInfo.packageName)) {
1669                            return;
1670                        }
1671                        mCompatModeDialog.dismiss();
1672                        mCompatModeDialog = null;
1673                    }
1674                    if (ar != null && false) {
1675                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1676                                ar.packageName)) {
1677                            int mode = mCompatModePackages.computeCompatModeLocked(
1678                                    ar.info.applicationInfo);
1679                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1680                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1681                                mCompatModeDialog = new CompatModeDialog(
1682                                        ActivityManagerService.this, mContext,
1683                                        ar.info.applicationInfo);
1684                                mCompatModeDialog.show();
1685                            }
1686                        }
1687                    }
1688                }
1689                break;
1690            }
1691            case START_USER_SWITCH_UI_MSG: {
1692                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1693                break;
1694            }
1695            case DISMISS_DIALOG_UI_MSG: {
1696                final Dialog d = (Dialog) msg.obj;
1697                d.dismiss();
1698                break;
1699            }
1700            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1701                dispatchProcessesChanged();
1702                break;
1703            }
1704            case DISPATCH_PROCESS_DIED_UI_MSG: {
1705                final int pid = msg.arg1;
1706                final int uid = msg.arg2;
1707                dispatchProcessDied(pid, uid);
1708                break;
1709            }
1710            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1711                dispatchUidsChanged();
1712            } break;
1713            }
1714        }
1715    }
1716
1717    final class MainHandler extends Handler {
1718        public MainHandler(Looper looper) {
1719            super(looper, null, true);
1720        }
1721
1722        @Override
1723        public void handleMessage(Message msg) {
1724            switch (msg.what) {
1725            case UPDATE_CONFIGURATION_MSG: {
1726                final ContentResolver resolver = mContext.getContentResolver();
1727                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1728                        msg.arg1);
1729            } break;
1730            case GC_BACKGROUND_PROCESSES_MSG: {
1731                synchronized (ActivityManagerService.this) {
1732                    performAppGcsIfAppropriateLocked();
1733                }
1734            } break;
1735            case SERVICE_TIMEOUT_MSG: {
1736                if (mDidDexOpt) {
1737                    mDidDexOpt = false;
1738                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1739                    nmsg.obj = msg.obj;
1740                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1741                    return;
1742                }
1743                mServices.serviceTimeout((ProcessRecord)msg.obj);
1744            } break;
1745            case UPDATE_TIME_ZONE: {
1746                synchronized (ActivityManagerService.this) {
1747                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1748                        ProcessRecord r = mLruProcesses.get(i);
1749                        if (r.thread != null) {
1750                            try {
1751                                r.thread.updateTimeZone();
1752                            } catch (RemoteException ex) {
1753                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1754                            }
1755                        }
1756                    }
1757                }
1758            } break;
1759            case CLEAR_DNS_CACHE_MSG: {
1760                synchronized (ActivityManagerService.this) {
1761                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1762                        ProcessRecord r = mLruProcesses.get(i);
1763                        if (r.thread != null) {
1764                            try {
1765                                r.thread.clearDnsCache();
1766                            } catch (RemoteException ex) {
1767                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1768                            }
1769                        }
1770                    }
1771                }
1772            } break;
1773            case UPDATE_HTTP_PROXY_MSG: {
1774                ProxyInfo proxy = (ProxyInfo)msg.obj;
1775                String host = "";
1776                String port = "";
1777                String exclList = "";
1778                Uri pacFileUrl = Uri.EMPTY;
1779                if (proxy != null) {
1780                    host = proxy.getHost();
1781                    port = Integer.toString(proxy.getPort());
1782                    exclList = proxy.getExclusionListAsString();
1783                    pacFileUrl = proxy.getPacFileUrl();
1784                }
1785                synchronized (ActivityManagerService.this) {
1786                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1787                        ProcessRecord r = mLruProcesses.get(i);
1788                        if (r.thread != null) {
1789                            try {
1790                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1791                            } catch (RemoteException ex) {
1792                                Slog.w(TAG, "Failed to update http proxy for: " +
1793                                        r.info.processName);
1794                            }
1795                        }
1796                    }
1797                }
1798            } break;
1799            case PROC_START_TIMEOUT_MSG: {
1800                if (mDidDexOpt) {
1801                    mDidDexOpt = false;
1802                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1803                    nmsg.obj = msg.obj;
1804                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1805                    return;
1806                }
1807                ProcessRecord app = (ProcessRecord)msg.obj;
1808                synchronized (ActivityManagerService.this) {
1809                    processStartTimedOutLocked(app);
1810                }
1811            } break;
1812            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1813                ProcessRecord app = (ProcessRecord)msg.obj;
1814                synchronized (ActivityManagerService.this) {
1815                    processContentProviderPublishTimedOutLocked(app);
1816                }
1817            } break;
1818            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1821                }
1822            } break;
1823            case KILL_APPLICATION_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    int appid = msg.arg1;
1826                    boolean restart = (msg.arg2 == 1);
1827                    Bundle bundle = (Bundle)msg.obj;
1828                    String pkg = bundle.getString("pkg");
1829                    String reason = bundle.getString("reason");
1830                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1831                            false, UserHandle.USER_ALL, reason);
1832                }
1833            } break;
1834            case FINALIZE_PENDING_INTENT_MSG: {
1835                ((PendingIntentRecord)msg.obj).completeFinalize();
1836            } break;
1837            case POST_HEAVY_NOTIFICATION_MSG: {
1838                INotificationManager inm = NotificationManager.getService();
1839                if (inm == null) {
1840                    return;
1841                }
1842
1843                ActivityRecord root = (ActivityRecord)msg.obj;
1844                ProcessRecord process = root.app;
1845                if (process == null) {
1846                    return;
1847                }
1848
1849                try {
1850                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1851                    String text = mContext.getString(R.string.heavy_weight_notification,
1852                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1853                    Notification notification = new Notification.Builder(context)
1854                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1855                            .setWhen(0)
1856                            .setOngoing(true)
1857                            .setTicker(text)
1858                            .setColor(mContext.getColor(
1859                                    com.android.internal.R.color.system_notification_accent_color))
1860                            .setContentTitle(text)
1861                            .setContentText(
1862                                    mContext.getText(R.string.heavy_weight_notification_detail))
1863                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1864                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1865                                    new UserHandle(root.userId)))
1866                            .build();
1867                    try {
1868                        int[] outId = new int[1];
1869                        inm.enqueueNotificationWithTag("android", "android", null,
1870                                R.string.heavy_weight_notification,
1871                                notification, outId, root.userId);
1872                    } catch (RuntimeException e) {
1873                        Slog.w(ActivityManagerService.TAG,
1874                                "Error showing notification for heavy-weight app", e);
1875                    } catch (RemoteException e) {
1876                    }
1877                } catch (NameNotFoundException e) {
1878                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1879                }
1880            } break;
1881            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1882                INotificationManager inm = NotificationManager.getService();
1883                if (inm == null) {
1884                    return;
1885                }
1886                try {
1887                    inm.cancelNotificationWithTag("android", null,
1888                            R.string.heavy_weight_notification,  msg.arg1);
1889                } catch (RuntimeException e) {
1890                    Slog.w(ActivityManagerService.TAG,
1891                            "Error canceling notification for service", e);
1892                } catch (RemoteException e) {
1893                }
1894            } break;
1895            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1896                synchronized (ActivityManagerService.this) {
1897                    checkExcessivePowerUsageLocked(true);
1898                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1899                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1900                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1901                }
1902            } break;
1903            case REPORT_MEM_USAGE_MSG: {
1904                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1905                Thread thread = new Thread() {
1906                    @Override public void run() {
1907                        reportMemUsage(memInfos);
1908                    }
1909                };
1910                thread.start();
1911                break;
1912            }
1913            case REPORT_USER_SWITCH_MSG: {
1914                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1915                break;
1916            }
1917            case CONTINUE_USER_SWITCH_MSG: {
1918                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1919                break;
1920            }
1921            case USER_SWITCH_TIMEOUT_MSG: {
1922                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1923                break;
1924            }
1925            case IMMERSIVE_MODE_LOCK_MSG: {
1926                final boolean nextState = (msg.arg1 != 0);
1927                if (mUpdateLock.isHeld() != nextState) {
1928                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1929                            "Applying new update lock state '" + nextState
1930                            + "' for " + (ActivityRecord)msg.obj);
1931                    if (nextState) {
1932                        mUpdateLock.acquire();
1933                    } else {
1934                        mUpdateLock.release();
1935                    }
1936                }
1937                break;
1938            }
1939            case PERSIST_URI_GRANTS_MSG: {
1940                writeGrantedUriPermissions();
1941                break;
1942            }
1943            case REQUEST_ALL_PSS_MSG: {
1944                synchronized (ActivityManagerService.this) {
1945                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1946                }
1947                break;
1948            }
1949            case START_PROFILES_MSG: {
1950                synchronized (ActivityManagerService.this) {
1951                    mUserController.startProfilesLocked();
1952                }
1953                break;
1954            }
1955            case UPDATE_TIME: {
1956                synchronized (ActivityManagerService.this) {
1957                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1958                        ProcessRecord r = mLruProcesses.get(i);
1959                        if (r.thread != null) {
1960                            try {
1961                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1962                            } catch (RemoteException ex) {
1963                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1964                            }
1965                        }
1966                    }
1967                }
1968                break;
1969            }
1970            case SYSTEM_USER_START_MSG: {
1971                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1972                        Integer.toString(msg.arg1), msg.arg1);
1973                mSystemServiceManager.startUser(msg.arg1);
1974                break;
1975            }
1976            case SYSTEM_USER_UNLOCK_MSG: {
1977                final int userId = msg.arg1;
1978                mSystemServiceManager.unlockUser(userId);
1979                synchronized (ActivityManagerService.this) {
1980                    mRecentTasks.loadUserRecentsLocked(userId);
1981                }
1982                if (userId == UserHandle.USER_SYSTEM) {
1983                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1984                }
1985                installEncryptionUnawareProviders(userId);
1986                mUserController.finishUserUnlocked((UserState) msg.obj);
1987                break;
1988            }
1989            case SYSTEM_USER_CURRENT_MSG: {
1990                mBatteryStatsService.noteEvent(
1991                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1992                        Integer.toString(msg.arg2), msg.arg2);
1993                mBatteryStatsService.noteEvent(
1994                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1995                        Integer.toString(msg.arg1), msg.arg1);
1996                mSystemServiceManager.switchUser(msg.arg1);
1997                break;
1998            }
1999            case ENTER_ANIMATION_COMPLETE_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2002                    if (r != null && r.app != null && r.app.thread != null) {
2003                        try {
2004                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2005                        } catch (RemoteException e) {
2006                        }
2007                    }
2008                }
2009                break;
2010            }
2011            case FINISH_BOOTING_MSG: {
2012                if (msg.arg1 != 0) {
2013                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2014                    finishBooting();
2015                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2016                }
2017                if (msg.arg2 != 0) {
2018                    enableScreenAfterBoot();
2019                }
2020                break;
2021            }
2022            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2023                try {
2024                    Locale l = (Locale) msg.obj;
2025                    IBinder service = ServiceManager.getService("mount");
2026                    IMountService mountService = IMountService.Stub.asInterface(service);
2027                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2028                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2029                } catch (RemoteException e) {
2030                    Log.e(TAG, "Error storing locale for decryption UI", e);
2031                }
2032                break;
2033            }
2034            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2035                synchronized (ActivityManagerService.this) {
2036                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2037                        try {
2038                            // Make a one-way callback to the listener
2039                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2040                        } catch (RemoteException e){
2041                            // Handled by the RemoteCallbackList
2042                        }
2043                    }
2044                    mTaskStackListeners.finishBroadcast();
2045                }
2046                break;
2047            }
2048            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2049                synchronized (ActivityManagerService.this) {
2050                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2051                        try {
2052                            // Make a one-way callback to the listener
2053                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2054                        } catch (RemoteException e){
2055                            // Handled by the RemoteCallbackList
2056                        }
2057                    }
2058                    mTaskStackListeners.finishBroadcast();
2059                }
2060                break;
2061            }
2062            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2063                synchronized (ActivityManagerService.this) {
2064                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2065                        try {
2066                            // Make a one-way callback to the listener
2067                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2068                        } catch (RemoteException e){
2069                            // Handled by the RemoteCallbackList
2070                        }
2071                    }
2072                    mTaskStackListeners.finishBroadcast();
2073                }
2074                break;
2075            }
2076            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2077                synchronized (ActivityManagerService.this) {
2078                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2079                        try {
2080                            // Make a one-way callback to the listener
2081                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2082                        } catch (RemoteException e){
2083                            // Handled by the RemoteCallbackList
2084                        }
2085                    }
2086                    mTaskStackListeners.finishBroadcast();
2087                }
2088                break;
2089            }
2090            case NOTIFY_FORCED_RESIZABLE_MSG: {
2091                synchronized (ActivityManagerService.this) {
2092                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2093                        try {
2094                            // Make a one-way callback to the listener
2095                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2096                                    (String) msg.obj, msg.arg1);
2097                        } catch (RemoteException e){
2098                            // Handled by the RemoteCallbackList
2099                        }
2100                    }
2101                    mTaskStackListeners.finishBroadcast();
2102                }
2103                break;
2104            }
2105                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2106                    synchronized (ActivityManagerService.this) {
2107                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2108                            try {
2109                                // Make a one-way callback to the listener
2110                                mTaskStackListeners.getBroadcastItem(i)
2111                                        .onActivityDismissingDockedStack();
2112                            } catch (RemoteException e){
2113                                // Handled by the RemoteCallbackList
2114                            }
2115                        }
2116                        mTaskStackListeners.finishBroadcast();
2117                    }
2118                    break;
2119                }
2120            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2121                final int uid = msg.arg1;
2122                final byte[] firstPacket = (byte[]) msg.obj;
2123
2124                synchronized (mPidsSelfLocked) {
2125                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2126                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2127                        if (p.uid == uid) {
2128                            try {
2129                                p.thread.notifyCleartextNetwork(firstPacket);
2130                            } catch (RemoteException ignored) {
2131                            }
2132                        }
2133                    }
2134                }
2135                break;
2136            }
2137            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2138                final String procName;
2139                final int uid;
2140                final long memLimit;
2141                final String reportPackage;
2142                synchronized (ActivityManagerService.this) {
2143                    procName = mMemWatchDumpProcName;
2144                    uid = mMemWatchDumpUid;
2145                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2146                    if (val == null) {
2147                        val = mMemWatchProcesses.get(procName, 0);
2148                    }
2149                    if (val != null) {
2150                        memLimit = val.first;
2151                        reportPackage = val.second;
2152                    } else {
2153                        memLimit = 0;
2154                        reportPackage = null;
2155                    }
2156                }
2157                if (procName == null) {
2158                    return;
2159                }
2160
2161                if (DEBUG_PSS) Slog.d(TAG_PSS,
2162                        "Showing dump heap notification from " + procName + "/" + uid);
2163
2164                INotificationManager inm = NotificationManager.getService();
2165                if (inm == null) {
2166                    return;
2167                }
2168
2169                String text = mContext.getString(R.string.dump_heap_notification, procName);
2170
2171
2172                Intent deleteIntent = new Intent();
2173                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2174                Intent intent = new Intent();
2175                intent.setClassName("android", DumpHeapActivity.class.getName());
2176                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2177                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2178                if (reportPackage != null) {
2179                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2180                }
2181                int userId = UserHandle.getUserId(uid);
2182                Notification notification = new Notification.Builder(mContext)
2183                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2184                        .setWhen(0)
2185                        .setOngoing(true)
2186                        .setAutoCancel(true)
2187                        .setTicker(text)
2188                        .setColor(mContext.getColor(
2189                                com.android.internal.R.color.system_notification_accent_color))
2190                        .setContentTitle(text)
2191                        .setContentText(
2192                                mContext.getText(R.string.dump_heap_notification_detail))
2193                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2194                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2195                                new UserHandle(userId)))
2196                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2197                                deleteIntent, 0, UserHandle.SYSTEM))
2198                        .build();
2199
2200                try {
2201                    int[] outId = new int[1];
2202                    inm.enqueueNotificationWithTag("android", "android", null,
2203                            R.string.dump_heap_notification,
2204                            notification, outId, userId);
2205                } catch (RuntimeException e) {
2206                    Slog.w(ActivityManagerService.TAG,
2207                            "Error showing notification for dump heap", e);
2208                } catch (RemoteException e) {
2209                }
2210            } break;
2211            case DELETE_DUMPHEAP_MSG: {
2212                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2213                        DumpHeapActivity.JAVA_URI,
2214                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2215                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2216                        UserHandle.myUserId());
2217                synchronized (ActivityManagerService.this) {
2218                    mMemWatchDumpFile = null;
2219                    mMemWatchDumpProcName = null;
2220                    mMemWatchDumpPid = -1;
2221                    mMemWatchDumpUid = -1;
2222                }
2223            } break;
2224            case FOREGROUND_PROFILE_CHANGED_MSG: {
2225                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2226            } break;
2227            case REPORT_TIME_TRACKER_MSG: {
2228                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2229                tracker.deliverResult(mContext);
2230            } break;
2231            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2232                mUserController.dispatchUserSwitchComplete(msg.arg1);
2233            } break;
2234            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2235                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2236                try {
2237                    connection.shutdown();
2238                } catch (RemoteException e) {
2239                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2240                }
2241                // Only a UiAutomation can set this flag and now that
2242                // it is finished we make sure it is reset to its default.
2243                mUserIsMonkey = false;
2244            } break;
2245            case APP_BOOST_DEACTIVATE_MSG: {
2246                synchronized(ActivityManagerService.this) {
2247                    if (mIsBoosted) {
2248                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2249                            nativeMigrateFromBoost();
2250                            mIsBoosted = false;
2251                            mBoostStartTime = 0;
2252                        } else {
2253                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2254                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2255                        }
2256                    }
2257                }
2258            } break;
2259            case IDLE_UIDS_MSG: {
2260                idleUids();
2261            } break;
2262            case LOG_STACK_STATE: {
2263                synchronized (ActivityManagerService.this) {
2264                    mStackSupervisor.logStackState();
2265                }
2266            } break;
2267            case VR_MODE_CHANGE_MSG: {
2268                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2269                final ActivityRecord r = (ActivityRecord) msg.obj;
2270                boolean vrMode;
2271                ComponentName requestedPackage;
2272                ComponentName callingPackage;
2273                int userId;
2274                synchronized (ActivityManagerService.this) {
2275                    vrMode = r.requestedVrComponent != null;
2276                    requestedPackage = r.requestedVrComponent;
2277                    userId = r.userId;
2278                    callingPackage = r.info.getComponentName();
2279                    if (mInVrMode != vrMode) {
2280                        mInVrMode = vrMode;
2281                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2282                    }
2283                }
2284                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2285            } break;
2286            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2287                final ActivityRecord r = (ActivityRecord) msg.obj;
2288                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2289                if (needsVrMode) {
2290                    VrManagerInternal vrService =
2291                            LocalServices.getService(VrManagerInternal.class);
2292                    boolean enable = msg.arg1 == 1;
2293                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2294                            r.info.getComponentName());
2295                }
2296            } break;
2297            }
2298        }
2299    };
2300
2301    static final int COLLECT_PSS_BG_MSG = 1;
2302
2303    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2304        @Override
2305        public void handleMessage(Message msg) {
2306            switch (msg.what) {
2307            case COLLECT_PSS_BG_MSG: {
2308                long start = SystemClock.uptimeMillis();
2309                MemInfoReader memInfo = null;
2310                synchronized (ActivityManagerService.this) {
2311                    if (mFullPssPending) {
2312                        mFullPssPending = false;
2313                        memInfo = new MemInfoReader();
2314                    }
2315                }
2316                if (memInfo != null) {
2317                    updateCpuStatsNow();
2318                    long nativeTotalPss = 0;
2319                    synchronized (mProcessCpuTracker) {
2320                        final int N = mProcessCpuTracker.countStats();
2321                        for (int j=0; j<N; j++) {
2322                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2323                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2324                                // This is definitely an application process; skip it.
2325                                continue;
2326                            }
2327                            synchronized (mPidsSelfLocked) {
2328                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2329                                    // This is one of our own processes; skip it.
2330                                    continue;
2331                                }
2332                            }
2333                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2334                        }
2335                    }
2336                    memInfo.readMemInfo();
2337                    synchronized (ActivityManagerService.this) {
2338                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2339                                + (SystemClock.uptimeMillis()-start) + "ms");
2340                        final long cachedKb = memInfo.getCachedSizeKb();
2341                        final long freeKb = memInfo.getFreeSizeKb();
2342                        final long zramKb = memInfo.getZramTotalSizeKb();
2343                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2344                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2345                                kernelKb*1024, nativeTotalPss*1024);
2346                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2347                                nativeTotalPss);
2348                    }
2349                }
2350
2351                int num = 0;
2352                long[] tmp = new long[2];
2353                do {
2354                    ProcessRecord proc;
2355                    int procState;
2356                    int pid;
2357                    long lastPssTime;
2358                    synchronized (ActivityManagerService.this) {
2359                        if (mPendingPssProcesses.size() <= 0) {
2360                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2361                                    "Collected PSS of " + num + " processes in "
2362                                    + (SystemClock.uptimeMillis() - start) + "ms");
2363                            mPendingPssProcesses.clear();
2364                            return;
2365                        }
2366                        proc = mPendingPssProcesses.remove(0);
2367                        procState = proc.pssProcState;
2368                        lastPssTime = proc.lastPssTime;
2369                        if (proc.thread != null && procState == proc.setProcState
2370                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2371                                        < SystemClock.uptimeMillis()) {
2372                            pid = proc.pid;
2373                        } else {
2374                            proc = null;
2375                            pid = 0;
2376                        }
2377                    }
2378                    if (proc != null) {
2379                        long pss = Debug.getPss(pid, tmp, null);
2380                        synchronized (ActivityManagerService.this) {
2381                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2382                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2383                                num++;
2384                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2385                                        SystemClock.uptimeMillis());
2386                            }
2387                        }
2388                    }
2389                } while (true);
2390            }
2391            }
2392        }
2393    };
2394
2395    public void setSystemProcess() {
2396        try {
2397            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2398            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2399            ServiceManager.addService("meminfo", new MemBinder(this));
2400            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2401            ServiceManager.addService("dbinfo", new DbBinder(this));
2402            if (MONITOR_CPU_USAGE) {
2403                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2404            }
2405            ServiceManager.addService("permission", new PermissionController(this));
2406            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2407
2408            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2409                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2410            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2411
2412            synchronized (this) {
2413                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2414                app.persistent = true;
2415                app.pid = MY_PID;
2416                app.maxAdj = ProcessList.SYSTEM_ADJ;
2417                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2418                synchronized (mPidsSelfLocked) {
2419                    mPidsSelfLocked.put(app.pid, app);
2420                }
2421                updateLruProcessLocked(app, false, null);
2422                updateOomAdjLocked();
2423            }
2424        } catch (PackageManager.NameNotFoundException e) {
2425            throw new RuntimeException(
2426                    "Unable to find android system package", e);
2427        }
2428    }
2429
2430    public void setWindowManager(WindowManagerService wm) {
2431        mWindowManager = wm;
2432        mStackSupervisor.setWindowManager(wm);
2433        mActivityStarter.setWindowManager(wm);
2434    }
2435
2436    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2437        mUsageStatsService = usageStatsManager;
2438    }
2439
2440    public void startObservingNativeCrashes() {
2441        final NativeCrashListener ncl = new NativeCrashListener(this);
2442        ncl.start();
2443    }
2444
2445    public IAppOpsService getAppOpsService() {
2446        return mAppOpsService;
2447    }
2448
2449    static class MemBinder extends Binder {
2450        ActivityManagerService mActivityManagerService;
2451        MemBinder(ActivityManagerService activityManagerService) {
2452            mActivityManagerService = activityManagerService;
2453        }
2454
2455        @Override
2456        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2457            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2458                    != PackageManager.PERMISSION_GRANTED) {
2459                pw.println("Permission Denial: can't dump meminfo from from pid="
2460                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2461                        + " without permission " + android.Manifest.permission.DUMP);
2462                return;
2463            }
2464
2465            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2466        }
2467    }
2468
2469    static class GraphicsBinder extends Binder {
2470        ActivityManagerService mActivityManagerService;
2471        GraphicsBinder(ActivityManagerService activityManagerService) {
2472            mActivityManagerService = activityManagerService;
2473        }
2474
2475        @Override
2476        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2477            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2478                    != PackageManager.PERMISSION_GRANTED) {
2479                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2480                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2481                        + " without permission " + android.Manifest.permission.DUMP);
2482                return;
2483            }
2484
2485            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2486        }
2487    }
2488
2489    static class DbBinder extends Binder {
2490        ActivityManagerService mActivityManagerService;
2491        DbBinder(ActivityManagerService activityManagerService) {
2492            mActivityManagerService = activityManagerService;
2493        }
2494
2495        @Override
2496        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2497            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2498                    != PackageManager.PERMISSION_GRANTED) {
2499                pw.println("Permission Denial: can't dump dbinfo from from pid="
2500                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2501                        + " without permission " + android.Manifest.permission.DUMP);
2502                return;
2503            }
2504
2505            mActivityManagerService.dumpDbInfo(fd, pw, args);
2506        }
2507    }
2508
2509    static class CpuBinder extends Binder {
2510        ActivityManagerService mActivityManagerService;
2511        CpuBinder(ActivityManagerService activityManagerService) {
2512            mActivityManagerService = activityManagerService;
2513        }
2514
2515        @Override
2516        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2517            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2518                    != PackageManager.PERMISSION_GRANTED) {
2519                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2520                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2521                        + " without permission " + android.Manifest.permission.DUMP);
2522                return;
2523            }
2524
2525            synchronized (mActivityManagerService.mProcessCpuTracker) {
2526                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2527                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2528                        SystemClock.uptimeMillis()));
2529            }
2530        }
2531    }
2532
2533    public static final class Lifecycle extends SystemService {
2534        private final ActivityManagerService mService;
2535
2536        public Lifecycle(Context context) {
2537            super(context);
2538            mService = new ActivityManagerService(context);
2539        }
2540
2541        @Override
2542        public void onStart() {
2543            mService.start();
2544        }
2545
2546        public ActivityManagerService getService() {
2547            return mService;
2548        }
2549    }
2550
2551    // Note: This method is invoked on the main thread but may need to attach various
2552    // handlers to other threads.  So take care to be explicit about the looper.
2553    public ActivityManagerService(Context systemContext) {
2554        mContext = systemContext;
2555        mFactoryTest = FactoryTest.getMode();
2556        mSystemThread = ActivityThread.currentActivityThread();
2557
2558        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2559
2560        mHandlerThread = new ServiceThread(TAG,
2561                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2562        mHandlerThread.start();
2563        mHandler = new MainHandler(mHandlerThread.getLooper());
2564        mUiHandler = new UiHandler();
2565
2566        /* static; one-time init here */
2567        if (sKillHandler == null) {
2568            sKillThread = new ServiceThread(TAG + ":kill",
2569                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2570            sKillThread.start();
2571            sKillHandler = new KillHandler(sKillThread.getLooper());
2572        }
2573
2574        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2575                "foreground", BROADCAST_FG_TIMEOUT, false);
2576        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "background", BROADCAST_BG_TIMEOUT, true);
2578        mBroadcastQueues[0] = mFgBroadcastQueue;
2579        mBroadcastQueues[1] = mBgBroadcastQueue;
2580
2581        mServices = new ActiveServices(this);
2582        mProviderMap = new ProviderMap(this);
2583        mAppErrors = new AppErrors(mContext, this);
2584
2585        // TODO: Move creation of battery stats service outside of activity manager service.
2586        File dataDir = Environment.getDataDirectory();
2587        File systemDir = new File(dataDir, "system");
2588        systemDir.mkdirs();
2589        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2590        mBatteryStatsService.getActiveStatistics().readLocked();
2591        mBatteryStatsService.scheduleWriteToDisk();
2592        mOnBattery = DEBUG_POWER ? true
2593                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2594        mBatteryStatsService.getActiveStatistics().setCallback(this);
2595
2596        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2597
2598        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2599        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2600                new IAppOpsCallback.Stub() {
2601                    @Override public void opChanged(int op, int uid, String packageName) {
2602                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2603                            if (mAppOpsService.checkOperation(op, uid, packageName)
2604                                    != AppOpsManager.MODE_ALLOWED) {
2605                                runInBackgroundDisabled(uid);
2606                            }
2607                        }
2608                    }
2609                });
2610
2611        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2612
2613        mUserController = new UserController(this);
2614
2615        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2616            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2617
2618        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2619
2620        mConfiguration.setToDefaults();
2621        mConfiguration.setLocales(LocaleList.getDefault());
2622
2623        mConfigurationSeq = mConfiguration.seq = 1;
2624        mProcessCpuTracker.init();
2625
2626        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2627        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2628        mStackSupervisor = new ActivityStackSupervisor(this);
2629        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2630        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2631
2632        mProcessCpuThread = new Thread("CpuTracker") {
2633            @Override
2634            public void run() {
2635                while (true) {
2636                    try {
2637                        try {
2638                            synchronized(this) {
2639                                final long now = SystemClock.uptimeMillis();
2640                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2641                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2642                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2643                                //        + ", write delay=" + nextWriteDelay);
2644                                if (nextWriteDelay < nextCpuDelay) {
2645                                    nextCpuDelay = nextWriteDelay;
2646                                }
2647                                if (nextCpuDelay > 0) {
2648                                    mProcessCpuMutexFree.set(true);
2649                                    this.wait(nextCpuDelay);
2650                                }
2651                            }
2652                        } catch (InterruptedException e) {
2653                        }
2654                        updateCpuStatsNow();
2655                    } catch (Exception e) {
2656                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2657                    }
2658                }
2659            }
2660        };
2661
2662        Watchdog.getInstance().addMonitor(this);
2663        Watchdog.getInstance().addThread(mHandler);
2664    }
2665
2666    public void setSystemServiceManager(SystemServiceManager mgr) {
2667        mSystemServiceManager = mgr;
2668    }
2669
2670    public void setInstaller(Installer installer) {
2671        mInstaller = installer;
2672    }
2673
2674    private void start() {
2675        Process.removeAllProcessGroups();
2676        mProcessCpuThread.start();
2677
2678        mBatteryStatsService.publish(mContext);
2679        mAppOpsService.publish(mContext);
2680        Slog.d("AppOps", "AppOpsService published");
2681        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2682    }
2683
2684    void onUserStoppedLocked(int userId) {
2685        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2686    }
2687
2688    public void initPowerManagement() {
2689        mStackSupervisor.initPowerManagement();
2690        mBatteryStatsService.initPowerManagement();
2691        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2692        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2693        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2694        mVoiceWakeLock.setReferenceCounted(false);
2695    }
2696
2697    @Override
2698    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2699            throws RemoteException {
2700        if (code == SYSPROPS_TRANSACTION) {
2701            // We need to tell all apps about the system property change.
2702            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2703            synchronized(this) {
2704                final int NP = mProcessNames.getMap().size();
2705                for (int ip=0; ip<NP; ip++) {
2706                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2707                    final int NA = apps.size();
2708                    for (int ia=0; ia<NA; ia++) {
2709                        ProcessRecord app = apps.valueAt(ia);
2710                        if (app.thread != null) {
2711                            procs.add(app.thread.asBinder());
2712                        }
2713                    }
2714                }
2715            }
2716
2717            int N = procs.size();
2718            for (int i=0; i<N; i++) {
2719                Parcel data2 = Parcel.obtain();
2720                try {
2721                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2722                } catch (RemoteException e) {
2723                }
2724                data2.recycle();
2725            }
2726        }
2727        try {
2728            return super.onTransact(code, data, reply, flags);
2729        } catch (RuntimeException e) {
2730            // The activity manager only throws security exceptions, so let's
2731            // log all others.
2732            if (!(e instanceof SecurityException)) {
2733                Slog.wtf(TAG, "Activity Manager Crash", e);
2734            }
2735            throw e;
2736        }
2737    }
2738
2739    void updateCpuStats() {
2740        final long now = SystemClock.uptimeMillis();
2741        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2742            return;
2743        }
2744        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2745            synchronized (mProcessCpuThread) {
2746                mProcessCpuThread.notify();
2747            }
2748        }
2749    }
2750
2751    void updateCpuStatsNow() {
2752        synchronized (mProcessCpuTracker) {
2753            mProcessCpuMutexFree.set(false);
2754            final long now = SystemClock.uptimeMillis();
2755            boolean haveNewCpuStats = false;
2756
2757            if (MONITOR_CPU_USAGE &&
2758                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2759                mLastCpuTime.set(now);
2760                mProcessCpuTracker.update();
2761                if (mProcessCpuTracker.hasGoodLastStats()) {
2762                    haveNewCpuStats = true;
2763                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2764                    //Slog.i(TAG, "Total CPU usage: "
2765                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2766
2767                    // Slog the cpu usage if the property is set.
2768                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2769                        int user = mProcessCpuTracker.getLastUserTime();
2770                        int system = mProcessCpuTracker.getLastSystemTime();
2771                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2772                        int irq = mProcessCpuTracker.getLastIrqTime();
2773                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2774                        int idle = mProcessCpuTracker.getLastIdleTime();
2775
2776                        int total = user + system + iowait + irq + softIrq + idle;
2777                        if (total == 0) total = 1;
2778
2779                        EventLog.writeEvent(EventLogTags.CPU,
2780                                ((user+system+iowait+irq+softIrq) * 100) / total,
2781                                (user * 100) / total,
2782                                (system * 100) / total,
2783                                (iowait * 100) / total,
2784                                (irq * 100) / total,
2785                                (softIrq * 100) / total);
2786                    }
2787                }
2788            }
2789
2790            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2791            synchronized(bstats) {
2792                synchronized(mPidsSelfLocked) {
2793                    if (haveNewCpuStats) {
2794                        if (bstats.startAddingCpuLocked()) {
2795                            int totalUTime = 0;
2796                            int totalSTime = 0;
2797                            final int N = mProcessCpuTracker.countStats();
2798                            for (int i=0; i<N; i++) {
2799                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2800                                if (!st.working) {
2801                                    continue;
2802                                }
2803                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2804                                totalUTime += st.rel_utime;
2805                                totalSTime += st.rel_stime;
2806                                if (pr != null) {
2807                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2808                                    if (ps == null || !ps.isActive()) {
2809                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2810                                                pr.info.uid, pr.processName);
2811                                    }
2812                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2813                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2814                                } else {
2815                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2816                                    if (ps == null || !ps.isActive()) {
2817                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2818                                                bstats.mapUid(st.uid), st.name);
2819                                    }
2820                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2821                                }
2822                            }
2823                            final int userTime = mProcessCpuTracker.getLastUserTime();
2824                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2825                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2826                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2827                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2828                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2829                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2830                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2831                        }
2832                    }
2833                }
2834
2835                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2836                    mLastWriteTime = now;
2837                    mBatteryStatsService.scheduleWriteToDisk();
2838                }
2839            }
2840        }
2841    }
2842
2843    @Override
2844    public void batteryNeedsCpuUpdate() {
2845        updateCpuStatsNow();
2846    }
2847
2848    @Override
2849    public void batteryPowerChanged(boolean onBattery) {
2850        // When plugging in, update the CPU stats first before changing
2851        // the plug state.
2852        updateCpuStatsNow();
2853        synchronized (this) {
2854            synchronized(mPidsSelfLocked) {
2855                mOnBattery = DEBUG_POWER ? true : onBattery;
2856            }
2857        }
2858    }
2859
2860    @Override
2861    public void batterySendBroadcast(Intent intent) {
2862        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2863                AppOpsManager.OP_NONE, null, false, false,
2864                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2865    }
2866
2867    /**
2868     * Initialize the application bind args. These are passed to each
2869     * process when the bindApplication() IPC is sent to the process. They're
2870     * lazily setup to make sure the services are running when they're asked for.
2871     */
2872    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2873        if (mAppBindArgs == null) {
2874            mAppBindArgs = new HashMap<>();
2875
2876            // Isolated processes won't get this optimization, so that we don't
2877            // violate the rules about which services they have access to.
2878            if (!isolated) {
2879                // Setup the application init args
2880                mAppBindArgs.put("package", ServiceManager.getService("package"));
2881                mAppBindArgs.put("window", ServiceManager.getService("window"));
2882                mAppBindArgs.put(Context.ALARM_SERVICE,
2883                        ServiceManager.getService(Context.ALARM_SERVICE));
2884            }
2885        }
2886        return mAppBindArgs;
2887    }
2888
2889    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2890        if (r == null || mFocusedActivity == r) {
2891            return false;
2892        }
2893
2894        if (!r.isFocusable()) {
2895            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2896            return false;
2897        }
2898
2899        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2900
2901        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2902        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2903                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2904        mDoingSetFocusedActivity = true;
2905
2906        final ActivityRecord last = mFocusedActivity;
2907        mFocusedActivity = r;
2908        if (r.task.isApplicationTask()) {
2909            if (mCurAppTimeTracker != r.appTimeTracker) {
2910                // We are switching app tracking.  Complete the current one.
2911                if (mCurAppTimeTracker != null) {
2912                    mCurAppTimeTracker.stop();
2913                    mHandler.obtainMessage(
2914                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2915                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2916                    mCurAppTimeTracker = null;
2917                }
2918                if (r.appTimeTracker != null) {
2919                    mCurAppTimeTracker = r.appTimeTracker;
2920                    startTimeTrackingFocusedActivityLocked();
2921                }
2922            } else {
2923                startTimeTrackingFocusedActivityLocked();
2924            }
2925        } else {
2926            r.appTimeTracker = null;
2927        }
2928        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2929        // TODO: Probably not, because we don't want to resume voice on switching
2930        // back to this activity
2931        if (r.task.voiceInteractor != null) {
2932            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2933        } else {
2934            finishRunningVoiceLocked();
2935            IVoiceInteractionSession session;
2936            if (last != null && ((session = last.task.voiceSession) != null
2937                    || (session = last.voiceSession) != null)) {
2938                // We had been in a voice interaction session, but now focused has
2939                // move to something different.  Just finish the session, we can't
2940                // return to it and retain the proper state and synchronization with
2941                // the voice interaction service.
2942                finishVoiceTask(session);
2943            }
2944        }
2945        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2946            mWindowManager.setFocusedApp(r.appToken, true);
2947        }
2948        applyUpdateLockStateLocked(r);
2949        applyUpdateVrModeLocked(r);
2950        if (mFocusedActivity.userId != mLastFocusedUserId) {
2951            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2952            mHandler.obtainMessage(
2953                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2954            mLastFocusedUserId = mFocusedActivity.userId;
2955        }
2956
2957        // Log a warning if the focused app is changed during the process. This could
2958        // indicate a problem of the focus setting logic!
2959        if (mFocusedActivity != r) Slog.w(TAG,
2960                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2961        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2962
2963        EventLogTags.writeAmFocusedActivity(
2964                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2965                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2966                reason);
2967        return true;
2968    }
2969
2970    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2971        if (mFocusedActivity != goingAway) {
2972            return;
2973        }
2974
2975        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2976        if (focusedStack != null) {
2977            final ActivityRecord top = focusedStack.topActivity();
2978            if (top != null && top.userId != mLastFocusedUserId) {
2979                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2980                mHandler.sendMessage(
2981                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2982                mLastFocusedUserId = top.userId;
2983            }
2984        }
2985
2986        // Try to move focus to another activity if possible.
2987        if (setFocusedActivityLocked(
2988                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2989            return;
2990        }
2991
2992        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2993                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2994        mFocusedActivity = null;
2995        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2996    }
2997
2998    @Override
2999    public void setFocusedStack(int stackId) {
3000        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3001        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3002        final long callingId = Binder.clearCallingIdentity();
3003        try {
3004            synchronized (this) {
3005                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3006                if (stack == null) {
3007                    return;
3008                }
3009                final ActivityRecord r = stack.topRunningActivityLocked();
3010                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3011                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3012                }
3013            }
3014        } finally {
3015            Binder.restoreCallingIdentity(callingId);
3016        }
3017    }
3018
3019    @Override
3020    public void setFocusedTask(int taskId) {
3021        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3022        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3023        final long callingId = Binder.clearCallingIdentity();
3024        try {
3025            synchronized (this) {
3026                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3027                if (task == null) {
3028                    return;
3029                }
3030                final ActivityRecord r = task.topRunningActivityLocked();
3031                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3032                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3033                }
3034            }
3035        } finally {
3036            Binder.restoreCallingIdentity(callingId);
3037        }
3038    }
3039
3040    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3041    @Override
3042    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3043        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3044        synchronized (this) {
3045            if (listener != null) {
3046                mTaskStackListeners.register(listener);
3047            }
3048        }
3049    }
3050
3051    @Override
3052    public void notifyActivityDrawn(IBinder token) {
3053        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3054        synchronized (this) {
3055            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3056            if (r != null) {
3057                r.task.stack.notifyActivityDrawnLocked(r);
3058            }
3059        }
3060    }
3061
3062    final void applyUpdateLockStateLocked(ActivityRecord r) {
3063        // Modifications to the UpdateLock state are done on our handler, outside
3064        // the activity manager's locks.  The new state is determined based on the
3065        // state *now* of the relevant activity record.  The object is passed to
3066        // the handler solely for logging detail, not to be consulted/modified.
3067        final boolean nextState = r != null && r.immersive;
3068        mHandler.sendMessage(
3069                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3070    }
3071
3072    final void applyUpdateVrModeLocked(ActivityRecord r) {
3073        mHandler.sendMessage(
3074                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3075    }
3076
3077    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3078        mHandler.sendMessage(
3079                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3080    }
3081
3082    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3083        Message msg = Message.obtain();
3084        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3085        msg.obj = r.task.askedCompatMode ? null : r;
3086        mUiHandler.sendMessage(msg);
3087    }
3088
3089    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3090            String what, Object obj, ProcessRecord srcApp) {
3091        app.lastActivityTime = now;
3092
3093        if (app.activities.size() > 0) {
3094            // Don't want to touch dependent processes that are hosting activities.
3095            return index;
3096        }
3097
3098        int lrui = mLruProcesses.lastIndexOf(app);
3099        if (lrui < 0) {
3100            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3101                    + what + " " + obj + " from " + srcApp);
3102            return index;
3103        }
3104
3105        if (lrui >= index) {
3106            // Don't want to cause this to move dependent processes *back* in the
3107            // list as if they were less frequently used.
3108            return index;
3109        }
3110
3111        if (lrui >= mLruProcessActivityStart) {
3112            // Don't want to touch dependent processes that are hosting activities.
3113            return index;
3114        }
3115
3116        mLruProcesses.remove(lrui);
3117        if (index > 0) {
3118            index--;
3119        }
3120        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3121                + " in LRU list: " + app);
3122        mLruProcesses.add(index, app);
3123        return index;
3124    }
3125
3126    static void killProcessGroup(int uid, int pid) {
3127        if (sKillHandler != null) {
3128            sKillHandler.sendMessage(
3129                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3130        } else {
3131            Slog.w(TAG, "Asked to kill process group before system bringup!");
3132            Process.killProcessGroup(uid, pid);
3133        }
3134    }
3135
3136    final void removeLruProcessLocked(ProcessRecord app) {
3137        int lrui = mLruProcesses.lastIndexOf(app);
3138        if (lrui >= 0) {
3139            if (!app.killed) {
3140                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3141                Process.killProcessQuiet(app.pid);
3142                killProcessGroup(app.uid, app.pid);
3143            }
3144            if (lrui <= mLruProcessActivityStart) {
3145                mLruProcessActivityStart--;
3146            }
3147            if (lrui <= mLruProcessServiceStart) {
3148                mLruProcessServiceStart--;
3149            }
3150            mLruProcesses.remove(lrui);
3151        }
3152    }
3153
3154    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3155            ProcessRecord client) {
3156        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3157                || app.treatLikeActivity;
3158        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3159        if (!activityChange && hasActivity) {
3160            // The process has activities, so we are only allowing activity-based adjustments
3161            // to move it.  It should be kept in the front of the list with other
3162            // processes that have activities, and we don't want those to change their
3163            // order except due to activity operations.
3164            return;
3165        }
3166
3167        mLruSeq++;
3168        final long now = SystemClock.uptimeMillis();
3169        app.lastActivityTime = now;
3170
3171        // First a quick reject: if the app is already at the position we will
3172        // put it, then there is nothing to do.
3173        if (hasActivity) {
3174            final int N = mLruProcesses.size();
3175            if (N > 0 && mLruProcesses.get(N-1) == app) {
3176                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3177                return;
3178            }
3179        } else {
3180            if (mLruProcessServiceStart > 0
3181                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3182                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3183                return;
3184            }
3185        }
3186
3187        int lrui = mLruProcesses.lastIndexOf(app);
3188
3189        if (app.persistent && lrui >= 0) {
3190            // We don't care about the position of persistent processes, as long as
3191            // they are in the list.
3192            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3193            return;
3194        }
3195
3196        /* In progress: compute new position first, so we can avoid doing work
3197           if the process is not actually going to move.  Not yet working.
3198        int addIndex;
3199        int nextIndex;
3200        boolean inActivity = false, inService = false;
3201        if (hasActivity) {
3202            // Process has activities, put it at the very tipsy-top.
3203            addIndex = mLruProcesses.size();
3204            nextIndex = mLruProcessServiceStart;
3205            inActivity = true;
3206        } else if (hasService) {
3207            // Process has services, put it at the top of the service list.
3208            addIndex = mLruProcessActivityStart;
3209            nextIndex = mLruProcessServiceStart;
3210            inActivity = true;
3211            inService = true;
3212        } else  {
3213            // Process not otherwise of interest, it goes to the top of the non-service area.
3214            addIndex = mLruProcessServiceStart;
3215            if (client != null) {
3216                int clientIndex = mLruProcesses.lastIndexOf(client);
3217                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3218                        + app);
3219                if (clientIndex >= 0 && addIndex > clientIndex) {
3220                    addIndex = clientIndex;
3221                }
3222            }
3223            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3224        }
3225
3226        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3227                + mLruProcessActivityStart + "): " + app);
3228        */
3229
3230        if (lrui >= 0) {
3231            if (lrui < mLruProcessActivityStart) {
3232                mLruProcessActivityStart--;
3233            }
3234            if (lrui < mLruProcessServiceStart) {
3235                mLruProcessServiceStart--;
3236            }
3237            /*
3238            if (addIndex > lrui) {
3239                addIndex--;
3240            }
3241            if (nextIndex > lrui) {
3242                nextIndex--;
3243            }
3244            */
3245            mLruProcesses.remove(lrui);
3246        }
3247
3248        /*
3249        mLruProcesses.add(addIndex, app);
3250        if (inActivity) {
3251            mLruProcessActivityStart++;
3252        }
3253        if (inService) {
3254            mLruProcessActivityStart++;
3255        }
3256        */
3257
3258        int nextIndex;
3259        if (hasActivity) {
3260            final int N = mLruProcesses.size();
3261            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3262                // Process doesn't have activities, but has clients with
3263                // activities...  move it up, but one below the top (the top
3264                // should always have a real activity).
3265                if (DEBUG_LRU) Slog.d(TAG_LRU,
3266                        "Adding to second-top of LRU activity list: " + app);
3267                mLruProcesses.add(N - 1, app);
3268                // To keep it from spamming the LRU list (by making a bunch of clients),
3269                // we will push down any other entries owned by the app.
3270                final int uid = app.info.uid;
3271                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3272                    ProcessRecord subProc = mLruProcesses.get(i);
3273                    if (subProc.info.uid == uid) {
3274                        // We want to push this one down the list.  If the process after
3275                        // it is for the same uid, however, don't do so, because we don't
3276                        // want them internally to be re-ordered.
3277                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3278                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3279                                    "Pushing uid " + uid + " swapping at " + i + ": "
3280                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3281                            ProcessRecord tmp = mLruProcesses.get(i);
3282                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3283                            mLruProcesses.set(i - 1, tmp);
3284                            i--;
3285                        }
3286                    } else {
3287                        // A gap, we can stop here.
3288                        break;
3289                    }
3290                }
3291            } else {
3292                // Process has activities, put it at the very tipsy-top.
3293                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3294                mLruProcesses.add(app);
3295            }
3296            nextIndex = mLruProcessServiceStart;
3297        } else if (hasService) {
3298            // Process has services, put it at the top of the service list.
3299            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3300            mLruProcesses.add(mLruProcessActivityStart, app);
3301            nextIndex = mLruProcessServiceStart;
3302            mLruProcessActivityStart++;
3303        } else  {
3304            // Process not otherwise of interest, it goes to the top of the non-service area.
3305            int index = mLruProcessServiceStart;
3306            if (client != null) {
3307                // If there is a client, don't allow the process to be moved up higher
3308                // in the list than that client.
3309                int clientIndex = mLruProcesses.lastIndexOf(client);
3310                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3311                        + " when updating " + app);
3312                if (clientIndex <= lrui) {
3313                    // Don't allow the client index restriction to push it down farther in the
3314                    // list than it already is.
3315                    clientIndex = lrui;
3316                }
3317                if (clientIndex >= 0 && index > clientIndex) {
3318                    index = clientIndex;
3319                }
3320            }
3321            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3322            mLruProcesses.add(index, app);
3323            nextIndex = index-1;
3324            mLruProcessActivityStart++;
3325            mLruProcessServiceStart++;
3326        }
3327
3328        // If the app is currently using a content provider or service,
3329        // bump those processes as well.
3330        for (int j=app.connections.size()-1; j>=0; j--) {
3331            ConnectionRecord cr = app.connections.valueAt(j);
3332            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3333                    && cr.binding.service.app != null
3334                    && cr.binding.service.app.lruSeq != mLruSeq
3335                    && !cr.binding.service.app.persistent) {
3336                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3337                        "service connection", cr, app);
3338            }
3339        }
3340        for (int j=app.conProviders.size()-1; j>=0; j--) {
3341            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3342            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3343                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3344                        "provider reference", cpr, app);
3345            }
3346        }
3347    }
3348
3349    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3350        if (uid == Process.SYSTEM_UID) {
3351            // The system gets to run in any process.  If there are multiple
3352            // processes with the same uid, just pick the first (this
3353            // should never happen).
3354            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3355            if (procs == null) return null;
3356            final int procCount = procs.size();
3357            for (int i = 0; i < procCount; i++) {
3358                final int procUid = procs.keyAt(i);
3359                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3360                    // Don't use an app process or different user process for system component.
3361                    continue;
3362                }
3363                return procs.valueAt(i);
3364            }
3365        }
3366        ProcessRecord proc = mProcessNames.get(processName, uid);
3367        if (false && proc != null && !keepIfLarge
3368                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3369                && proc.lastCachedPss >= 4000) {
3370            // Turn this condition on to cause killing to happen regularly, for testing.
3371            if (proc.baseProcessTracker != null) {
3372                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3373            }
3374            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3375        } else if (proc != null && !keepIfLarge
3376                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3377                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3378            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3379            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3380                if (proc.baseProcessTracker != null) {
3381                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3382                }
3383                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3384            }
3385        }
3386        return proc;
3387    }
3388
3389    void notifyPackageUse(String packageName, int reason) {
3390        IPackageManager pm = AppGlobals.getPackageManager();
3391        try {
3392            pm.notifyPackageUse(packageName, reason);
3393        } catch (RemoteException e) {
3394        }
3395    }
3396
3397    boolean isNextTransitionForward() {
3398        int transit = mWindowManager.getPendingAppTransition();
3399        return transit == TRANSIT_ACTIVITY_OPEN
3400                || transit == TRANSIT_TASK_OPEN
3401                || transit == TRANSIT_TASK_TO_FRONT;
3402    }
3403
3404    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3405            String processName, String abiOverride, int uid, Runnable crashHandler) {
3406        synchronized(this) {
3407            ApplicationInfo info = new ApplicationInfo();
3408            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3409            // For isolated processes, the former contains the parent's uid and the latter the
3410            // actual uid of the isolated process.
3411            // In the special case introduced by this method (which is, starting an isolated
3412            // process directly from the SystemServer without an actual parent app process) the
3413            // closest thing to a parent's uid is SYSTEM_UID.
3414            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3415            // the |isolated| logic in the ProcessRecord constructor.
3416            info.uid = Process.SYSTEM_UID;
3417            info.processName = processName;
3418            info.className = entryPoint;
3419            info.packageName = "android";
3420            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3421                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3422                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3423                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3424                    crashHandler);
3425            return proc != null ? proc.pid : 0;
3426        }
3427    }
3428
3429    final ProcessRecord startProcessLocked(String processName,
3430            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3431            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3432            boolean isolated, boolean keepIfLarge) {
3433        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3434                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3435                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3436                null /* crashHandler */);
3437    }
3438
3439    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3440            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3441            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3442            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3443        long startTime = SystemClock.elapsedRealtime();
3444        ProcessRecord app;
3445        if (!isolated) {
3446            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3447            checkTime(startTime, "startProcess: after getProcessRecord");
3448
3449            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3450                // If we are in the background, then check to see if this process
3451                // is bad.  If so, we will just silently fail.
3452                if (mAppErrors.isBadProcessLocked(info)) {
3453                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3454                            + "/" + info.processName);
3455                    return null;
3456                }
3457            } else {
3458                // When the user is explicitly starting a process, then clear its
3459                // crash count so that we won't make it bad until they see at
3460                // least one crash dialog again, and make the process good again
3461                // if it had been bad.
3462                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3463                        + "/" + info.processName);
3464                mAppErrors.resetProcessCrashTimeLocked(info);
3465                if (mAppErrors.isBadProcessLocked(info)) {
3466                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3467                            UserHandle.getUserId(info.uid), info.uid,
3468                            info.processName);
3469                    mAppErrors.clearBadProcessLocked(info);
3470                    if (app != null) {
3471                        app.bad = false;
3472                    }
3473                }
3474            }
3475        } else {
3476            // If this is an isolated process, it can't re-use an existing process.
3477            app = null;
3478        }
3479
3480        // app launch boost for big.little configurations
3481        // use cpusets to migrate freshly launched tasks to big cores
3482        synchronized(ActivityManagerService.this) {
3483            nativeMigrateToBoost();
3484            mIsBoosted = true;
3485            mBoostStartTime = SystemClock.uptimeMillis();
3486            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3487            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3488        }
3489
3490        // We don't have to do anything more if:
3491        // (1) There is an existing application record; and
3492        // (2) The caller doesn't think it is dead, OR there is no thread
3493        //     object attached to it so we know it couldn't have crashed; and
3494        // (3) There is a pid assigned to it, so it is either starting or
3495        //     already running.
3496        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3497                + " app=" + app + " knownToBeDead=" + knownToBeDead
3498                + " thread=" + (app != null ? app.thread : null)
3499                + " pid=" + (app != null ? app.pid : -1));
3500        if (app != null && app.pid > 0) {
3501            if (!knownToBeDead || app.thread == null) {
3502                // We already have the app running, or are waiting for it to
3503                // come up (we have a pid but not yet its thread), so keep it.
3504                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3505                // If this is a new package in the process, add the package to the list
3506                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3507                checkTime(startTime, "startProcess: done, added package to proc");
3508                return app;
3509            }
3510
3511            // An application record is attached to a previous process,
3512            // clean it up now.
3513            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3514            checkTime(startTime, "startProcess: bad proc running, killing");
3515            killProcessGroup(app.uid, app.pid);
3516            handleAppDiedLocked(app, true, true);
3517            checkTime(startTime, "startProcess: done killing old proc");
3518        }
3519
3520        String hostingNameStr = hostingName != null
3521                ? hostingName.flattenToShortString() : null;
3522
3523        if (app == null) {
3524            checkTime(startTime, "startProcess: creating new process record");
3525            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3526            if (app == null) {
3527                Slog.w(TAG, "Failed making new process record for "
3528                        + processName + "/" + info.uid + " isolated=" + isolated);
3529                return null;
3530            }
3531            app.crashHandler = crashHandler;
3532            checkTime(startTime, "startProcess: done creating new process record");
3533        } else {
3534            // If this is a new package in the process, add the package to the list
3535            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3536            checkTime(startTime, "startProcess: added package to existing proc");
3537        }
3538
3539        // If the system is not ready yet, then hold off on starting this
3540        // process until it is.
3541        if (!mProcessesReady
3542                && !isAllowedWhileBooting(info)
3543                && !allowWhileBooting) {
3544            if (!mProcessesOnHold.contains(app)) {
3545                mProcessesOnHold.add(app);
3546            }
3547            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3548                    "System not ready, putting on hold: " + app);
3549            checkTime(startTime, "startProcess: returning with proc on hold");
3550            return app;
3551        }
3552
3553        checkTime(startTime, "startProcess: stepping in to startProcess");
3554        startProcessLocked(
3555                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3556        checkTime(startTime, "startProcess: done starting proc!");
3557        return (app.pid != 0) ? app : null;
3558    }
3559
3560    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3561        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3562    }
3563
3564    private final void startProcessLocked(ProcessRecord app,
3565            String hostingType, String hostingNameStr) {
3566        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3567                null /* entryPoint */, null /* entryPointArgs */);
3568    }
3569
3570    private final void startProcessLocked(ProcessRecord app, String hostingType,
3571            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3572        long startTime = SystemClock.elapsedRealtime();
3573        if (app.pid > 0 && app.pid != MY_PID) {
3574            checkTime(startTime, "startProcess: removing from pids map");
3575            synchronized (mPidsSelfLocked) {
3576                mPidsSelfLocked.remove(app.pid);
3577                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3578            }
3579            checkTime(startTime, "startProcess: done removing from pids map");
3580            app.setPid(0);
3581        }
3582
3583        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3584                "startProcessLocked removing on hold: " + app);
3585        mProcessesOnHold.remove(app);
3586
3587        checkTime(startTime, "startProcess: starting to update cpu stats");
3588        updateCpuStats();
3589        checkTime(startTime, "startProcess: done updating cpu stats");
3590
3591        try {
3592            try {
3593                final int userId = UserHandle.getUserId(app.uid);
3594                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3595            } catch (RemoteException e) {
3596                throw e.rethrowAsRuntimeException();
3597            }
3598
3599            int uid = app.uid;
3600            int[] gids = null;
3601            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3602            if (!app.isolated) {
3603                int[] permGids = null;
3604                try {
3605                    checkTime(startTime, "startProcess: getting gids from package manager");
3606                    final IPackageManager pm = AppGlobals.getPackageManager();
3607                    permGids = pm.getPackageGids(app.info.packageName,
3608                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3609                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3610                            MountServiceInternal.class);
3611                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3612                            app.info.packageName);
3613                } catch (RemoteException e) {
3614                    throw e.rethrowAsRuntimeException();
3615                }
3616
3617                /*
3618                 * Add shared application and profile GIDs so applications can share some
3619                 * resources like shared libraries and access user-wide resources
3620                 */
3621                if (ArrayUtils.isEmpty(permGids)) {
3622                    gids = new int[2];
3623                } else {
3624                    gids = new int[permGids.length + 2];
3625                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3626                }
3627                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3628                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3629            }
3630            checkTime(startTime, "startProcess: building args");
3631            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3632                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3633                        && mTopComponent != null
3634                        && app.processName.equals(mTopComponent.getPackageName())) {
3635                    uid = 0;
3636                }
3637                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3638                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3639                    uid = 0;
3640                }
3641            }
3642            int debugFlags = 0;
3643            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3644                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3645                // Also turn on CheckJNI for debuggable apps. It's quite
3646                // awkward to turn on otherwise.
3647                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3648            }
3649            // Run the app in safe mode if its manifest requests so or the
3650            // system is booted in safe mode.
3651            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3652                mSafeMode == true) {
3653                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3654            }
3655            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3656                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3657            }
3658            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3659            if ("true".equals(genDebugInfoProperty)) {
3660                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3661            }
3662            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3663                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3664            }
3665            if ("1".equals(SystemProperties.get("debug.assert"))) {
3666                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3667            }
3668            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3669                // Enable all debug flags required by the native debugger.
3670                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3671                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3672                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3673                mNativeDebuggingApp = null;
3674            }
3675
3676            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3677            if (requiredAbi == null) {
3678                requiredAbi = Build.SUPPORTED_ABIS[0];
3679            }
3680
3681            String instructionSet = null;
3682            if (app.info.primaryCpuAbi != null) {
3683                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3684            }
3685
3686            app.gids = gids;
3687            app.requiredAbi = requiredAbi;
3688            app.instructionSet = instructionSet;
3689
3690            // Start the process.  It will either succeed and return a result containing
3691            // the PID of the new process, or else throw a RuntimeException.
3692            boolean isActivityProcess = (entryPoint == null);
3693            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3694            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3695                    app.processName);
3696            checkTime(startTime, "startProcess: asking zygote to start proc");
3697            Process.ProcessStartResult startResult = Process.start(entryPoint,
3698                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3699                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3700                    app.info.dataDir, entryPointArgs);
3701            checkTime(startTime, "startProcess: returned from zygote!");
3702            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3703
3704            if (app.isolated) {
3705                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3706            }
3707            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3708            checkTime(startTime, "startProcess: done updating battery stats");
3709
3710            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3711                    UserHandle.getUserId(uid), startResult.pid, uid,
3712                    app.processName, hostingType,
3713                    hostingNameStr != null ? hostingNameStr : "");
3714
3715            try {
3716                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3717                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3718            } catch (RemoteException ex) {
3719                // Ignore
3720            }
3721
3722            if (app.persistent) {
3723                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3724            }
3725
3726            checkTime(startTime, "startProcess: building log message");
3727            StringBuilder buf = mStringBuilder;
3728            buf.setLength(0);
3729            buf.append("Start proc ");
3730            buf.append(startResult.pid);
3731            buf.append(':');
3732            buf.append(app.processName);
3733            buf.append('/');
3734            UserHandle.formatUid(buf, uid);
3735            if (!isActivityProcess) {
3736                buf.append(" [");
3737                buf.append(entryPoint);
3738                buf.append("]");
3739            }
3740            buf.append(" for ");
3741            buf.append(hostingType);
3742            if (hostingNameStr != null) {
3743                buf.append(" ");
3744                buf.append(hostingNameStr);
3745            }
3746            Slog.i(TAG, buf.toString());
3747            app.setPid(startResult.pid);
3748            app.usingWrapper = startResult.usingWrapper;
3749            app.removed = false;
3750            app.killed = false;
3751            app.killedByAm = false;
3752            checkTime(startTime, "startProcess: starting to update pids map");
3753            synchronized (mPidsSelfLocked) {
3754                this.mPidsSelfLocked.put(startResult.pid, app);
3755                if (isActivityProcess) {
3756                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3757                    msg.obj = app;
3758                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3759                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3760                }
3761            }
3762            checkTime(startTime, "startProcess: done updating pids map");
3763        } catch (RuntimeException e) {
3764            Slog.e(TAG, "Failure starting process " + app.processName, e);
3765
3766            // Something went very wrong while trying to start this process; one
3767            // common case is when the package is frozen due to an active
3768            // upgrade. To recover, clean up any active bookkeeping related to
3769            // starting this process. (We already invoked this method once when
3770            // the package was initially frozen through KILL_APPLICATION_MSG, so
3771            // it doesn't hurt to use it again.)
3772            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3773                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3774        }
3775    }
3776
3777    void updateUsageStats(ActivityRecord component, boolean resumed) {
3778        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3779                "updateUsageStats: comp=" + component + "res=" + resumed);
3780        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3781        if (resumed) {
3782            if (mUsageStatsService != null) {
3783                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3784                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3785            }
3786            synchronized (stats) {
3787                stats.noteActivityResumedLocked(component.app.uid);
3788            }
3789        } else {
3790            if (mUsageStatsService != null) {
3791                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3792                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3793            }
3794            synchronized (stats) {
3795                stats.noteActivityPausedLocked(component.app.uid);
3796            }
3797        }
3798    }
3799
3800    Intent getHomeIntent() {
3801        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3802        intent.setComponent(mTopComponent);
3803        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3804        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3805            intent.addCategory(Intent.CATEGORY_HOME);
3806        }
3807        return intent;
3808    }
3809
3810    boolean startHomeActivityLocked(int userId, String reason) {
3811        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3812                && mTopAction == null) {
3813            // We are running in factory test mode, but unable to find
3814            // the factory test app, so just sit around displaying the
3815            // error message and don't try to start anything.
3816            return false;
3817        }
3818        Intent intent = getHomeIntent();
3819        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3820        if (aInfo != null) {
3821            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3822            // Don't do this if the home app is currently being
3823            // instrumented.
3824            aInfo = new ActivityInfo(aInfo);
3825            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3826            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3827                    aInfo.applicationInfo.uid, true);
3828            if (app == null || app.instrumentationClass == null) {
3829                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3830                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3831            }
3832        } else {
3833            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3834        }
3835
3836        return true;
3837    }
3838
3839    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3840        ActivityInfo ai = null;
3841        ComponentName comp = intent.getComponent();
3842        try {
3843            if (comp != null) {
3844                // Factory test.
3845                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3846            } else {
3847                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3848                        intent,
3849                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3850                        flags, userId);
3851
3852                if (info != null) {
3853                    ai = info.activityInfo;
3854                }
3855            }
3856        } catch (RemoteException e) {
3857            // ignore
3858        }
3859
3860        return ai;
3861    }
3862
3863    /**
3864     * Starts the "new version setup screen" if appropriate.
3865     */
3866    void startSetupActivityLocked() {
3867        // Only do this once per boot.
3868        if (mCheckedForSetup) {
3869            return;
3870        }
3871
3872        // We will show this screen if the current one is a different
3873        // version than the last one shown, and we are not running in
3874        // low-level factory test mode.
3875        final ContentResolver resolver = mContext.getContentResolver();
3876        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3877                Settings.Global.getInt(resolver,
3878                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3879            mCheckedForSetup = true;
3880
3881            // See if we should be showing the platform update setup UI.
3882            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3883            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3884                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3885            if (!ris.isEmpty()) {
3886                final ResolveInfo ri = ris.get(0);
3887                String vers = ri.activityInfo.metaData != null
3888                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3889                        : null;
3890                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3891                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3892                            Intent.METADATA_SETUP_VERSION);
3893                }
3894                String lastVers = Settings.Secure.getString(
3895                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3896                if (vers != null && !vers.equals(lastVers)) {
3897                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3898                    intent.setComponent(new ComponentName(
3899                            ri.activityInfo.packageName, ri.activityInfo.name));
3900                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3901                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3902                            null, 0, 0, 0, null, false, false, null, null, null);
3903                }
3904            }
3905        }
3906    }
3907
3908    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3909        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3910    }
3911
3912    void enforceNotIsolatedCaller(String caller) {
3913        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3914            throw new SecurityException("Isolated process not allowed to call " + caller);
3915        }
3916    }
3917
3918    void enforceShellRestriction(String restriction, int userHandle) {
3919        if (Binder.getCallingUid() == Process.SHELL_UID) {
3920            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3921                throw new SecurityException("Shell does not have permission to access user "
3922                        + userHandle);
3923            }
3924        }
3925    }
3926
3927    @Override
3928    public int getFrontActivityScreenCompatMode() {
3929        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3930        synchronized (this) {
3931            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3932        }
3933    }
3934
3935    @Override
3936    public void setFrontActivityScreenCompatMode(int mode) {
3937        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3938                "setFrontActivityScreenCompatMode");
3939        synchronized (this) {
3940            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3941        }
3942    }
3943
3944    @Override
3945    public int getPackageScreenCompatMode(String packageName) {
3946        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3947        synchronized (this) {
3948            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3949        }
3950    }
3951
3952    @Override
3953    public void setPackageScreenCompatMode(String packageName, int mode) {
3954        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3955                "setPackageScreenCompatMode");
3956        synchronized (this) {
3957            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3958        }
3959    }
3960
3961    @Override
3962    public boolean getPackageAskScreenCompat(String packageName) {
3963        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3964        synchronized (this) {
3965            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3966        }
3967    }
3968
3969    @Override
3970    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3972                "setPackageAskScreenCompat");
3973        synchronized (this) {
3974            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3975        }
3976    }
3977
3978    private boolean hasUsageStatsPermission(String callingPackage) {
3979        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3980                Binder.getCallingUid(), callingPackage);
3981        if (mode == AppOpsManager.MODE_DEFAULT) {
3982            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3983                    == PackageManager.PERMISSION_GRANTED;
3984        }
3985        return mode == AppOpsManager.MODE_ALLOWED;
3986    }
3987
3988    @Override
3989    public int getPackageProcessState(String packageName, String callingPackage) {
3990        if (!hasUsageStatsPermission(callingPackage)) {
3991            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3992                    "getPackageProcessState");
3993        }
3994
3995        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3996        synchronized (this) {
3997            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3998                final ProcessRecord proc = mLruProcesses.get(i);
3999                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4000                        || procState > proc.setProcState) {
4001                    boolean found = false;
4002                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4003                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4004                            procState = proc.setProcState;
4005                            found = true;
4006                        }
4007                    }
4008                    if (proc.pkgDeps != null && !found) {
4009                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4010                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4011                                procState = proc.setProcState;
4012                                break;
4013                            }
4014                        }
4015                    }
4016                }
4017            }
4018        }
4019        return procState;
4020    }
4021
4022    @Override
4023    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4024        synchronized (this) {
4025            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4026            if (app == null) {
4027                return false;
4028            }
4029            if (app.trimMemoryLevel < level && app.thread != null &&
4030                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4031                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4032                try {
4033                    app.thread.scheduleTrimMemory(level);
4034                    app.trimMemoryLevel = level;
4035                    return true;
4036                } catch (RemoteException e) {
4037                    // Fallthrough to failure case.
4038                }
4039            }
4040        }
4041        return false;
4042    }
4043
4044    private void dispatchProcessesChanged() {
4045        int N;
4046        synchronized (this) {
4047            N = mPendingProcessChanges.size();
4048            if (mActiveProcessChanges.length < N) {
4049                mActiveProcessChanges = new ProcessChangeItem[N];
4050            }
4051            mPendingProcessChanges.toArray(mActiveProcessChanges);
4052            mPendingProcessChanges.clear();
4053            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4054                    "*** Delivering " + N + " process changes");
4055        }
4056
4057        int i = mProcessObservers.beginBroadcast();
4058        while (i > 0) {
4059            i--;
4060            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4061            if (observer != null) {
4062                try {
4063                    for (int j=0; j<N; j++) {
4064                        ProcessChangeItem item = mActiveProcessChanges[j];
4065                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4066                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4067                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4068                                    + item.uid + ": " + item.foregroundActivities);
4069                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4070                                    item.foregroundActivities);
4071                        }
4072                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4073                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4074                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4075                                    + ": " + item.processState);
4076                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4077                        }
4078                    }
4079                } catch (RemoteException e) {
4080                }
4081            }
4082        }
4083        mProcessObservers.finishBroadcast();
4084
4085        synchronized (this) {
4086            for (int j=0; j<N; j++) {
4087                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4088            }
4089        }
4090    }
4091
4092    private void dispatchProcessDied(int pid, int uid) {
4093        int i = mProcessObservers.beginBroadcast();
4094        while (i > 0) {
4095            i--;
4096            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4097            if (observer != null) {
4098                try {
4099                    observer.onProcessDied(pid, uid);
4100                } catch (RemoteException e) {
4101                }
4102            }
4103        }
4104        mProcessObservers.finishBroadcast();
4105    }
4106
4107    private void dispatchUidsChanged() {
4108        int N;
4109        synchronized (this) {
4110            N = mPendingUidChanges.size();
4111            if (mActiveUidChanges.length < N) {
4112                mActiveUidChanges = new UidRecord.ChangeItem[N];
4113            }
4114            for (int i=0; i<N; i++) {
4115                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4116                mActiveUidChanges[i] = change;
4117                if (change.uidRecord != null) {
4118                    change.uidRecord.pendingChange = null;
4119                    change.uidRecord = null;
4120                }
4121            }
4122            mPendingUidChanges.clear();
4123            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4124                    "*** Delivering " + N + " uid changes");
4125        }
4126
4127        if (mLocalPowerManager != null) {
4128            for (int j=0; j<N; j++) {
4129                UidRecord.ChangeItem item = mActiveUidChanges[j];
4130                if (item.change == UidRecord.CHANGE_GONE
4131                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4132                    mLocalPowerManager.uidGone(item.uid);
4133                } else {
4134                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4135                }
4136            }
4137        }
4138
4139        int i = mUidObservers.beginBroadcast();
4140        while (i > 0) {
4141            i--;
4142            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4143            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4144            if (observer != null) {
4145                try {
4146                    for (int j=0; j<N; j++) {
4147                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4148                        final int change = item.change;
4149                        UidRecord validateUid = null;
4150                        if (VALIDATE_UID_STATES && i == 0) {
4151                            validateUid = mValidateUids.get(item.uid);
4152                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4153                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4154                                validateUid = new UidRecord(item.uid);
4155                                mValidateUids.put(item.uid, validateUid);
4156                            }
4157                        }
4158                        if (change == UidRecord.CHANGE_IDLE
4159                                || change == UidRecord.CHANGE_GONE_IDLE) {
4160                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4161                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4162                                        "UID idle uid=" + item.uid);
4163                                observer.onUidIdle(item.uid);
4164                            }
4165                            if (VALIDATE_UID_STATES && i == 0) {
4166                                if (validateUid != null) {
4167                                    validateUid.idle = true;
4168                                }
4169                            }
4170                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4171                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4172                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4173                                        "UID active uid=" + item.uid);
4174                                observer.onUidActive(item.uid);
4175                            }
4176                            if (VALIDATE_UID_STATES && i == 0) {
4177                                validateUid.idle = false;
4178                            }
4179                        }
4180                        if (change == UidRecord.CHANGE_GONE
4181                                || change == UidRecord.CHANGE_GONE_IDLE) {
4182                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4183                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4184                                        "UID gone uid=" + item.uid);
4185                                observer.onUidGone(item.uid);
4186                            }
4187                            if (VALIDATE_UID_STATES && i == 0) {
4188                                if (validateUid != null) {
4189                                    mValidateUids.remove(item.uid);
4190                                }
4191                            }
4192                        } else {
4193                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4194                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4195                                        "UID CHANGED uid=" + item.uid
4196                                                + ": " + item.processState);
4197                                observer.onUidStateChanged(item.uid, item.processState);
4198                            }
4199                            if (VALIDATE_UID_STATES && i == 0) {
4200                                validateUid.curProcState = validateUid.setProcState
4201                                        = item.processState;
4202                            }
4203                        }
4204                    }
4205                } catch (RemoteException e) {
4206                }
4207            }
4208        }
4209        mUidObservers.finishBroadcast();
4210
4211        synchronized (this) {
4212            for (int j=0; j<N; j++) {
4213                mAvailUidChanges.add(mActiveUidChanges[j]);
4214            }
4215        }
4216    }
4217
4218    @Override
4219    public final int startActivity(IApplicationThread caller, String callingPackage,
4220            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4221            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4222        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4223                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4224                UserHandle.getCallingUserId());
4225    }
4226
4227    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4228        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4229        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4230                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4231                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4232
4233        // TODO: Switch to user app stacks here.
4234        String mimeType = intent.getType();
4235        final Uri data = intent.getData();
4236        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4237            mimeType = getProviderMimeType(data, userId);
4238        }
4239        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4240
4241        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4242        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4243                null, 0, 0, null, null, null, null, false, userId, container, null);
4244    }
4245
4246    @Override
4247    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4248            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4249            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4250        enforceNotIsolatedCaller("startActivity");
4251        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4252                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4253        // TODO: Switch to user app stacks here.
4254        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4255                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4256                profilerInfo, null, null, bOptions, false, userId, null, null);
4257    }
4258
4259    @Override
4260    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4261            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4262            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4263            int userId) {
4264
4265        // This is very dangerous -- it allows you to perform a start activity (including
4266        // permission grants) as any app that may launch one of your own activities.  So
4267        // we will only allow this to be done from activities that are part of the core framework,
4268        // and then only when they are running as the system.
4269        final ActivityRecord sourceRecord;
4270        final int targetUid;
4271        final String targetPackage;
4272        synchronized (this) {
4273            if (resultTo == null) {
4274                throw new SecurityException("Must be called from an activity");
4275            }
4276            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4277            if (sourceRecord == null) {
4278                throw new SecurityException("Called with bad activity token: " + resultTo);
4279            }
4280            if (!sourceRecord.info.packageName.equals("android")) {
4281                throw new SecurityException(
4282                        "Must be called from an activity that is declared in the android package");
4283            }
4284            if (sourceRecord.app == null) {
4285                throw new SecurityException("Called without a process attached to activity");
4286            }
4287            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4288                // This is still okay, as long as this activity is running under the
4289                // uid of the original calling activity.
4290                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4291                    throw new SecurityException(
4292                            "Calling activity in uid " + sourceRecord.app.uid
4293                                    + " must be system uid or original calling uid "
4294                                    + sourceRecord.launchedFromUid);
4295                }
4296            }
4297            if (ignoreTargetSecurity) {
4298                if (intent.getComponent() == null) {
4299                    throw new SecurityException(
4300                            "Component must be specified with ignoreTargetSecurity");
4301                }
4302                if (intent.getSelector() != null) {
4303                    throw new SecurityException(
4304                            "Selector not allowed with ignoreTargetSecurity");
4305                }
4306            }
4307            targetUid = sourceRecord.launchedFromUid;
4308            targetPackage = sourceRecord.launchedFromPackage;
4309        }
4310
4311        if (userId == UserHandle.USER_NULL) {
4312            userId = UserHandle.getUserId(sourceRecord.app.uid);
4313        }
4314
4315        // TODO: Switch to user app stacks here.
4316        try {
4317            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4318                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4319                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4320            return ret;
4321        } catch (SecurityException e) {
4322            // XXX need to figure out how to propagate to original app.
4323            // A SecurityException here is generally actually a fault of the original
4324            // calling activity (such as a fairly granting permissions), so propagate it
4325            // back to them.
4326            /*
4327            StringBuilder msg = new StringBuilder();
4328            msg.append("While launching");
4329            msg.append(intent.toString());
4330            msg.append(": ");
4331            msg.append(e.getMessage());
4332            */
4333            throw e;
4334        }
4335    }
4336
4337    @Override
4338    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4339            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4340            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4341        enforceNotIsolatedCaller("startActivityAndWait");
4342        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4343                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4344        WaitResult res = new WaitResult();
4345        // TODO: Switch to user app stacks here.
4346        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4347                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4348                bOptions, false, userId, null, null);
4349        return res;
4350    }
4351
4352    @Override
4353    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4354            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4355            int startFlags, Configuration config, Bundle bOptions, int userId) {
4356        enforceNotIsolatedCaller("startActivityWithConfig");
4357        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4358                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4359        // TODO: Switch to user app stacks here.
4360        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4361                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4362                null, null, config, bOptions, false, userId, null, null);
4363        return ret;
4364    }
4365
4366    @Override
4367    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4368            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4369            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4370            throws TransactionTooLargeException {
4371        enforceNotIsolatedCaller("startActivityIntentSender");
4372        // Refuse possible leaked file descriptors
4373        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4374            throw new IllegalArgumentException("File descriptors passed in Intent");
4375        }
4376
4377        IIntentSender sender = intent.getTarget();
4378        if (!(sender instanceof PendingIntentRecord)) {
4379            throw new IllegalArgumentException("Bad PendingIntent object");
4380        }
4381
4382        PendingIntentRecord pir = (PendingIntentRecord)sender;
4383
4384        synchronized (this) {
4385            // If this is coming from the currently resumed activity, it is
4386            // effectively saying that app switches are allowed at this point.
4387            final ActivityStack stack = getFocusedStack();
4388            if (stack.mResumedActivity != null &&
4389                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4390                mAppSwitchesAllowedTime = 0;
4391            }
4392        }
4393        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4394                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4395        return ret;
4396    }
4397
4398    @Override
4399    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4400            Intent intent, String resolvedType, IVoiceInteractionSession session,
4401            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4402            Bundle bOptions, int userId) {
4403        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4404                != PackageManager.PERMISSION_GRANTED) {
4405            String msg = "Permission Denial: startVoiceActivity() from pid="
4406                    + Binder.getCallingPid()
4407                    + ", uid=" + Binder.getCallingUid()
4408                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4409            Slog.w(TAG, msg);
4410            throw new SecurityException(msg);
4411        }
4412        if (session == null || interactor == null) {
4413            throw new NullPointerException("null session or interactor");
4414        }
4415        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4416                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4417        // TODO: Switch to user app stacks here.
4418        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4419                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4420                null, bOptions, false, userId, null, null);
4421    }
4422
4423    @Override
4424    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4425            throws RemoteException {
4426        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4427        synchronized (this) {
4428            ActivityRecord activity = getFocusedStack().topActivity();
4429            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4430                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4431            }
4432            if (mRunningVoice != null || activity.task.voiceSession != null
4433                    || activity.voiceSession != null) {
4434                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4435                return;
4436            }
4437            if (activity.pendingVoiceInteractionStart) {
4438                Slog.w(TAG, "Pending start of voice interaction already.");
4439                return;
4440            }
4441            activity.pendingVoiceInteractionStart = true;
4442        }
4443        LocalServices.getService(VoiceInteractionManagerInternal.class)
4444                .startLocalVoiceInteraction(callingActivity, options);
4445    }
4446
4447    @Override
4448    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4449        LocalServices.getService(VoiceInteractionManagerInternal.class)
4450                .stopLocalVoiceInteraction(callingActivity);
4451    }
4452
4453    @Override
4454    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4455        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4456                .supportsLocalVoiceInteraction();
4457    }
4458
4459    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4460            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4461        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4462        if (activityToCallback == null) return;
4463        activityToCallback.setVoiceSessionLocked(voiceSession);
4464
4465        // Inform the activity
4466        try {
4467            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4468                    voiceInteractor);
4469            long token = Binder.clearCallingIdentity();
4470            try {
4471                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4472            } finally {
4473                Binder.restoreCallingIdentity(token);
4474            }
4475            // TODO: VI Should we cache the activity so that it's easier to find later
4476            // rather than scan through all the stacks and activities?
4477        } catch (RemoteException re) {
4478            activityToCallback.clearVoiceSessionLocked();
4479            // TODO: VI Should this terminate the voice session?
4480        }
4481    }
4482
4483    @Override
4484    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4485        synchronized (this) {
4486            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4487                if (keepAwake) {
4488                    mVoiceWakeLock.acquire();
4489                } else {
4490                    mVoiceWakeLock.release();
4491                }
4492            }
4493        }
4494    }
4495
4496    @Override
4497    public boolean startNextMatchingActivity(IBinder callingActivity,
4498            Intent intent, Bundle bOptions) {
4499        // Refuse possible leaked file descriptors
4500        if (intent != null && intent.hasFileDescriptors() == true) {
4501            throw new IllegalArgumentException("File descriptors passed in Intent");
4502        }
4503        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4504
4505        synchronized (this) {
4506            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4507            if (r == null) {
4508                ActivityOptions.abort(options);
4509                return false;
4510            }
4511            if (r.app == null || r.app.thread == null) {
4512                // The caller is not running...  d'oh!
4513                ActivityOptions.abort(options);
4514                return false;
4515            }
4516            intent = new Intent(intent);
4517            // The caller is not allowed to change the data.
4518            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4519            // And we are resetting to find the next component...
4520            intent.setComponent(null);
4521
4522            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4523
4524            ActivityInfo aInfo = null;
4525            try {
4526                List<ResolveInfo> resolves =
4527                    AppGlobals.getPackageManager().queryIntentActivities(
4528                            intent, r.resolvedType,
4529                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4530                            UserHandle.getCallingUserId()).getList();
4531
4532                // Look for the original activity in the list...
4533                final int N = resolves != null ? resolves.size() : 0;
4534                for (int i=0; i<N; i++) {
4535                    ResolveInfo rInfo = resolves.get(i);
4536                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4537                            && rInfo.activityInfo.name.equals(r.info.name)) {
4538                        // We found the current one...  the next matching is
4539                        // after it.
4540                        i++;
4541                        if (i<N) {
4542                            aInfo = resolves.get(i).activityInfo;
4543                        }
4544                        if (debug) {
4545                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4546                                    + "/" + r.info.name);
4547                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4548                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4549                        }
4550                        break;
4551                    }
4552                }
4553            } catch (RemoteException e) {
4554            }
4555
4556            if (aInfo == null) {
4557                // Nobody who is next!
4558                ActivityOptions.abort(options);
4559                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4560                return false;
4561            }
4562
4563            intent.setComponent(new ComponentName(
4564                    aInfo.applicationInfo.packageName, aInfo.name));
4565            intent.setFlags(intent.getFlags()&~(
4566                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4567                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4568                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4569                    Intent.FLAG_ACTIVITY_NEW_TASK));
4570
4571            // Okay now we need to start the new activity, replacing the
4572            // currently running activity.  This is a little tricky because
4573            // we want to start the new one as if the current one is finished,
4574            // but not finish the current one first so that there is no flicker.
4575            // And thus...
4576            final boolean wasFinishing = r.finishing;
4577            r.finishing = true;
4578
4579            // Propagate reply information over to the new activity.
4580            final ActivityRecord resultTo = r.resultTo;
4581            final String resultWho = r.resultWho;
4582            final int requestCode = r.requestCode;
4583            r.resultTo = null;
4584            if (resultTo != null) {
4585                resultTo.removeResultsLocked(r, resultWho, requestCode);
4586            }
4587
4588            final long origId = Binder.clearCallingIdentity();
4589            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4590                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4591                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4592                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4593                    false, false, null, null, null);
4594            Binder.restoreCallingIdentity(origId);
4595
4596            r.finishing = wasFinishing;
4597            if (res != ActivityManager.START_SUCCESS) {
4598                return false;
4599            }
4600            return true;
4601        }
4602    }
4603
4604    @Override
4605    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4606        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4607            String msg = "Permission Denial: startActivityFromRecents called without " +
4608                    START_TASKS_FROM_RECENTS;
4609            Slog.w(TAG, msg);
4610            throw new SecurityException(msg);
4611        }
4612        final long origId = Binder.clearCallingIdentity();
4613        try {
4614            synchronized (this) {
4615                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4616            }
4617        } finally {
4618            Binder.restoreCallingIdentity(origId);
4619        }
4620    }
4621
4622    final int startActivityInPackage(int uid, String callingPackage,
4623            Intent intent, String resolvedType, IBinder resultTo,
4624            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4625            IActivityContainer container, TaskRecord inTask) {
4626
4627        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4628                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4629
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4632                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4633                null, null, null, bOptions, false, userId, container, inTask);
4634        return ret;
4635    }
4636
4637    @Override
4638    public final int startActivities(IApplicationThread caller, String callingPackage,
4639            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4640            int userId) {
4641        enforceNotIsolatedCaller("startActivities");
4642        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4643                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4644        // TODO: Switch to user app stacks here.
4645        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4646                resolvedTypes, resultTo, bOptions, userId);
4647        return ret;
4648    }
4649
4650    final int startActivitiesInPackage(int uid, String callingPackage,
4651            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4652            Bundle bOptions, int userId) {
4653
4654        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4655                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4656        // TODO: Switch to user app stacks here.
4657        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4658                resultTo, bOptions, userId);
4659        return ret;
4660    }
4661
4662    @Override
4663    public void reportActivityFullyDrawn(IBinder token) {
4664        synchronized (this) {
4665            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4666            if (r == null) {
4667                return;
4668            }
4669            r.reportFullyDrawnLocked();
4670        }
4671    }
4672
4673    @Override
4674    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4675        synchronized (this) {
4676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4677            if (r == null) {
4678                return;
4679            }
4680            TaskRecord task = r.task;
4681            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4682                // Fixed screen orientation isn't supported when activities aren't in full screen
4683                // mode.
4684                return;
4685            }
4686            final long origId = Binder.clearCallingIdentity();
4687            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4688            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4689                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4690            if (config != null) {
4691                r.frozenBeforeDestroy = true;
4692                if (!updateConfigurationLocked(config, r, false)) {
4693                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4694                }
4695            }
4696            Binder.restoreCallingIdentity(origId);
4697        }
4698    }
4699
4700    @Override
4701    public int getRequestedOrientation(IBinder token) {
4702        synchronized (this) {
4703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4704            if (r == null) {
4705                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4706            }
4707            return mWindowManager.getAppOrientation(r.appToken);
4708        }
4709    }
4710
4711    /**
4712     * This is the internal entry point for handling Activity.finish().
4713     *
4714     * @param token The Binder token referencing the Activity we want to finish.
4715     * @param resultCode Result code, if any, from this Activity.
4716     * @param resultData Result data (Intent), if any, from this Activity.
4717     * @param finishTask Whether to finish the task associated with this Activity.
4718     *
4719     * @return Returns true if the activity successfully finished, or false if it is still running.
4720     */
4721    @Override
4722    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4723            int finishTask) {
4724        // Refuse possible leaked file descriptors
4725        if (resultData != null && resultData.hasFileDescriptors() == true) {
4726            throw new IllegalArgumentException("File descriptors passed in Intent");
4727        }
4728
4729        synchronized(this) {
4730            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4731            if (r == null) {
4732                return true;
4733            }
4734            // Keep track of the root activity of the task before we finish it
4735            TaskRecord tr = r.task;
4736            ActivityRecord rootR = tr.getRootActivity();
4737            if (rootR == null) {
4738                Slog.w(TAG, "Finishing task with all activities already finished");
4739            }
4740            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4741            // finish.
4742            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4743                    mStackSupervisor.isLastLockedTask(tr)) {
4744                Slog.i(TAG, "Not finishing task in lock task mode");
4745                mStackSupervisor.showLockTaskToast();
4746                return false;
4747            }
4748            if (mController != null) {
4749                // Find the first activity that is not finishing.
4750                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4751                if (next != null) {
4752                    // ask watcher if this is allowed
4753                    boolean resumeOK = true;
4754                    try {
4755                        resumeOK = mController.activityResuming(next.packageName);
4756                    } catch (RemoteException e) {
4757                        mController = null;
4758                        Watchdog.getInstance().setActivityController(null);
4759                    }
4760
4761                    if (!resumeOK) {
4762                        Slog.i(TAG, "Not finishing activity because controller resumed");
4763                        return false;
4764                    }
4765                }
4766            }
4767            final long origId = Binder.clearCallingIdentity();
4768            try {
4769                boolean res;
4770                final boolean finishWithRootActivity =
4771                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4772                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4773                        || (finishWithRootActivity && r == rootR)) {
4774                    // If requested, remove the task that is associated to this activity only if it
4775                    // was the root activity in the task. The result code and data is ignored
4776                    // because we don't support returning them across task boundaries. Also, to
4777                    // keep backwards compatibility we remove the task from recents when finishing
4778                    // task with root activity.
4779                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4780                    if (!res) {
4781                        Slog.i(TAG, "Removing task failed to finish activity");
4782                    }
4783                } else {
4784                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4785                            resultData, "app-request", true);
4786                    if (!res) {
4787                        Slog.i(TAG, "Failed to finish by app-request");
4788                    }
4789                }
4790                return res;
4791            } finally {
4792                Binder.restoreCallingIdentity(origId);
4793            }
4794        }
4795    }
4796
4797    @Override
4798    public final void finishHeavyWeightApp() {
4799        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4800                != PackageManager.PERMISSION_GRANTED) {
4801            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4802                    + Binder.getCallingPid()
4803                    + ", uid=" + Binder.getCallingUid()
4804                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4805            Slog.w(TAG, msg);
4806            throw new SecurityException(msg);
4807        }
4808
4809        synchronized(this) {
4810            if (mHeavyWeightProcess == null) {
4811                return;
4812            }
4813
4814            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4815            for (int i = 0; i < activities.size(); i++) {
4816                ActivityRecord r = activities.get(i);
4817                if (!r.finishing && r.isInStackLocked()) {
4818                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4819                            null, "finish-heavy", true);
4820                }
4821            }
4822
4823            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4824                    mHeavyWeightProcess.userId, 0));
4825            mHeavyWeightProcess = null;
4826        }
4827    }
4828
4829    @Override
4830    public void crashApplication(int uid, int initialPid, String packageName,
4831            String message) {
4832        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4833                != PackageManager.PERMISSION_GRANTED) {
4834            String msg = "Permission Denial: crashApplication() from pid="
4835                    + Binder.getCallingPid()
4836                    + ", uid=" + Binder.getCallingUid()
4837                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4838            Slog.w(TAG, msg);
4839            throw new SecurityException(msg);
4840        }
4841
4842        synchronized(this) {
4843            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4844        }
4845    }
4846
4847    @Override
4848    public final void finishSubActivity(IBinder token, String resultWho,
4849            int requestCode) {
4850        synchronized(this) {
4851            final long origId = Binder.clearCallingIdentity();
4852            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4853            if (r != null) {
4854                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4855            }
4856            Binder.restoreCallingIdentity(origId);
4857        }
4858    }
4859
4860    @Override
4861    public boolean finishActivityAffinity(IBinder token) {
4862        synchronized(this) {
4863            final long origId = Binder.clearCallingIdentity();
4864            try {
4865                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866                if (r == null) {
4867                    return false;
4868                }
4869
4870                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4871                // can finish.
4872                final TaskRecord task = r.task;
4873                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4874                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4875                    mStackSupervisor.showLockTaskToast();
4876                    return false;
4877                }
4878                return task.stack.finishActivityAffinityLocked(r);
4879            } finally {
4880                Binder.restoreCallingIdentity(origId);
4881            }
4882        }
4883    }
4884
4885    @Override
4886    public void finishVoiceTask(IVoiceInteractionSession session) {
4887        synchronized (this) {
4888            final long origId = Binder.clearCallingIdentity();
4889            try {
4890                // TODO: VI Consider treating local voice interactions and voice tasks
4891                // differently here
4892                mStackSupervisor.finishVoiceTask(session);
4893            } finally {
4894                Binder.restoreCallingIdentity(origId);
4895            }
4896        }
4897
4898    }
4899
4900    @Override
4901    public boolean releaseActivityInstance(IBinder token) {
4902        synchronized(this) {
4903            final long origId = Binder.clearCallingIdentity();
4904            try {
4905                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4906                if (r == null) {
4907                    return false;
4908                }
4909                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4910            } finally {
4911                Binder.restoreCallingIdentity(origId);
4912            }
4913        }
4914    }
4915
4916    @Override
4917    public void releaseSomeActivities(IApplicationThread appInt) {
4918        synchronized(this) {
4919            final long origId = Binder.clearCallingIdentity();
4920            try {
4921                ProcessRecord app = getRecordForAppLocked(appInt);
4922                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4923            } finally {
4924                Binder.restoreCallingIdentity(origId);
4925            }
4926        }
4927    }
4928
4929    @Override
4930    public boolean willActivityBeVisible(IBinder token) {
4931        synchronized(this) {
4932            ActivityStack stack = ActivityRecord.getStackLocked(token);
4933            if (stack != null) {
4934                return stack.willActivityBeVisibleLocked(token);
4935            }
4936            return false;
4937        }
4938    }
4939
4940    @Override
4941    public void overridePendingTransition(IBinder token, String packageName,
4942            int enterAnim, int exitAnim) {
4943        synchronized(this) {
4944            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4945            if (self == null) {
4946                return;
4947            }
4948
4949            final long origId = Binder.clearCallingIdentity();
4950
4951            if (self.state == ActivityState.RESUMED
4952                    || self.state == ActivityState.PAUSING) {
4953                mWindowManager.overridePendingAppTransition(packageName,
4954                        enterAnim, exitAnim, null);
4955            }
4956
4957            Binder.restoreCallingIdentity(origId);
4958        }
4959    }
4960
4961    /**
4962     * Main function for removing an existing process from the activity manager
4963     * as a result of that process going away.  Clears out all connections
4964     * to the process.
4965     */
4966    private final void handleAppDiedLocked(ProcessRecord app,
4967            boolean restarting, boolean allowRestart) {
4968        int pid = app.pid;
4969        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4970        if (!kept && !restarting) {
4971            removeLruProcessLocked(app);
4972            if (pid > 0) {
4973                ProcessList.remove(pid);
4974            }
4975        }
4976
4977        if (mProfileProc == app) {
4978            clearProfilerLocked();
4979        }
4980
4981        // Remove this application's activities from active lists.
4982        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4983
4984        app.activities.clear();
4985
4986        if (app.instrumentationClass != null) {
4987            Slog.w(TAG, "Crash of app " + app.processName
4988                  + " running instrumentation " + app.instrumentationClass);
4989            Bundle info = new Bundle();
4990            info.putString("shortMsg", "Process crashed.");
4991            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4992        }
4993
4994        if (!restarting && hasVisibleActivities
4995                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4996            // If there was nothing to resume, and we are not already restarting this process, but
4997            // there is a visible activity that is hosted by the process...  then make sure all
4998            // visible activities are running, taking care of restarting this process.
4999            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5000        }
5001    }
5002
5003    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5004        IBinder threadBinder = thread.asBinder();
5005        // Find the application record.
5006        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5007            ProcessRecord rec = mLruProcesses.get(i);
5008            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5009                return i;
5010            }
5011        }
5012        return -1;
5013    }
5014
5015    final ProcessRecord getRecordForAppLocked(
5016            IApplicationThread thread) {
5017        if (thread == null) {
5018            return null;
5019        }
5020
5021        int appIndex = getLRURecordIndexForAppLocked(thread);
5022        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5023    }
5024
5025    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5026        // If there are no longer any background processes running,
5027        // and the app that died was not running instrumentation,
5028        // then tell everyone we are now low on memory.
5029        boolean haveBg = false;
5030        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5031            ProcessRecord rec = mLruProcesses.get(i);
5032            if (rec.thread != null
5033                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5034                haveBg = true;
5035                break;
5036            }
5037        }
5038
5039        if (!haveBg) {
5040            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5041            if (doReport) {
5042                long now = SystemClock.uptimeMillis();
5043                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5044                    doReport = false;
5045                } else {
5046                    mLastMemUsageReportTime = now;
5047                }
5048            }
5049            final ArrayList<ProcessMemInfo> memInfos
5050                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5051            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5052            long now = SystemClock.uptimeMillis();
5053            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5054                ProcessRecord rec = mLruProcesses.get(i);
5055                if (rec == dyingProc || rec.thread == null) {
5056                    continue;
5057                }
5058                if (doReport) {
5059                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5060                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5061                }
5062                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5063                    // The low memory report is overriding any current
5064                    // state for a GC request.  Make sure to do
5065                    // heavy/important/visible/foreground processes first.
5066                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5067                        rec.lastRequestedGc = 0;
5068                    } else {
5069                        rec.lastRequestedGc = rec.lastLowMemory;
5070                    }
5071                    rec.reportLowMemory = true;
5072                    rec.lastLowMemory = now;
5073                    mProcessesToGc.remove(rec);
5074                    addProcessToGcListLocked(rec);
5075                }
5076            }
5077            if (doReport) {
5078                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5079                mHandler.sendMessage(msg);
5080            }
5081            scheduleAppGcsLocked();
5082        }
5083    }
5084
5085    final void appDiedLocked(ProcessRecord app) {
5086       appDiedLocked(app, app.pid, app.thread, false);
5087    }
5088
5089    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5090            boolean fromBinderDied) {
5091        // First check if this ProcessRecord is actually active for the pid.
5092        synchronized (mPidsSelfLocked) {
5093            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5094            if (curProc != app) {
5095                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5096                return;
5097            }
5098        }
5099
5100        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5101        synchronized (stats) {
5102            stats.noteProcessDiedLocked(app.info.uid, pid);
5103        }
5104
5105        if (!app.killed) {
5106            if (!fromBinderDied) {
5107                Process.killProcessQuiet(pid);
5108            }
5109            killProcessGroup(app.uid, pid);
5110            app.killed = true;
5111        }
5112
5113        // Clean up already done if the process has been re-started.
5114        if (app.pid == pid && app.thread != null &&
5115                app.thread.asBinder() == thread.asBinder()) {
5116            boolean doLowMem = app.instrumentationClass == null;
5117            boolean doOomAdj = doLowMem;
5118            if (!app.killedByAm) {
5119                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5120                        + ") has died");
5121                mAllowLowerMemLevel = true;
5122            } else {
5123                // Note that we always want to do oom adj to update our state with the
5124                // new number of procs.
5125                mAllowLowerMemLevel = false;
5126                doLowMem = false;
5127            }
5128            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5129            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5130                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5131            handleAppDiedLocked(app, false, true);
5132
5133            if (doOomAdj) {
5134                updateOomAdjLocked();
5135            }
5136            if (doLowMem) {
5137                doLowMemReportIfNeededLocked(app);
5138            }
5139        } else if (app.pid != pid) {
5140            // A new process has already been started.
5141            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5142                    + ") has died and restarted (pid " + app.pid + ").");
5143            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5144        } else if (DEBUG_PROCESSES) {
5145            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5146                    + thread.asBinder());
5147        }
5148    }
5149
5150    /**
5151     * If a stack trace dump file is configured, dump process stack traces.
5152     * @param clearTraces causes the dump file to be erased prior to the new
5153     *    traces being written, if true; when false, the new traces will be
5154     *    appended to any existing file content.
5155     * @param firstPids of dalvik VM processes to dump stack traces for first
5156     * @param lastPids of dalvik VM processes to dump stack traces for last
5157     * @param nativeProcs optional list of native process names to dump stack crawls
5158     * @return file containing stack traces, or null if no dump file is configured
5159     */
5160    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5161            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5162        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5163        if (tracesPath == null || tracesPath.length() == 0) {
5164            return null;
5165        }
5166
5167        File tracesFile = new File(tracesPath);
5168        try {
5169            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5170            tracesFile.createNewFile();
5171            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5172        } catch (IOException e) {
5173            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5174            return null;
5175        }
5176
5177        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5178        return tracesFile;
5179    }
5180
5181    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5182            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5183        // Use a FileObserver to detect when traces finish writing.
5184        // The order of traces is considered important to maintain for legibility.
5185        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5186            @Override
5187            public synchronized void onEvent(int event, String path) { notify(); }
5188        };
5189
5190        try {
5191            observer.startWatching();
5192
5193            // First collect all of the stacks of the most important pids.
5194            if (firstPids != null) {
5195                try {
5196                    int num = firstPids.size();
5197                    for (int i = 0; i < num; i++) {
5198                        synchronized (observer) {
5199                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5200                                    + firstPids.get(i));
5201                            final long sime = SystemClock.elapsedRealtime();
5202                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5203                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5204                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5205                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5206                        }
5207                    }
5208                } catch (InterruptedException e) {
5209                    Slog.wtf(TAG, e);
5210                }
5211            }
5212
5213            // Next collect the stacks of the native pids
5214            if (nativeProcs != null) {
5215                int[] pids = Process.getPidsForCommands(nativeProcs);
5216                if (pids != null) {
5217                    for (int pid : pids) {
5218                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5219                        final long sime = SystemClock.elapsedRealtime();
5220                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5221                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5222                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5223                    }
5224                }
5225            }
5226
5227            // Lastly, measure CPU usage.
5228            if (processCpuTracker != null) {
5229                processCpuTracker.init();
5230                System.gc();
5231                processCpuTracker.update();
5232                try {
5233                    synchronized (processCpuTracker) {
5234                        processCpuTracker.wait(500); // measure over 1/2 second.
5235                    }
5236                } catch (InterruptedException e) {
5237                }
5238                processCpuTracker.update();
5239
5240                // We'll take the stack crawls of just the top apps using CPU.
5241                final int N = processCpuTracker.countWorkingStats();
5242                int numProcs = 0;
5243                for (int i=0; i<N && numProcs<5; i++) {
5244                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5245                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5246                        numProcs++;
5247                        try {
5248                            synchronized (observer) {
5249                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5250                                        + stats.pid);
5251                                final long stime = SystemClock.elapsedRealtime();
5252                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5253                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5254                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5255                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5256                            }
5257                        } catch (InterruptedException e) {
5258                            Slog.wtf(TAG, e);
5259                        }
5260                    } else if (DEBUG_ANR) {
5261                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5262                                + stats.pid);
5263                    }
5264                }
5265            }
5266        } finally {
5267            observer.stopWatching();
5268        }
5269    }
5270
5271    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5272        if (true || IS_USER_BUILD) {
5273            return;
5274        }
5275        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5276        if (tracesPath == null || tracesPath.length() == 0) {
5277            return;
5278        }
5279
5280        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5281        StrictMode.allowThreadDiskWrites();
5282        try {
5283            final File tracesFile = new File(tracesPath);
5284            final File tracesDir = tracesFile.getParentFile();
5285            final File tracesTmp = new File(tracesDir, "__tmp__");
5286            try {
5287                if (tracesFile.exists()) {
5288                    tracesTmp.delete();
5289                    tracesFile.renameTo(tracesTmp);
5290                }
5291                StringBuilder sb = new StringBuilder();
5292                Time tobj = new Time();
5293                tobj.set(System.currentTimeMillis());
5294                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5295                sb.append(": ");
5296                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5297                sb.append(" since ");
5298                sb.append(msg);
5299                FileOutputStream fos = new FileOutputStream(tracesFile);
5300                fos.write(sb.toString().getBytes());
5301                if (app == null) {
5302                    fos.write("\n*** No application process!".getBytes());
5303                }
5304                fos.close();
5305                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5306            } catch (IOException e) {
5307                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5308                return;
5309            }
5310
5311            if (app != null) {
5312                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5313                firstPids.add(app.pid);
5314                dumpStackTraces(tracesPath, firstPids, null, null, null);
5315            }
5316
5317            File lastTracesFile = null;
5318            File curTracesFile = null;
5319            for (int i=9; i>=0; i--) {
5320                String name = String.format(Locale.US, "slow%02d.txt", i);
5321                curTracesFile = new File(tracesDir, name);
5322                if (curTracesFile.exists()) {
5323                    if (lastTracesFile != null) {
5324                        curTracesFile.renameTo(lastTracesFile);
5325                    } else {
5326                        curTracesFile.delete();
5327                    }
5328                }
5329                lastTracesFile = curTracesFile;
5330            }
5331            tracesFile.renameTo(curTracesFile);
5332            if (tracesTmp.exists()) {
5333                tracesTmp.renameTo(tracesFile);
5334            }
5335        } finally {
5336            StrictMode.setThreadPolicy(oldPolicy);
5337        }
5338    }
5339
5340    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5341        if (!mLaunchWarningShown) {
5342            mLaunchWarningShown = true;
5343            mUiHandler.post(new Runnable() {
5344                @Override
5345                public void run() {
5346                    synchronized (ActivityManagerService.this) {
5347                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5348                        d.show();
5349                        mUiHandler.postDelayed(new Runnable() {
5350                            @Override
5351                            public void run() {
5352                                synchronized (ActivityManagerService.this) {
5353                                    d.dismiss();
5354                                    mLaunchWarningShown = false;
5355                                }
5356                            }
5357                        }, 4000);
5358                    }
5359                }
5360            });
5361        }
5362    }
5363
5364    @Override
5365    public boolean clearApplicationUserData(final String packageName,
5366            final IPackageDataObserver observer, int userId) {
5367        enforceNotIsolatedCaller("clearApplicationUserData");
5368        int uid = Binder.getCallingUid();
5369        int pid = Binder.getCallingPid();
5370        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5371                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5372
5373        final DevicePolicyManagerInternal dpmi = LocalServices
5374                .getService(DevicePolicyManagerInternal.class);
5375        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5376            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5377        }
5378
5379        long callingId = Binder.clearCallingIdentity();
5380        try {
5381            IPackageManager pm = AppGlobals.getPackageManager();
5382            int pkgUid = -1;
5383            synchronized(this) {
5384                try {
5385                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5386                } catch (RemoteException e) {
5387                }
5388                if (pkgUid == -1) {
5389                    Slog.w(TAG, "Invalid packageName: " + packageName);
5390                    if (observer != null) {
5391                        try {
5392                            observer.onRemoveCompleted(packageName, false);
5393                        } catch (RemoteException e) {
5394                            Slog.i(TAG, "Observer no longer exists.");
5395                        }
5396                    }
5397                    return false;
5398                }
5399                if (uid == pkgUid || checkComponentPermission(
5400                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5401                        pid, uid, -1, true)
5402                        == PackageManager.PERMISSION_GRANTED) {
5403                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5404                } else {
5405                    throw new SecurityException("PID " + pid + " does not have permission "
5406                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5407                                    + " of package " + packageName);
5408                }
5409
5410                // Remove all tasks match the cleared application package and user
5411                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5412                    final TaskRecord tr = mRecentTasks.get(i);
5413                    final String taskPackageName =
5414                            tr.getBaseIntent().getComponent().getPackageName();
5415                    if (tr.userId != userId) continue;
5416                    if (!taskPackageName.equals(packageName)) continue;
5417                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5418                }
5419            }
5420
5421            try {
5422                // Clear application user data
5423                pm.clearApplicationUserData(packageName, observer, userId);
5424
5425                synchronized(this) {
5426                    // Remove all permissions granted from/to this package
5427                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5428                }
5429
5430                // Remove all zen rules created by this package; revoke it's zen access.
5431                INotificationManager inm = NotificationManager.getService();
5432                inm.removeAutomaticZenRules(packageName);
5433                inm.setNotificationPolicyAccessGranted(packageName, false);
5434
5435                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5436                        Uri.fromParts("package", packageName, null));
5437                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5438                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5439                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5440                        null, null, 0, null, null, null, null, false, false, userId);
5441            } catch (RemoteException e) {
5442            }
5443        } finally {
5444            Binder.restoreCallingIdentity(callingId);
5445        }
5446        return true;
5447    }
5448
5449    @Override
5450    public void killBackgroundProcesses(final String packageName, int userId) {
5451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5452                != PackageManager.PERMISSION_GRANTED &&
5453                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5454                        != PackageManager.PERMISSION_GRANTED) {
5455            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5456                    + Binder.getCallingPid()
5457                    + ", uid=" + Binder.getCallingUid()
5458                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5459            Slog.w(TAG, msg);
5460            throw new SecurityException(msg);
5461        }
5462
5463        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5464                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5465        long callingId = Binder.clearCallingIdentity();
5466        try {
5467            IPackageManager pm = AppGlobals.getPackageManager();
5468            synchronized(this) {
5469                int appId = -1;
5470                try {
5471                    appId = UserHandle.getAppId(
5472                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5473                } catch (RemoteException e) {
5474                }
5475                if (appId == -1) {
5476                    Slog.w(TAG, "Invalid packageName: " + packageName);
5477                    return;
5478                }
5479                killPackageProcessesLocked(packageName, appId, userId,
5480                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5481            }
5482        } finally {
5483            Binder.restoreCallingIdentity(callingId);
5484        }
5485    }
5486
5487    @Override
5488    public void killAllBackgroundProcesses() {
5489        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5490                != PackageManager.PERMISSION_GRANTED) {
5491            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5492                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5493                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5494            Slog.w(TAG, msg);
5495            throw new SecurityException(msg);
5496        }
5497
5498        final long callingId = Binder.clearCallingIdentity();
5499        try {
5500            synchronized (this) {
5501                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5502                final int NP = mProcessNames.getMap().size();
5503                for (int ip = 0; ip < NP; ip++) {
5504                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5505                    final int NA = apps.size();
5506                    for (int ia = 0; ia < NA; ia++) {
5507                        final ProcessRecord app = apps.valueAt(ia);
5508                        if (app.persistent) {
5509                            // We don't kill persistent processes.
5510                            continue;
5511                        }
5512                        if (app.removed) {
5513                            procs.add(app);
5514                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5515                            app.removed = true;
5516                            procs.add(app);
5517                        }
5518                    }
5519                }
5520
5521                final int N = procs.size();
5522                for (int i = 0; i < N; i++) {
5523                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5524                }
5525
5526                mAllowLowerMemLevel = true;
5527
5528                updateOomAdjLocked();
5529                doLowMemReportIfNeededLocked(null);
5530            }
5531        } finally {
5532            Binder.restoreCallingIdentity(callingId);
5533        }
5534    }
5535
5536    /**
5537     * Kills all background processes, except those matching any of the
5538     * specified properties.
5539     *
5540     * @param minTargetSdk the target SDK version at or above which to preserve
5541     *                     processes, or {@code -1} to ignore the target SDK
5542     * @param maxProcState the process state at or below which to preserve
5543     *                     processes, or {@code -1} to ignore the process state
5544     */
5545    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5547                != PackageManager.PERMISSION_GRANTED) {
5548            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5549                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5550                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5551            Slog.w(TAG, msg);
5552            throw new SecurityException(msg);
5553        }
5554
5555        final long callingId = Binder.clearCallingIdentity();
5556        try {
5557            synchronized (this) {
5558                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5559                final int NP = mProcessNames.getMap().size();
5560                for (int ip = 0; ip < NP; ip++) {
5561                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5562                    final int NA = apps.size();
5563                    for (int ia = 0; ia < NA; ia++) {
5564                        final ProcessRecord app = apps.valueAt(ia);
5565                        if (app.removed) {
5566                            procs.add(app);
5567                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5568                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5569                            app.removed = true;
5570                            procs.add(app);
5571                        }
5572                    }
5573                }
5574
5575                final int N = procs.size();
5576                for (int i = 0; i < N; i++) {
5577                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5578                }
5579            }
5580        } finally {
5581            Binder.restoreCallingIdentity(callingId);
5582        }
5583    }
5584
5585    @Override
5586    public void forceStopPackage(final String packageName, int userId) {
5587        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5588                != PackageManager.PERMISSION_GRANTED) {
5589            String msg = "Permission Denial: forceStopPackage() from pid="
5590                    + Binder.getCallingPid()
5591                    + ", uid=" + Binder.getCallingUid()
5592                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5593            Slog.w(TAG, msg);
5594            throw new SecurityException(msg);
5595        }
5596        final int callingPid = Binder.getCallingPid();
5597        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5598                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5599        long callingId = Binder.clearCallingIdentity();
5600        try {
5601            IPackageManager pm = AppGlobals.getPackageManager();
5602            synchronized(this) {
5603                int[] users = userId == UserHandle.USER_ALL
5604                        ? mUserController.getUsers() : new int[] { userId };
5605                for (int user : users) {
5606                    int pkgUid = -1;
5607                    try {
5608                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5609                                user);
5610                    } catch (RemoteException e) {
5611                    }
5612                    if (pkgUid == -1) {
5613                        Slog.w(TAG, "Invalid packageName: " + packageName);
5614                        continue;
5615                    }
5616                    try {
5617                        pm.setPackageStoppedState(packageName, true, user);
5618                    } catch (RemoteException e) {
5619                    } catch (IllegalArgumentException e) {
5620                        Slog.w(TAG, "Failed trying to unstop package "
5621                                + packageName + ": " + e);
5622                    }
5623                    if (mUserController.isUserRunningLocked(user, 0)) {
5624                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5625                    }
5626                }
5627            }
5628        } finally {
5629            Binder.restoreCallingIdentity(callingId);
5630        }
5631    }
5632
5633    @Override
5634    public void addPackageDependency(String packageName) {
5635        synchronized (this) {
5636            int callingPid = Binder.getCallingPid();
5637            if (callingPid == Process.myPid()) {
5638                //  Yeah, um, no.
5639                return;
5640            }
5641            ProcessRecord proc;
5642            synchronized (mPidsSelfLocked) {
5643                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5644            }
5645            if (proc != null) {
5646                if (proc.pkgDeps == null) {
5647                    proc.pkgDeps = new ArraySet<String>(1);
5648                }
5649                proc.pkgDeps.add(packageName);
5650            }
5651        }
5652    }
5653
5654    /*
5655     * The pkg name and app id have to be specified.
5656     */
5657    @Override
5658    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5659        if (pkg == null) {
5660            return;
5661        }
5662        // Make sure the uid is valid.
5663        if (appid < 0) {
5664            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5665            return;
5666        }
5667        int callerUid = Binder.getCallingUid();
5668        // Only the system server can kill an application
5669        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5670            // Post an aysnc message to kill the application
5671            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5672            msg.arg1 = appid;
5673            msg.arg2 = 0;
5674            Bundle bundle = new Bundle();
5675            bundle.putString("pkg", pkg);
5676            bundle.putString("reason", reason);
5677            msg.obj = bundle;
5678            mHandler.sendMessage(msg);
5679        } else {
5680            throw new SecurityException(callerUid + " cannot kill pkg: " +
5681                    pkg);
5682        }
5683    }
5684
5685    @Override
5686    public void closeSystemDialogs(String reason) {
5687        enforceNotIsolatedCaller("closeSystemDialogs");
5688
5689        final int pid = Binder.getCallingPid();
5690        final int uid = Binder.getCallingUid();
5691        final long origId = Binder.clearCallingIdentity();
5692        try {
5693            synchronized (this) {
5694                // Only allow this from foreground processes, so that background
5695                // applications can't abuse it to prevent system UI from being shown.
5696                if (uid >= Process.FIRST_APPLICATION_UID) {
5697                    ProcessRecord proc;
5698                    synchronized (mPidsSelfLocked) {
5699                        proc = mPidsSelfLocked.get(pid);
5700                    }
5701                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5702                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5703                                + " from background process " + proc);
5704                        return;
5705                    }
5706                }
5707                closeSystemDialogsLocked(reason);
5708            }
5709        } finally {
5710            Binder.restoreCallingIdentity(origId);
5711        }
5712    }
5713
5714    void closeSystemDialogsLocked(String reason) {
5715        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5716        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5717                | Intent.FLAG_RECEIVER_FOREGROUND);
5718        if (reason != null) {
5719            intent.putExtra("reason", reason);
5720        }
5721        mWindowManager.closeSystemDialogs(reason);
5722
5723        mStackSupervisor.closeSystemDialogsLocked();
5724
5725        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5726                AppOpsManager.OP_NONE, null, false, false,
5727                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5728    }
5729
5730    @Override
5731    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5732        enforceNotIsolatedCaller("getProcessMemoryInfo");
5733        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5734        for (int i=pids.length-1; i>=0; i--) {
5735            ProcessRecord proc;
5736            int oomAdj;
5737            synchronized (this) {
5738                synchronized (mPidsSelfLocked) {
5739                    proc = mPidsSelfLocked.get(pids[i]);
5740                    oomAdj = proc != null ? proc.setAdj : 0;
5741                }
5742            }
5743            infos[i] = new Debug.MemoryInfo();
5744            Debug.getMemoryInfo(pids[i], infos[i]);
5745            if (proc != null) {
5746                synchronized (this) {
5747                    if (proc.thread != null && proc.setAdj == oomAdj) {
5748                        // Record this for posterity if the process has been stable.
5749                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5750                                infos[i].getTotalUss(), false, proc.pkgList);
5751                    }
5752                }
5753            }
5754        }
5755        return infos;
5756    }
5757
5758    @Override
5759    public long[] getProcessPss(int[] pids) {
5760        enforceNotIsolatedCaller("getProcessPss");
5761        long[] pss = new long[pids.length];
5762        for (int i=pids.length-1; i>=0; i--) {
5763            ProcessRecord proc;
5764            int oomAdj;
5765            synchronized (this) {
5766                synchronized (mPidsSelfLocked) {
5767                    proc = mPidsSelfLocked.get(pids[i]);
5768                    oomAdj = proc != null ? proc.setAdj : 0;
5769                }
5770            }
5771            long[] tmpUss = new long[1];
5772            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5773            if (proc != null) {
5774                synchronized (this) {
5775                    if (proc.thread != null && proc.setAdj == oomAdj) {
5776                        // Record this for posterity if the process has been stable.
5777                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5778                    }
5779                }
5780            }
5781        }
5782        return pss;
5783    }
5784
5785    @Override
5786    public void killApplicationProcess(String processName, int uid) {
5787        if (processName == null) {
5788            return;
5789        }
5790
5791        int callerUid = Binder.getCallingUid();
5792        // Only the system server can kill an application
5793        if (callerUid == Process.SYSTEM_UID) {
5794            synchronized (this) {
5795                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5796                if (app != null && app.thread != null) {
5797                    try {
5798                        app.thread.scheduleSuicide();
5799                    } catch (RemoteException e) {
5800                        // If the other end already died, then our work here is done.
5801                    }
5802                } else {
5803                    Slog.w(TAG, "Process/uid not found attempting kill of "
5804                            + processName + " / " + uid);
5805                }
5806            }
5807        } else {
5808            throw new SecurityException(callerUid + " cannot kill app process: " +
5809                    processName);
5810        }
5811    }
5812
5813    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5814        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5815                false, true, false, false, UserHandle.getUserId(uid), reason);
5816        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5817                Uri.fromParts("package", packageName, null));
5818        if (!mProcessesReady) {
5819            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5820                    | Intent.FLAG_RECEIVER_FOREGROUND);
5821        }
5822        intent.putExtra(Intent.EXTRA_UID, uid);
5823        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5824        broadcastIntentLocked(null, null, intent,
5825                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5826                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5827    }
5828
5829
5830    private final boolean killPackageProcessesLocked(String packageName, int appId,
5831            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5832            boolean doit, boolean evenPersistent, String reason) {
5833        ArrayList<ProcessRecord> procs = new ArrayList<>();
5834
5835        // Remove all processes this package may have touched: all with the
5836        // same UID (except for the system or root user), and all whose name
5837        // matches the package name.
5838        final int NP = mProcessNames.getMap().size();
5839        for (int ip=0; ip<NP; ip++) {
5840            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5841            final int NA = apps.size();
5842            for (int ia=0; ia<NA; ia++) {
5843                ProcessRecord app = apps.valueAt(ia);
5844                if (app.persistent && !evenPersistent) {
5845                    // we don't kill persistent processes
5846                    continue;
5847                }
5848                if (app.removed) {
5849                    if (doit) {
5850                        procs.add(app);
5851                    }
5852                    continue;
5853                }
5854
5855                // Skip process if it doesn't meet our oom adj requirement.
5856                if (app.setAdj < minOomAdj) {
5857                    continue;
5858                }
5859
5860                // If no package is specified, we call all processes under the
5861                // give user id.
5862                if (packageName == null) {
5863                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5864                        continue;
5865                    }
5866                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5867                        continue;
5868                    }
5869                // Package has been specified, we want to hit all processes
5870                // that match it.  We need to qualify this by the processes
5871                // that are running under the specified app and user ID.
5872                } else {
5873                    final boolean isDep = app.pkgDeps != null
5874                            && app.pkgDeps.contains(packageName);
5875                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5876                        continue;
5877                    }
5878                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5879                        continue;
5880                    }
5881                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5882                        continue;
5883                    }
5884                }
5885
5886                // Process has passed all conditions, kill it!
5887                if (!doit) {
5888                    return true;
5889                }
5890                app.removed = true;
5891                procs.add(app);
5892            }
5893        }
5894
5895        int N = procs.size();
5896        for (int i=0; i<N; i++) {
5897            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5898        }
5899        updateOomAdjLocked();
5900        return N > 0;
5901    }
5902
5903    private void cleanupDisabledPackageComponentsLocked(
5904            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5905
5906        Set<String> disabledClasses = null;
5907        boolean packageDisabled = false;
5908        IPackageManager pm = AppGlobals.getPackageManager();
5909
5910        if (changedClasses == null) {
5911            // Nothing changed...
5912            return;
5913        }
5914
5915        // Determine enable/disable state of the package and its components.
5916        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5917        for (int i = changedClasses.length - 1; i >= 0; i--) {
5918            final String changedClass = changedClasses[i];
5919
5920            if (changedClass.equals(packageName)) {
5921                try {
5922                    // Entire package setting changed
5923                    enabled = pm.getApplicationEnabledSetting(packageName,
5924                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5925                } catch (Exception e) {
5926                    // No such package/component; probably racing with uninstall.  In any
5927                    // event it means we have nothing further to do here.
5928                    return;
5929                }
5930                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5931                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5932                if (packageDisabled) {
5933                    // Entire package is disabled.
5934                    // No need to continue to check component states.
5935                    disabledClasses = null;
5936                    break;
5937                }
5938            } else {
5939                try {
5940                    enabled = pm.getComponentEnabledSetting(
5941                            new ComponentName(packageName, changedClass),
5942                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5943                } catch (Exception e) {
5944                    // As above, probably racing with uninstall.
5945                    return;
5946                }
5947                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5948                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5949                    if (disabledClasses == null) {
5950                        disabledClasses = new ArraySet<>(changedClasses.length);
5951                    }
5952                    disabledClasses.add(changedClass);
5953                }
5954            }
5955        }
5956
5957        if (!packageDisabled && disabledClasses == null) {
5958            // Nothing to do here...
5959            return;
5960        }
5961
5962        // Clean-up disabled activities.
5963        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5964                packageName, disabledClasses, true, false, userId) && mBooted) {
5965            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5966            mStackSupervisor.scheduleIdleLocked();
5967        }
5968
5969        // Clean-up disabled tasks
5970        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5971
5972        // Clean-up disabled services.
5973        mServices.bringDownDisabledPackageServicesLocked(
5974                packageName, disabledClasses, userId, false, killProcess, true);
5975
5976        // Clean-up disabled providers.
5977        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5978        mProviderMap.collectPackageProvidersLocked(
5979                packageName, disabledClasses, true, false, userId, providers);
5980        for (int i = providers.size() - 1; i >= 0; i--) {
5981            removeDyingProviderLocked(null, providers.get(i), true);
5982        }
5983
5984        // Clean-up disabled broadcast receivers.
5985        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5986            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5987                    packageName, disabledClasses, userId, true);
5988        }
5989
5990    }
5991
5992    final boolean clearBroadcastQueueForUserLocked(int userId) {
5993        boolean didSomething = false;
5994        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5995            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5996                    null, null, userId, true);
5997        }
5998        return didSomething;
5999    }
6000
6001    final boolean forceStopPackageLocked(String packageName, int appId,
6002            boolean callerWillRestart, boolean purgeCache, boolean doit,
6003            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6004        int i;
6005
6006        if (userId == UserHandle.USER_ALL && packageName == null) {
6007            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6008        }
6009
6010        if (appId < 0 && packageName != null) {
6011            try {
6012                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6013                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6014            } catch (RemoteException e) {
6015            }
6016        }
6017
6018        if (doit) {
6019            if (packageName != null) {
6020                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6021                        + " user=" + userId + ": " + reason);
6022            } else {
6023                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6024            }
6025
6026            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6027        }
6028
6029        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6030                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6031                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6032
6033        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6034                packageName, null, doit, evenPersistent, userId)) {
6035            if (!doit) {
6036                return true;
6037            }
6038            didSomething = true;
6039        }
6040
6041        if (mServices.bringDownDisabledPackageServicesLocked(
6042                packageName, null, userId, evenPersistent, true, doit)) {
6043            if (!doit) {
6044                return true;
6045            }
6046            didSomething = true;
6047        }
6048
6049        if (packageName == null) {
6050            // Remove all sticky broadcasts from this user.
6051            mStickyBroadcasts.remove(userId);
6052        }
6053
6054        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6055        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6056                userId, providers)) {
6057            if (!doit) {
6058                return true;
6059            }
6060            didSomething = true;
6061        }
6062        for (i = providers.size() - 1; i >= 0; i--) {
6063            removeDyingProviderLocked(null, providers.get(i), true);
6064        }
6065
6066        // Remove transient permissions granted from/to this package/user
6067        removeUriPermissionsForPackageLocked(packageName, userId, false);
6068
6069        if (doit) {
6070            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6071                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6072                        packageName, null, userId, doit);
6073            }
6074        }
6075
6076        if (packageName == null || uninstalling) {
6077            // Remove pending intents.  For now we only do this when force
6078            // stopping users, because we have some problems when doing this
6079            // for packages -- app widgets are not currently cleaned up for
6080            // such packages, so they can be left with bad pending intents.
6081            if (mIntentSenderRecords.size() > 0) {
6082                Iterator<WeakReference<PendingIntentRecord>> it
6083                        = mIntentSenderRecords.values().iterator();
6084                while (it.hasNext()) {
6085                    WeakReference<PendingIntentRecord> wpir = it.next();
6086                    if (wpir == null) {
6087                        it.remove();
6088                        continue;
6089                    }
6090                    PendingIntentRecord pir = wpir.get();
6091                    if (pir == null) {
6092                        it.remove();
6093                        continue;
6094                    }
6095                    if (packageName == null) {
6096                        // Stopping user, remove all objects for the user.
6097                        if (pir.key.userId != userId) {
6098                            // Not the same user, skip it.
6099                            continue;
6100                        }
6101                    } else {
6102                        if (UserHandle.getAppId(pir.uid) != appId) {
6103                            // Different app id, skip it.
6104                            continue;
6105                        }
6106                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6107                            // Different user, skip it.
6108                            continue;
6109                        }
6110                        if (!pir.key.packageName.equals(packageName)) {
6111                            // Different package, skip it.
6112                            continue;
6113                        }
6114                    }
6115                    if (!doit) {
6116                        return true;
6117                    }
6118                    didSomething = true;
6119                    it.remove();
6120                    pir.canceled = true;
6121                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6122                        pir.key.activity.pendingResults.remove(pir.ref);
6123                    }
6124                }
6125            }
6126        }
6127
6128        if (doit) {
6129            if (purgeCache && packageName != null) {
6130                AttributeCache ac = AttributeCache.instance();
6131                if (ac != null) {
6132                    ac.removePackage(packageName);
6133                }
6134            }
6135            if (mBooted) {
6136                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6137                mStackSupervisor.scheduleIdleLocked();
6138            }
6139        }
6140
6141        return didSomething;
6142    }
6143
6144    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6145        ProcessRecord old = mProcessNames.remove(name, uid);
6146        if (old != null) {
6147            old.uidRecord.numProcs--;
6148            if (old.uidRecord.numProcs == 0) {
6149                // No more processes using this uid, tell clients it is gone.
6150                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6151                        "No more processes in " + old.uidRecord);
6152                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6153                mActiveUids.remove(uid);
6154                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6155            }
6156            old.uidRecord = null;
6157        }
6158        mIsolatedProcesses.remove(uid);
6159        return old;
6160    }
6161
6162    private final void addProcessNameLocked(ProcessRecord proc) {
6163        // We shouldn't already have a process under this name, but just in case we
6164        // need to clean up whatever may be there now.
6165        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6166        if (old == proc && proc.persistent) {
6167            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6168            Slog.w(TAG, "Re-adding persistent process " + proc);
6169        } else if (old != null) {
6170            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6171        }
6172        UidRecord uidRec = mActiveUids.get(proc.uid);
6173        if (uidRec == null) {
6174            uidRec = new UidRecord(proc.uid);
6175            // This is the first appearance of the uid, report it now!
6176            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6177                    "Creating new process uid: " + uidRec);
6178            mActiveUids.put(proc.uid, uidRec);
6179            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6180            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6181        }
6182        proc.uidRecord = uidRec;
6183        uidRec.numProcs++;
6184        mProcessNames.put(proc.processName, proc.uid, proc);
6185        if (proc.isolated) {
6186            mIsolatedProcesses.put(proc.uid, proc);
6187        }
6188    }
6189
6190    boolean removeProcessLocked(ProcessRecord app,
6191            boolean callerWillRestart, boolean allowRestart, String reason) {
6192        final String name = app.processName;
6193        final int uid = app.uid;
6194        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6195            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6196
6197        ProcessRecord old = mProcessNames.get(name, uid);
6198        if (old != app) {
6199            // This process is no longer active, so nothing to do.
6200            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6201            return false;
6202        }
6203        removeProcessNameLocked(name, uid);
6204        if (mHeavyWeightProcess == app) {
6205            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6206                    mHeavyWeightProcess.userId, 0));
6207            mHeavyWeightProcess = null;
6208        }
6209        boolean needRestart = false;
6210        if (app.pid > 0 && app.pid != MY_PID) {
6211            int pid = app.pid;
6212            synchronized (mPidsSelfLocked) {
6213                mPidsSelfLocked.remove(pid);
6214                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6215            }
6216            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6217            if (app.isolated) {
6218                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6219            }
6220            boolean willRestart = false;
6221            if (app.persistent && !app.isolated) {
6222                if (!callerWillRestart) {
6223                    willRestart = true;
6224                } else {
6225                    needRestart = true;
6226                }
6227            }
6228            app.kill(reason, true);
6229            handleAppDiedLocked(app, willRestart, allowRestart);
6230            if (willRestart) {
6231                removeLruProcessLocked(app);
6232                addAppLocked(app.info, false, null /* ABI override */);
6233            }
6234        } else {
6235            mRemovedProcesses.add(app);
6236        }
6237
6238        return needRestart;
6239    }
6240
6241    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6242        cleanupAppInLaunchingProvidersLocked(app, true);
6243        removeProcessLocked(app, false, true, "timeout publishing content providers");
6244    }
6245
6246    private final void processStartTimedOutLocked(ProcessRecord app) {
6247        final int pid = app.pid;
6248        boolean gone = false;
6249        synchronized (mPidsSelfLocked) {
6250            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6251            if (knownApp != null && knownApp.thread == null) {
6252                mPidsSelfLocked.remove(pid);
6253                gone = true;
6254            }
6255        }
6256
6257        if (gone) {
6258            Slog.w(TAG, "Process " + app + " failed to attach");
6259            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6260                    pid, app.uid, app.processName);
6261            removeProcessNameLocked(app.processName, app.uid);
6262            if (mHeavyWeightProcess == app) {
6263                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6264                        mHeavyWeightProcess.userId, 0));
6265                mHeavyWeightProcess = null;
6266            }
6267            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6268            if (app.isolated) {
6269                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6270            }
6271            // Take care of any launching providers waiting for this process.
6272            cleanupAppInLaunchingProvidersLocked(app, true);
6273            // Take care of any services that are waiting for the process.
6274            mServices.processStartTimedOutLocked(app);
6275            app.kill("start timeout", true);
6276            removeLruProcessLocked(app);
6277            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6278                Slog.w(TAG, "Unattached app died before backup, skipping");
6279                try {
6280                    IBackupManager bm = IBackupManager.Stub.asInterface(
6281                            ServiceManager.getService(Context.BACKUP_SERVICE));
6282                    bm.agentDisconnected(app.info.packageName);
6283                } catch (RemoteException e) {
6284                    // Can't happen; the backup manager is local
6285                }
6286            }
6287            if (isPendingBroadcastProcessLocked(pid)) {
6288                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6289                skipPendingBroadcastLocked(pid);
6290            }
6291        } else {
6292            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6293        }
6294    }
6295
6296    private final boolean attachApplicationLocked(IApplicationThread thread,
6297            int pid) {
6298
6299        // Find the application record that is being attached...  either via
6300        // the pid if we are running in multiple processes, or just pull the
6301        // next app record if we are emulating process with anonymous threads.
6302        ProcessRecord app;
6303        if (pid != MY_PID && pid >= 0) {
6304            synchronized (mPidsSelfLocked) {
6305                app = mPidsSelfLocked.get(pid);
6306            }
6307        } else {
6308            app = null;
6309        }
6310
6311        if (app == null) {
6312            Slog.w(TAG, "No pending application record for pid " + pid
6313                    + " (IApplicationThread " + thread + "); dropping process");
6314            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6315            if (pid > 0 && pid != MY_PID) {
6316                Process.killProcessQuiet(pid);
6317                //TODO: killProcessGroup(app.info.uid, pid);
6318            } else {
6319                try {
6320                    thread.scheduleExit();
6321                } catch (Exception e) {
6322                    // Ignore exceptions.
6323                }
6324            }
6325            return false;
6326        }
6327
6328        // If this application record is still attached to a previous
6329        // process, clean it up now.
6330        if (app.thread != null) {
6331            handleAppDiedLocked(app, true, true);
6332        }
6333
6334        // Tell the process all about itself.
6335
6336        if (DEBUG_ALL) Slog.v(
6337                TAG, "Binding process pid " + pid + " to record " + app);
6338
6339        final String processName = app.processName;
6340        try {
6341            AppDeathRecipient adr = new AppDeathRecipient(
6342                    app, pid, thread);
6343            thread.asBinder().linkToDeath(adr, 0);
6344            app.deathRecipient = adr;
6345        } catch (RemoteException e) {
6346            app.resetPackageList(mProcessStats);
6347            startProcessLocked(app, "link fail", processName);
6348            return false;
6349        }
6350
6351        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6352
6353        app.makeActive(thread, mProcessStats);
6354        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6355        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6356        app.forcingToForeground = null;
6357        updateProcessForegroundLocked(app, false, false);
6358        app.hasShownUi = false;
6359        app.debugging = false;
6360        app.cached = false;
6361        app.killedByAm = false;
6362
6363        // We carefully use the same state that PackageManager uses for
6364        // filtering, since we use this flag to decide if we need to install
6365        // providers when user is unlocked later
6366        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6367
6368        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6369
6370        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6371        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6372
6373        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6374            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6375            msg.obj = app;
6376            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6377        }
6378
6379        if (!normalMode) {
6380            Slog.i(TAG, "Launching preboot mode app: " + app);
6381        }
6382
6383        if (DEBUG_ALL) Slog.v(
6384            TAG, "New app record " + app
6385            + " thread=" + thread.asBinder() + " pid=" + pid);
6386        try {
6387            int testMode = IApplicationThread.DEBUG_OFF;
6388            if (mDebugApp != null && mDebugApp.equals(processName)) {
6389                testMode = mWaitForDebugger
6390                    ? IApplicationThread.DEBUG_WAIT
6391                    : IApplicationThread.DEBUG_ON;
6392                app.debugging = true;
6393                if (mDebugTransient) {
6394                    mDebugApp = mOrigDebugApp;
6395                    mWaitForDebugger = mOrigWaitForDebugger;
6396                }
6397            }
6398            String profileFile = app.instrumentationProfileFile;
6399            ParcelFileDescriptor profileFd = null;
6400            int samplingInterval = 0;
6401            boolean profileAutoStop = false;
6402            if (mProfileApp != null && mProfileApp.equals(processName)) {
6403                mProfileProc = app;
6404                profileFile = mProfileFile;
6405                profileFd = mProfileFd;
6406                samplingInterval = mSamplingInterval;
6407                profileAutoStop = mAutoStopProfiler;
6408            }
6409            boolean enableTrackAllocation = false;
6410            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6411                enableTrackAllocation = true;
6412                mTrackAllocationApp = null;
6413            }
6414
6415            // If the app is being launched for restore or full backup, set it up specially
6416            boolean isRestrictedBackupMode = false;
6417            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6418                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6419                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6420                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6421                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6422            }
6423
6424            if (app.instrumentationClass != null) {
6425                notifyPackageUse(app.instrumentationClass.getPackageName(),
6426                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6427            }
6428            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6429                    + processName + " with config " + mConfiguration);
6430            ApplicationInfo appInfo = app.instrumentationInfo != null
6431                    ? app.instrumentationInfo : app.info;
6432            app.compat = compatibilityInfoForPackageLocked(appInfo);
6433            if (profileFd != null) {
6434                profileFd = profileFd.dup();
6435            }
6436            ProfilerInfo profilerInfo = profileFile == null ? null
6437                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6438            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6439                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6440                    app.instrumentationUiAutomationConnection, testMode,
6441                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6442                    isRestrictedBackupMode || !normalMode, app.persistent,
6443                    new Configuration(mConfiguration), app.compat,
6444                    getCommonServicesLocked(app.isolated),
6445                    mCoreSettingsObserver.getCoreSettingsLocked());
6446            updateLruProcessLocked(app, false, null);
6447            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6448        } catch (Exception e) {
6449            // todo: Yikes!  What should we do?  For now we will try to
6450            // start another process, but that could easily get us in
6451            // an infinite loop of restarting processes...
6452            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6453
6454            app.resetPackageList(mProcessStats);
6455            app.unlinkDeathRecipient();
6456            startProcessLocked(app, "bind fail", processName);
6457            return false;
6458        }
6459
6460        // Remove this record from the list of starting applications.
6461        mPersistentStartingProcesses.remove(app);
6462        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6463                "Attach application locked removing on hold: " + app);
6464        mProcessesOnHold.remove(app);
6465
6466        boolean badApp = false;
6467        boolean didSomething = false;
6468
6469        // See if the top visible activity is waiting to run in this process...
6470        if (normalMode) {
6471            try {
6472                if (mStackSupervisor.attachApplicationLocked(app)) {
6473                    didSomething = true;
6474                }
6475            } catch (Exception e) {
6476                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6477                badApp = true;
6478            }
6479        }
6480
6481        // Find any services that should be running in this process...
6482        if (!badApp) {
6483            try {
6484                didSomething |= mServices.attachApplicationLocked(app, processName);
6485            } catch (Exception e) {
6486                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6487                badApp = true;
6488            }
6489        }
6490
6491        // Check if a next-broadcast receiver is in this process...
6492        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6493            try {
6494                didSomething |= sendPendingBroadcastsLocked(app);
6495            } catch (Exception e) {
6496                // If the app died trying to launch the receiver we declare it 'bad'
6497                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6498                badApp = true;
6499            }
6500        }
6501
6502        // Check whether the next backup agent is in this process...
6503        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6504            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6505                    "New app is backup target, launching agent for " + app);
6506            notifyPackageUse(mBackupTarget.appInfo.packageName,
6507                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6508            try {
6509                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6510                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6511                        mBackupTarget.backupMode);
6512            } catch (Exception e) {
6513                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6514                badApp = true;
6515            }
6516        }
6517
6518        if (badApp) {
6519            app.kill("error during init", true);
6520            handleAppDiedLocked(app, false, true);
6521            return false;
6522        }
6523
6524        if (!didSomething) {
6525            updateOomAdjLocked();
6526        }
6527
6528        return true;
6529    }
6530
6531    @Override
6532    public final void attachApplication(IApplicationThread thread) {
6533        synchronized (this) {
6534            int callingPid = Binder.getCallingPid();
6535            final long origId = Binder.clearCallingIdentity();
6536            attachApplicationLocked(thread, callingPid);
6537            Binder.restoreCallingIdentity(origId);
6538        }
6539    }
6540
6541    @Override
6542    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6543        final long origId = Binder.clearCallingIdentity();
6544        synchronized (this) {
6545            ActivityStack stack = ActivityRecord.getStackLocked(token);
6546            if (stack != null) {
6547                ActivityRecord r =
6548                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6549                if (stopProfiling) {
6550                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6551                        try {
6552                            mProfileFd.close();
6553                        } catch (IOException e) {
6554                        }
6555                        clearProfilerLocked();
6556                    }
6557                }
6558            }
6559        }
6560        Binder.restoreCallingIdentity(origId);
6561    }
6562
6563    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6564        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6565                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6566    }
6567
6568    void enableScreenAfterBoot() {
6569        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6570                SystemClock.uptimeMillis());
6571        mWindowManager.enableScreenAfterBoot();
6572
6573        synchronized (this) {
6574            updateEventDispatchingLocked();
6575        }
6576    }
6577
6578    @Override
6579    public void showBootMessage(final CharSequence msg, final boolean always) {
6580        if (Binder.getCallingUid() != Process.myUid()) {
6581            // These days only the core system can call this, so apps can't get in
6582            // the way of what we show about running them.
6583        }
6584        mWindowManager.showBootMessage(msg, always);
6585    }
6586
6587    @Override
6588    public void keyguardWaitingForActivityDrawn() {
6589        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6590        final long token = Binder.clearCallingIdentity();
6591        try {
6592            synchronized (this) {
6593                if (DEBUG_LOCKSCREEN) logLockScreen("");
6594                mWindowManager.keyguardWaitingForActivityDrawn();
6595                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6596                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6597                    updateSleepIfNeededLocked();
6598                }
6599            }
6600        } finally {
6601            Binder.restoreCallingIdentity(token);
6602        }
6603    }
6604
6605    @Override
6606    public void keyguardGoingAway(int flags) {
6607        enforceNotIsolatedCaller("keyguardGoingAway");
6608        final long token = Binder.clearCallingIdentity();
6609        try {
6610            synchronized (this) {
6611                if (DEBUG_LOCKSCREEN) logLockScreen("");
6612                mWindowManager.keyguardGoingAway(flags);
6613                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6614                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6615                    updateSleepIfNeededLocked();
6616
6617                    // Some stack visibility might change (e.g. docked stack)
6618                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6619                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6620                }
6621            }
6622        } finally {
6623            Binder.restoreCallingIdentity(token);
6624        }
6625    }
6626
6627    final void finishBooting() {
6628        synchronized (this) {
6629            if (!mBootAnimationComplete) {
6630                mCallFinishBooting = true;
6631                return;
6632            }
6633            mCallFinishBooting = false;
6634        }
6635
6636        ArraySet<String> completedIsas = new ArraySet<String>();
6637        for (String abi : Build.SUPPORTED_ABIS) {
6638            Process.establishZygoteConnectionForAbi(abi);
6639            final String instructionSet = VMRuntime.getInstructionSet(abi);
6640            if (!completedIsas.contains(instructionSet)) {
6641                try {
6642                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6643                } catch (InstallerException e) {
6644                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6645                            e.getMessage() +")");
6646                }
6647                completedIsas.add(instructionSet);
6648            }
6649        }
6650
6651        IntentFilter pkgFilter = new IntentFilter();
6652        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6653        pkgFilter.addDataScheme("package");
6654        mContext.registerReceiver(new BroadcastReceiver() {
6655            @Override
6656            public void onReceive(Context context, Intent intent) {
6657                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6658                if (pkgs != null) {
6659                    for (String pkg : pkgs) {
6660                        synchronized (ActivityManagerService.this) {
6661                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6662                                    0, "query restart")) {
6663                                setResultCode(Activity.RESULT_OK);
6664                                return;
6665                            }
6666                        }
6667                    }
6668                }
6669            }
6670        }, pkgFilter);
6671
6672        IntentFilter dumpheapFilter = new IntentFilter();
6673        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6674        mContext.registerReceiver(new BroadcastReceiver() {
6675            @Override
6676            public void onReceive(Context context, Intent intent) {
6677                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6678                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6679                } else {
6680                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6681                }
6682            }
6683        }, dumpheapFilter);
6684
6685        // Let system services know.
6686        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6687
6688        synchronized (this) {
6689            // Ensure that any processes we had put on hold are now started
6690            // up.
6691            final int NP = mProcessesOnHold.size();
6692            if (NP > 0) {
6693                ArrayList<ProcessRecord> procs =
6694                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6695                for (int ip=0; ip<NP; ip++) {
6696                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6697                            + procs.get(ip));
6698                    startProcessLocked(procs.get(ip), "on-hold", null);
6699                }
6700            }
6701
6702            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6703                // Start looking for apps that are abusing wake locks.
6704                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6705                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6706                // Tell anyone interested that we are done booting!
6707                SystemProperties.set("sys.boot_completed", "1");
6708
6709                // And trigger dev.bootcomplete if we are not showing encryption progress
6710                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6711                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6712                    SystemProperties.set("dev.bootcomplete", "1");
6713                }
6714                mUserController.sendBootCompletedLocked(
6715                        new IIntentReceiver.Stub() {
6716                            @Override
6717                            public void performReceive(Intent intent, int resultCode,
6718                                    String data, Bundle extras, boolean ordered,
6719                                    boolean sticky, int sendingUser) {
6720                                synchronized (ActivityManagerService.this) {
6721                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6722                                            true, false);
6723                                }
6724                            }
6725                        });
6726                scheduleStartProfilesLocked();
6727            }
6728        }
6729    }
6730
6731    @Override
6732    public void bootAnimationComplete() {
6733        final boolean callFinishBooting;
6734        synchronized (this) {
6735            callFinishBooting = mCallFinishBooting;
6736            mBootAnimationComplete = true;
6737        }
6738        if (callFinishBooting) {
6739            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6740            finishBooting();
6741            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6742        }
6743    }
6744
6745    final void ensureBootCompleted() {
6746        boolean booting;
6747        boolean enableScreen;
6748        synchronized (this) {
6749            booting = mBooting;
6750            mBooting = false;
6751            enableScreen = !mBooted;
6752            mBooted = true;
6753        }
6754
6755        if (booting) {
6756            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6757            finishBooting();
6758            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6759        }
6760
6761        if (enableScreen) {
6762            enableScreenAfterBoot();
6763        }
6764    }
6765
6766    @Override
6767    public final void activityResumed(IBinder token) {
6768        final long origId = Binder.clearCallingIdentity();
6769        synchronized(this) {
6770            ActivityStack stack = ActivityRecord.getStackLocked(token);
6771            if (stack != null) {
6772                stack.activityResumedLocked(token);
6773            }
6774        }
6775        Binder.restoreCallingIdentity(origId);
6776    }
6777
6778    @Override
6779    public final void activityPaused(IBinder token) {
6780        final long origId = Binder.clearCallingIdentity();
6781        synchronized(this) {
6782            ActivityStack stack = ActivityRecord.getStackLocked(token);
6783            if (stack != null) {
6784                stack.activityPausedLocked(token, false);
6785            }
6786        }
6787        Binder.restoreCallingIdentity(origId);
6788    }
6789
6790    @Override
6791    public final void activityStopped(IBinder token, Bundle icicle,
6792            PersistableBundle persistentState, CharSequence description) {
6793        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6794
6795        // Refuse possible leaked file descriptors
6796        if (icicle != null && icicle.hasFileDescriptors()) {
6797            throw new IllegalArgumentException("File descriptors passed in Bundle");
6798        }
6799
6800        final long origId = Binder.clearCallingIdentity();
6801
6802        synchronized (this) {
6803            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6804            if (r != null) {
6805                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6806            }
6807        }
6808
6809        trimApplications();
6810
6811        Binder.restoreCallingIdentity(origId);
6812    }
6813
6814    @Override
6815    public final void activityDestroyed(IBinder token) {
6816        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6817        synchronized (this) {
6818            ActivityStack stack = ActivityRecord.getStackLocked(token);
6819            if (stack != null) {
6820                stack.activityDestroyedLocked(token, "activityDestroyed");
6821            }
6822        }
6823    }
6824
6825    @Override
6826    public final void activityRelaunched(IBinder token) {
6827        final long origId = Binder.clearCallingIdentity();
6828        synchronized (this) {
6829            mStackSupervisor.activityRelaunchedLocked(token);
6830        }
6831        Binder.restoreCallingIdentity(origId);
6832    }
6833
6834    @Override
6835    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6836            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6837        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6838                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6839        synchronized (this) {
6840            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6841            if (record == null) {
6842                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6843                        + "found for: " + token);
6844            }
6845            record.setSizeConfigurations(horizontalSizeConfiguration,
6846                    verticalSizeConfigurations, smallestSizeConfigurations);
6847        }
6848    }
6849
6850    @Override
6851    public final void backgroundResourcesReleased(IBinder token) {
6852        final long origId = Binder.clearCallingIdentity();
6853        try {
6854            synchronized (this) {
6855                ActivityStack stack = ActivityRecord.getStackLocked(token);
6856                if (stack != null) {
6857                    stack.backgroundResourcesReleased();
6858                }
6859            }
6860        } finally {
6861            Binder.restoreCallingIdentity(origId);
6862        }
6863    }
6864
6865    @Override
6866    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6867        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6868    }
6869
6870    @Override
6871    public final void notifyEnterAnimationComplete(IBinder token) {
6872        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6873    }
6874
6875    @Override
6876    public String getCallingPackage(IBinder token) {
6877        synchronized (this) {
6878            ActivityRecord r = getCallingRecordLocked(token);
6879            return r != null ? r.info.packageName : null;
6880        }
6881    }
6882
6883    @Override
6884    public ComponentName getCallingActivity(IBinder token) {
6885        synchronized (this) {
6886            ActivityRecord r = getCallingRecordLocked(token);
6887            return r != null ? r.intent.getComponent() : null;
6888        }
6889    }
6890
6891    private ActivityRecord getCallingRecordLocked(IBinder token) {
6892        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6893        if (r == null) {
6894            return null;
6895        }
6896        return r.resultTo;
6897    }
6898
6899    @Override
6900    public ComponentName getActivityClassForToken(IBinder token) {
6901        synchronized(this) {
6902            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6903            if (r == null) {
6904                return null;
6905            }
6906            return r.intent.getComponent();
6907        }
6908    }
6909
6910    @Override
6911    public String getPackageForToken(IBinder token) {
6912        synchronized(this) {
6913            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6914            if (r == null) {
6915                return null;
6916            }
6917            return r.packageName;
6918        }
6919    }
6920
6921    @Override
6922    public boolean isRootVoiceInteraction(IBinder token) {
6923        synchronized(this) {
6924            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6925            if (r == null) {
6926                return false;
6927            }
6928            return r.rootVoiceInteraction;
6929        }
6930    }
6931
6932    @Override
6933    public IIntentSender getIntentSender(int type,
6934            String packageName, IBinder token, String resultWho,
6935            int requestCode, Intent[] intents, String[] resolvedTypes,
6936            int flags, Bundle bOptions, int userId) {
6937        enforceNotIsolatedCaller("getIntentSender");
6938        // Refuse possible leaked file descriptors
6939        if (intents != null) {
6940            if (intents.length < 1) {
6941                throw new IllegalArgumentException("Intents array length must be >= 1");
6942            }
6943            for (int i=0; i<intents.length; i++) {
6944                Intent intent = intents[i];
6945                if (intent != null) {
6946                    if (intent.hasFileDescriptors()) {
6947                        throw new IllegalArgumentException("File descriptors passed in Intent");
6948                    }
6949                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6950                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6951                        throw new IllegalArgumentException(
6952                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6953                    }
6954                    intents[i] = new Intent(intent);
6955                }
6956            }
6957            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6958                throw new IllegalArgumentException(
6959                        "Intent array length does not match resolvedTypes length");
6960            }
6961        }
6962        if (bOptions != null) {
6963            if (bOptions.hasFileDescriptors()) {
6964                throw new IllegalArgumentException("File descriptors passed in options");
6965            }
6966        }
6967
6968        synchronized(this) {
6969            int callingUid = Binder.getCallingUid();
6970            int origUserId = userId;
6971            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6972                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6973                    ALLOW_NON_FULL, "getIntentSender", null);
6974            if (origUserId == UserHandle.USER_CURRENT) {
6975                // We don't want to evaluate this until the pending intent is
6976                // actually executed.  However, we do want to always do the
6977                // security checking for it above.
6978                userId = UserHandle.USER_CURRENT;
6979            }
6980            try {
6981                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6982                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6983                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6984                    if (!UserHandle.isSameApp(callingUid, uid)) {
6985                        String msg = "Permission Denial: getIntentSender() from pid="
6986                            + Binder.getCallingPid()
6987                            + ", uid=" + Binder.getCallingUid()
6988                            + ", (need uid=" + uid + ")"
6989                            + " is not allowed to send as package " + packageName;
6990                        Slog.w(TAG, msg);
6991                        throw new SecurityException(msg);
6992                    }
6993                }
6994
6995                return getIntentSenderLocked(type, packageName, callingUid, userId,
6996                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6997
6998            } catch (RemoteException e) {
6999                throw new SecurityException(e);
7000            }
7001        }
7002    }
7003
7004    IIntentSender getIntentSenderLocked(int type, String packageName,
7005            int callingUid, int userId, IBinder token, String resultWho,
7006            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7007            Bundle bOptions) {
7008        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7009        ActivityRecord activity = null;
7010        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7011            activity = ActivityRecord.isInStackLocked(token);
7012            if (activity == null) {
7013                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7014                return null;
7015            }
7016            if (activity.finishing) {
7017                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7018                return null;
7019            }
7020        }
7021
7022        // We're going to be splicing together extras before sending, so we're
7023        // okay poking into any contained extras.
7024        if (intents != null) {
7025            for (int i = 0; i < intents.length; i++) {
7026                intents[i].setDefusable(true);
7027            }
7028        }
7029        Bundle.setDefusable(bOptions, true);
7030
7031        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7032        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7033        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7034        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7035                |PendingIntent.FLAG_UPDATE_CURRENT);
7036
7037        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7038                type, packageName, activity, resultWho,
7039                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7040        WeakReference<PendingIntentRecord> ref;
7041        ref = mIntentSenderRecords.get(key);
7042        PendingIntentRecord rec = ref != null ? ref.get() : null;
7043        if (rec != null) {
7044            if (!cancelCurrent) {
7045                if (updateCurrent) {
7046                    if (rec.key.requestIntent != null) {
7047                        rec.key.requestIntent.replaceExtras(intents != null ?
7048                                intents[intents.length - 1] : null);
7049                    }
7050                    if (intents != null) {
7051                        intents[intents.length-1] = rec.key.requestIntent;
7052                        rec.key.allIntents = intents;
7053                        rec.key.allResolvedTypes = resolvedTypes;
7054                    } else {
7055                        rec.key.allIntents = null;
7056                        rec.key.allResolvedTypes = null;
7057                    }
7058                }
7059                return rec;
7060            }
7061            rec.canceled = true;
7062            mIntentSenderRecords.remove(key);
7063        }
7064        if (noCreate) {
7065            return rec;
7066        }
7067        rec = new PendingIntentRecord(this, key, callingUid);
7068        mIntentSenderRecords.put(key, rec.ref);
7069        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7070            if (activity.pendingResults == null) {
7071                activity.pendingResults
7072                        = new HashSet<WeakReference<PendingIntentRecord>>();
7073            }
7074            activity.pendingResults.add(rec.ref);
7075        }
7076        return rec;
7077    }
7078
7079    @Override
7080    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7081            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7082        if (target instanceof PendingIntentRecord) {
7083            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7084                    finishedReceiver, requiredPermission, options);
7085        } else {
7086            if (intent == null) {
7087                // Weird case: someone has given us their own custom IIntentSender, and now
7088                // they have someone else trying to send to it but of course this isn't
7089                // really a PendingIntent, so there is no base Intent, and the caller isn't
7090                // supplying an Intent... but we never want to dispatch a null Intent to
7091                // a receiver, so um...  let's make something up.
7092                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7093                intent = new Intent(Intent.ACTION_MAIN);
7094            }
7095            try {
7096                target.send(code, intent, resolvedType, null, requiredPermission, options);
7097            } catch (RemoteException e) {
7098            }
7099            // Platform code can rely on getting a result back when the send is done, but if
7100            // this intent sender is from outside of the system we can't rely on it doing that.
7101            // So instead we don't give it the result receiver, and instead just directly
7102            // report the finish immediately.
7103            if (finishedReceiver != null) {
7104                try {
7105                    finishedReceiver.performReceive(intent, 0,
7106                            null, null, false, false, UserHandle.getCallingUserId());
7107                } catch (RemoteException e) {
7108                }
7109            }
7110            return 0;
7111        }
7112    }
7113
7114    @Override
7115    public void cancelIntentSender(IIntentSender sender) {
7116        if (!(sender instanceof PendingIntentRecord)) {
7117            return;
7118        }
7119        synchronized(this) {
7120            PendingIntentRecord rec = (PendingIntentRecord)sender;
7121            try {
7122                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7123                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7124                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7125                    String msg = "Permission Denial: cancelIntentSender() from pid="
7126                        + Binder.getCallingPid()
7127                        + ", uid=" + Binder.getCallingUid()
7128                        + " is not allowed to cancel packges "
7129                        + rec.key.packageName;
7130                    Slog.w(TAG, msg);
7131                    throw new SecurityException(msg);
7132                }
7133            } catch (RemoteException e) {
7134                throw new SecurityException(e);
7135            }
7136            cancelIntentSenderLocked(rec, true);
7137        }
7138    }
7139
7140    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7141        rec.canceled = true;
7142        mIntentSenderRecords.remove(rec.key);
7143        if (cleanActivity && rec.key.activity != null) {
7144            rec.key.activity.pendingResults.remove(rec.ref);
7145        }
7146    }
7147
7148    @Override
7149    public String getPackageForIntentSender(IIntentSender pendingResult) {
7150        if (!(pendingResult instanceof PendingIntentRecord)) {
7151            return null;
7152        }
7153        try {
7154            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7155            return res.key.packageName;
7156        } catch (ClassCastException e) {
7157        }
7158        return null;
7159    }
7160
7161    @Override
7162    public int getUidForIntentSender(IIntentSender sender) {
7163        if (sender instanceof PendingIntentRecord) {
7164            try {
7165                PendingIntentRecord res = (PendingIntentRecord)sender;
7166                return res.uid;
7167            } catch (ClassCastException e) {
7168            }
7169        }
7170        return -1;
7171    }
7172
7173    @Override
7174    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7175        if (!(pendingResult instanceof PendingIntentRecord)) {
7176            return false;
7177        }
7178        try {
7179            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7180            if (res.key.allIntents == null) {
7181                return false;
7182            }
7183            for (int i=0; i<res.key.allIntents.length; i++) {
7184                Intent intent = res.key.allIntents[i];
7185                if (intent.getPackage() != null && intent.getComponent() != null) {
7186                    return false;
7187                }
7188            }
7189            return true;
7190        } catch (ClassCastException e) {
7191        }
7192        return false;
7193    }
7194
7195    @Override
7196    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7197        if (!(pendingResult instanceof PendingIntentRecord)) {
7198            return false;
7199        }
7200        try {
7201            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7202            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7203                return true;
7204            }
7205            return false;
7206        } catch (ClassCastException e) {
7207        }
7208        return false;
7209    }
7210
7211    @Override
7212    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7213        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7214                "getIntentForIntentSender()");
7215        if (!(pendingResult instanceof PendingIntentRecord)) {
7216            return null;
7217        }
7218        try {
7219            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7220            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7221        } catch (ClassCastException e) {
7222        }
7223        return null;
7224    }
7225
7226    @Override
7227    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7228        if (!(pendingResult instanceof PendingIntentRecord)) {
7229            return null;
7230        }
7231        try {
7232            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7233            synchronized (this) {
7234                return getTagForIntentSenderLocked(res, prefix);
7235            }
7236        } catch (ClassCastException e) {
7237        }
7238        return null;
7239    }
7240
7241    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7242        final Intent intent = res.key.requestIntent;
7243        if (intent != null) {
7244            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7245                    || res.lastTagPrefix.equals(prefix))) {
7246                return res.lastTag;
7247            }
7248            res.lastTagPrefix = prefix;
7249            final StringBuilder sb = new StringBuilder(128);
7250            if (prefix != null) {
7251                sb.append(prefix);
7252            }
7253            if (intent.getAction() != null) {
7254                sb.append(intent.getAction());
7255            } else if (intent.getComponent() != null) {
7256                intent.getComponent().appendShortString(sb);
7257            } else {
7258                sb.append("?");
7259            }
7260            return res.lastTag = sb.toString();
7261        }
7262        return null;
7263    }
7264
7265    @Override
7266    public void setProcessLimit(int max) {
7267        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7268                "setProcessLimit()");
7269        synchronized (this) {
7270            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7271            mProcessLimitOverride = max;
7272        }
7273        trimApplications();
7274    }
7275
7276    @Override
7277    public int getProcessLimit() {
7278        synchronized (this) {
7279            return mProcessLimitOverride;
7280        }
7281    }
7282
7283    void foregroundTokenDied(ForegroundToken token) {
7284        synchronized (ActivityManagerService.this) {
7285            synchronized (mPidsSelfLocked) {
7286                ForegroundToken cur
7287                    = mForegroundProcesses.get(token.pid);
7288                if (cur != token) {
7289                    return;
7290                }
7291                mForegroundProcesses.remove(token.pid);
7292                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7293                if (pr == null) {
7294                    return;
7295                }
7296                pr.forcingToForeground = null;
7297                updateProcessForegroundLocked(pr, false, false);
7298            }
7299            updateOomAdjLocked();
7300        }
7301    }
7302
7303    @Override
7304    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7305        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7306                "setProcessForeground()");
7307        synchronized(this) {
7308            boolean changed = false;
7309
7310            synchronized (mPidsSelfLocked) {
7311                ProcessRecord pr = mPidsSelfLocked.get(pid);
7312                if (pr == null && isForeground) {
7313                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7314                    return;
7315                }
7316                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7317                if (oldToken != null) {
7318                    oldToken.token.unlinkToDeath(oldToken, 0);
7319                    mForegroundProcesses.remove(pid);
7320                    if (pr != null) {
7321                        pr.forcingToForeground = null;
7322                    }
7323                    changed = true;
7324                }
7325                if (isForeground && token != null) {
7326                    ForegroundToken newToken = new ForegroundToken() {
7327                        @Override
7328                        public void binderDied() {
7329                            foregroundTokenDied(this);
7330                        }
7331                    };
7332                    newToken.pid = pid;
7333                    newToken.token = token;
7334                    try {
7335                        token.linkToDeath(newToken, 0);
7336                        mForegroundProcesses.put(pid, newToken);
7337                        pr.forcingToForeground = token;
7338                        changed = true;
7339                    } catch (RemoteException e) {
7340                        // If the process died while doing this, we will later
7341                        // do the cleanup with the process death link.
7342                    }
7343                }
7344            }
7345
7346            if (changed) {
7347                updateOomAdjLocked();
7348            }
7349        }
7350    }
7351
7352    @Override
7353    public boolean isAppForeground(int uid) throws RemoteException {
7354        synchronized (this) {
7355            UidRecord uidRec = mActiveUids.get(uid);
7356            if (uidRec == null || uidRec.idle) {
7357                return false;
7358            }
7359            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7360        }
7361    }
7362
7363    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7364    // be guarded by permission checking.
7365    int getUidState(int uid) {
7366        synchronized (this) {
7367            UidRecord uidRec = mActiveUids.get(uid);
7368            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7369        }
7370    }
7371
7372    @Override
7373    public boolean isInMultiWindowMode(IBinder token) {
7374        final long origId = Binder.clearCallingIdentity();
7375        try {
7376            synchronized(this) {
7377                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7378                if (r == null) {
7379                    return false;
7380                }
7381                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7382                return !r.task.mFullscreen;
7383            }
7384        } finally {
7385            Binder.restoreCallingIdentity(origId);
7386        }
7387    }
7388
7389    @Override
7390    public boolean isInPictureInPictureMode(IBinder token) {
7391        final long origId = Binder.clearCallingIdentity();
7392        try {
7393            synchronized(this) {
7394                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7395                if (stack == null) {
7396                    return false;
7397                }
7398                return stack.mStackId == PINNED_STACK_ID;
7399            }
7400        } finally {
7401            Binder.restoreCallingIdentity(origId);
7402        }
7403    }
7404
7405    @Override
7406    public void enterPictureInPictureMode(IBinder token) {
7407        final long origId = Binder.clearCallingIdentity();
7408        try {
7409            synchronized(this) {
7410                if (!mSupportsPictureInPicture) {
7411                    throw new IllegalStateException("enterPictureInPictureMode: "
7412                            + "Device doesn't support picture-in-picture mode.");
7413                }
7414
7415                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7416
7417                if (r == null) {
7418                    throw new IllegalStateException("enterPictureInPictureMode: "
7419                            + "Can't find activity for token=" + token);
7420                }
7421
7422                if (!r.supportsPictureInPicture()) {
7423                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7424                            + "Picture-In-Picture not supported for r=" + r);
7425                }
7426
7427                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7428                // current bounds.
7429                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7430                final Rect bounds = (pinnedStack != null)
7431                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7432
7433                mStackSupervisor.moveActivityToPinnedStackLocked(
7434                        r, "enterPictureInPictureMode", bounds);
7435            }
7436        } finally {
7437            Binder.restoreCallingIdentity(origId);
7438        }
7439    }
7440
7441    // =========================================================
7442    // PROCESS INFO
7443    // =========================================================
7444
7445    static class ProcessInfoService extends IProcessInfoService.Stub {
7446        final ActivityManagerService mActivityManagerService;
7447        ProcessInfoService(ActivityManagerService activityManagerService) {
7448            mActivityManagerService = activityManagerService;
7449        }
7450
7451        @Override
7452        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7453            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7454                    /*in*/ pids, /*out*/ states, null);
7455        }
7456
7457        @Override
7458        public void getProcessStatesAndOomScoresFromPids(
7459                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7460            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7461                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7462        }
7463    }
7464
7465    /**
7466     * For each PID in the given input array, write the current process state
7467     * for that process into the states array, or -1 to indicate that no
7468     * process with the given PID exists. If scores array is provided, write
7469     * the oom score for the process into the scores array, with INVALID_ADJ
7470     * indicating the PID doesn't exist.
7471     */
7472    public void getProcessStatesAndOomScoresForPIDs(
7473            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7474        if (scores != null) {
7475            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7476                    "getProcessStatesAndOomScoresForPIDs()");
7477        }
7478
7479        if (pids == null) {
7480            throw new NullPointerException("pids");
7481        } else if (states == null) {
7482            throw new NullPointerException("states");
7483        } else if (pids.length != states.length) {
7484            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7485        } else if (scores != null && pids.length != scores.length) {
7486            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7487        }
7488
7489        synchronized (mPidsSelfLocked) {
7490            for (int i = 0; i < pids.length; i++) {
7491                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7492                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7493                        pr.curProcState;
7494                if (scores != null) {
7495                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7496                }
7497            }
7498        }
7499    }
7500
7501    // =========================================================
7502    // PERMISSIONS
7503    // =========================================================
7504
7505    static class PermissionController extends IPermissionController.Stub {
7506        ActivityManagerService mActivityManagerService;
7507        PermissionController(ActivityManagerService activityManagerService) {
7508            mActivityManagerService = activityManagerService;
7509        }
7510
7511        @Override
7512        public boolean checkPermission(String permission, int pid, int uid) {
7513            return mActivityManagerService.checkPermission(permission, pid,
7514                    uid) == PackageManager.PERMISSION_GRANTED;
7515        }
7516
7517        @Override
7518        public String[] getPackagesForUid(int uid) {
7519            return mActivityManagerService.mContext.getPackageManager()
7520                    .getPackagesForUid(uid);
7521        }
7522
7523        @Override
7524        public boolean isRuntimePermission(String permission) {
7525            try {
7526                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7527                        .getPermissionInfo(permission, 0);
7528                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7529            } catch (NameNotFoundException nnfe) {
7530                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7531            }
7532            return false;
7533        }
7534    }
7535
7536    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7537        @Override
7538        public int checkComponentPermission(String permission, int pid, int uid,
7539                int owningUid, boolean exported) {
7540            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7541                    owningUid, exported);
7542        }
7543
7544        @Override
7545        public Object getAMSLock() {
7546            return ActivityManagerService.this;
7547        }
7548    }
7549
7550    /**
7551     * This can be called with or without the global lock held.
7552     */
7553    int checkComponentPermission(String permission, int pid, int uid,
7554            int owningUid, boolean exported) {
7555        if (pid == MY_PID) {
7556            return PackageManager.PERMISSION_GRANTED;
7557        }
7558        return ActivityManager.checkComponentPermission(permission, uid,
7559                owningUid, exported);
7560    }
7561
7562    /**
7563     * As the only public entry point for permissions checking, this method
7564     * can enforce the semantic that requesting a check on a null global
7565     * permission is automatically denied.  (Internally a null permission
7566     * string is used when calling {@link #checkComponentPermission} in cases
7567     * when only uid-based security is needed.)
7568     *
7569     * This can be called with or without the global lock held.
7570     */
7571    @Override
7572    public int checkPermission(String permission, int pid, int uid) {
7573        if (permission == null) {
7574            return PackageManager.PERMISSION_DENIED;
7575        }
7576        return checkComponentPermission(permission, pid, uid, -1, true);
7577    }
7578
7579    @Override
7580    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7581        if (permission == null) {
7582            return PackageManager.PERMISSION_DENIED;
7583        }
7584
7585        // We might be performing an operation on behalf of an indirect binder
7586        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7587        // client identity accordingly before proceeding.
7588        Identity tlsIdentity = sCallerIdentity.get();
7589        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7590            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7591                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7592            uid = tlsIdentity.uid;
7593            pid = tlsIdentity.pid;
7594        }
7595
7596        return checkComponentPermission(permission, pid, uid, -1, true);
7597    }
7598
7599    /**
7600     * Binder IPC calls go through the public entry point.
7601     * This can be called with or without the global lock held.
7602     */
7603    int checkCallingPermission(String permission) {
7604        return checkPermission(permission,
7605                Binder.getCallingPid(),
7606                UserHandle.getAppId(Binder.getCallingUid()));
7607    }
7608
7609    /**
7610     * This can be called with or without the global lock held.
7611     */
7612    void enforceCallingPermission(String permission, String func) {
7613        if (checkCallingPermission(permission)
7614                == PackageManager.PERMISSION_GRANTED) {
7615            return;
7616        }
7617
7618        String msg = "Permission Denial: " + func + " from pid="
7619                + Binder.getCallingPid()
7620                + ", uid=" + Binder.getCallingUid()
7621                + " requires " + permission;
7622        Slog.w(TAG, msg);
7623        throw new SecurityException(msg);
7624    }
7625
7626    /**
7627     * Determine if UID is holding permissions required to access {@link Uri} in
7628     * the given {@link ProviderInfo}. Final permission checking is always done
7629     * in {@link ContentProvider}.
7630     */
7631    private final boolean checkHoldingPermissionsLocked(
7632            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7633        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7634                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7635        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7636            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7637                    != PERMISSION_GRANTED) {
7638                return false;
7639            }
7640        }
7641        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7642    }
7643
7644    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7645            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7646        if (pi.applicationInfo.uid == uid) {
7647            return true;
7648        } else if (!pi.exported) {
7649            return false;
7650        }
7651
7652        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7653        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7654        try {
7655            // check if target holds top-level <provider> permissions
7656            if (!readMet && pi.readPermission != null && considerUidPermissions
7657                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7658                readMet = true;
7659            }
7660            if (!writeMet && pi.writePermission != null && considerUidPermissions
7661                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7662                writeMet = true;
7663            }
7664
7665            // track if unprotected read/write is allowed; any denied
7666            // <path-permission> below removes this ability
7667            boolean allowDefaultRead = pi.readPermission == null;
7668            boolean allowDefaultWrite = pi.writePermission == null;
7669
7670            // check if target holds any <path-permission> that match uri
7671            final PathPermission[] pps = pi.pathPermissions;
7672            if (pps != null) {
7673                final String path = grantUri.uri.getPath();
7674                int i = pps.length;
7675                while (i > 0 && (!readMet || !writeMet)) {
7676                    i--;
7677                    PathPermission pp = pps[i];
7678                    if (pp.match(path)) {
7679                        if (!readMet) {
7680                            final String pprperm = pp.getReadPermission();
7681                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7682                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7683                                    + ": match=" + pp.match(path)
7684                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7685                            if (pprperm != null) {
7686                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7687                                        == PERMISSION_GRANTED) {
7688                                    readMet = true;
7689                                } else {
7690                                    allowDefaultRead = false;
7691                                }
7692                            }
7693                        }
7694                        if (!writeMet) {
7695                            final String ppwperm = pp.getWritePermission();
7696                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7697                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7698                                    + ": match=" + pp.match(path)
7699                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7700                            if (ppwperm != null) {
7701                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7702                                        == PERMISSION_GRANTED) {
7703                                    writeMet = true;
7704                                } else {
7705                                    allowDefaultWrite = false;
7706                                }
7707                            }
7708                        }
7709                    }
7710                }
7711            }
7712
7713            // grant unprotected <provider> read/write, if not blocked by
7714            // <path-permission> above
7715            if (allowDefaultRead) readMet = true;
7716            if (allowDefaultWrite) writeMet = true;
7717
7718        } catch (RemoteException e) {
7719            return false;
7720        }
7721
7722        return readMet && writeMet;
7723    }
7724
7725    public int getAppStartMode(int uid, String packageName) {
7726        synchronized (this) {
7727            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7728        }
7729    }
7730
7731    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7732            boolean allowWhenForeground) {
7733        UidRecord uidRec = mActiveUids.get(uid);
7734        if (!mLenientBackgroundCheck) {
7735            if (!allowWhenForeground || uidRec == null
7736                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7737                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7738                        packageName) != AppOpsManager.MODE_ALLOWED) {
7739                    return ActivityManager.APP_START_MODE_DELAYED;
7740                }
7741            }
7742
7743        } else if (uidRec == null || uidRec.idle) {
7744            if (callingPid >= 0) {
7745                ProcessRecord proc;
7746                synchronized (mPidsSelfLocked) {
7747                    proc = mPidsSelfLocked.get(callingPid);
7748                }
7749                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7750                    // Whoever is instigating this is in the foreground, so we will allow it
7751                    // to go through.
7752                    return ActivityManager.APP_START_MODE_NORMAL;
7753                }
7754            }
7755            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7756                    != AppOpsManager.MODE_ALLOWED) {
7757                return ActivityManager.APP_START_MODE_DELAYED;
7758            }
7759        }
7760        return ActivityManager.APP_START_MODE_NORMAL;
7761    }
7762
7763    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7764        ProviderInfo pi = null;
7765        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7766        if (cpr != null) {
7767            pi = cpr.info;
7768        } else {
7769            try {
7770                pi = AppGlobals.getPackageManager().resolveContentProvider(
7771                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7772            } catch (RemoteException ex) {
7773            }
7774        }
7775        return pi;
7776    }
7777
7778    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7779        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7780        if (targetUris != null) {
7781            return targetUris.get(grantUri);
7782        }
7783        return null;
7784    }
7785
7786    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7787            String targetPkg, int targetUid, GrantUri grantUri) {
7788        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7789        if (targetUris == null) {
7790            targetUris = Maps.newArrayMap();
7791            mGrantedUriPermissions.put(targetUid, targetUris);
7792        }
7793
7794        UriPermission perm = targetUris.get(grantUri);
7795        if (perm == null) {
7796            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7797            targetUris.put(grantUri, perm);
7798        }
7799
7800        return perm;
7801    }
7802
7803    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7804            final int modeFlags) {
7805        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7806        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7807                : UriPermission.STRENGTH_OWNED;
7808
7809        // Root gets to do everything.
7810        if (uid == 0) {
7811            return true;
7812        }
7813
7814        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7815        if (perms == null) return false;
7816
7817        // First look for exact match
7818        final UriPermission exactPerm = perms.get(grantUri);
7819        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7820            return true;
7821        }
7822
7823        // No exact match, look for prefixes
7824        final int N = perms.size();
7825        for (int i = 0; i < N; i++) {
7826            final UriPermission perm = perms.valueAt(i);
7827            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7828                    && perm.getStrength(modeFlags) >= minStrength) {
7829                return true;
7830            }
7831        }
7832
7833        return false;
7834    }
7835
7836    /**
7837     * @param uri This uri must NOT contain an embedded userId.
7838     * @param userId The userId in which the uri is to be resolved.
7839     */
7840    @Override
7841    public int checkUriPermission(Uri uri, int pid, int uid,
7842            final int modeFlags, int userId, IBinder callerToken) {
7843        enforceNotIsolatedCaller("checkUriPermission");
7844
7845        // Another redirected-binder-call permissions check as in
7846        // {@link checkPermissionWithToken}.
7847        Identity tlsIdentity = sCallerIdentity.get();
7848        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7849            uid = tlsIdentity.uid;
7850            pid = tlsIdentity.pid;
7851        }
7852
7853        // Our own process gets to do everything.
7854        if (pid == MY_PID) {
7855            return PackageManager.PERMISSION_GRANTED;
7856        }
7857        synchronized (this) {
7858            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7859                    ? PackageManager.PERMISSION_GRANTED
7860                    : PackageManager.PERMISSION_DENIED;
7861        }
7862    }
7863
7864    /**
7865     * Check if the targetPkg can be granted permission to access uri by
7866     * the callingUid using the given modeFlags.  Throws a security exception
7867     * if callingUid is not allowed to do this.  Returns the uid of the target
7868     * if the URI permission grant should be performed; returns -1 if it is not
7869     * needed (for example targetPkg already has permission to access the URI).
7870     * If you already know the uid of the target, you can supply it in
7871     * lastTargetUid else set that to -1.
7872     */
7873    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7874            final int modeFlags, int lastTargetUid) {
7875        if (!Intent.isAccessUriMode(modeFlags)) {
7876            return -1;
7877        }
7878
7879        if (targetPkg != null) {
7880            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7881                    "Checking grant " + targetPkg + " permission to " + grantUri);
7882        }
7883
7884        final IPackageManager pm = AppGlobals.getPackageManager();
7885
7886        // If this is not a content: uri, we can't do anything with it.
7887        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7888            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7889                    "Can't grant URI permission for non-content URI: " + grantUri);
7890            return -1;
7891        }
7892
7893        final String authority = grantUri.uri.getAuthority();
7894        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7895        if (pi == null) {
7896            Slog.w(TAG, "No content provider found for permission check: " +
7897                    grantUri.uri.toSafeString());
7898            return -1;
7899        }
7900
7901        int targetUid = lastTargetUid;
7902        if (targetUid < 0 && targetPkg != null) {
7903            try {
7904                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7905                        UserHandle.getUserId(callingUid));
7906                if (targetUid < 0) {
7907                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7908                            "Can't grant URI permission no uid for: " + targetPkg);
7909                    return -1;
7910                }
7911            } catch (RemoteException ex) {
7912                return -1;
7913            }
7914        }
7915
7916        if (targetUid >= 0) {
7917            // First...  does the target actually need this permission?
7918            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7919                // No need to grant the target this permission.
7920                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7921                        "Target " + targetPkg + " already has full permission to " + grantUri);
7922                return -1;
7923            }
7924        } else {
7925            // First...  there is no target package, so can anyone access it?
7926            boolean allowed = pi.exported;
7927            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7928                if (pi.readPermission != null) {
7929                    allowed = false;
7930                }
7931            }
7932            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7933                if (pi.writePermission != null) {
7934                    allowed = false;
7935                }
7936            }
7937            if (allowed) {
7938                return -1;
7939            }
7940        }
7941
7942        /* There is a special cross user grant if:
7943         * - The target is on another user.
7944         * - Apps on the current user can access the uri without any uid permissions.
7945         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7946         * grant uri permissions.
7947         */
7948        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7949                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7950                modeFlags, false /*without considering the uid permissions*/);
7951
7952        // Second...  is the provider allowing granting of URI permissions?
7953        if (!specialCrossUserGrant) {
7954            if (!pi.grantUriPermissions) {
7955                throw new SecurityException("Provider " + pi.packageName
7956                        + "/" + pi.name
7957                        + " does not allow granting of Uri permissions (uri "
7958                        + grantUri + ")");
7959            }
7960            if (pi.uriPermissionPatterns != null) {
7961                final int N = pi.uriPermissionPatterns.length;
7962                boolean allowed = false;
7963                for (int i=0; i<N; i++) {
7964                    if (pi.uriPermissionPatterns[i] != null
7965                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7966                        allowed = true;
7967                        break;
7968                    }
7969                }
7970                if (!allowed) {
7971                    throw new SecurityException("Provider " + pi.packageName
7972                            + "/" + pi.name
7973                            + " does not allow granting of permission to path of Uri "
7974                            + grantUri);
7975                }
7976            }
7977        }
7978
7979        // Third...  does the caller itself have permission to access
7980        // this uri?
7981        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7982            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7983                // Require they hold a strong enough Uri permission
7984                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7985                    throw new SecurityException("Uid " + callingUid
7986                            + " does not have permission to uri " + grantUri);
7987                }
7988            }
7989        }
7990        return targetUid;
7991    }
7992
7993    /**
7994     * @param uri This uri must NOT contain an embedded userId.
7995     * @param userId The userId in which the uri is to be resolved.
7996     */
7997    @Override
7998    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7999            final int modeFlags, int userId) {
8000        enforceNotIsolatedCaller("checkGrantUriPermission");
8001        synchronized(this) {
8002            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8003                    new GrantUri(userId, uri, false), modeFlags, -1);
8004        }
8005    }
8006
8007    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8008            final int modeFlags, UriPermissionOwner owner) {
8009        if (!Intent.isAccessUriMode(modeFlags)) {
8010            return;
8011        }
8012
8013        // So here we are: the caller has the assumed permission
8014        // to the uri, and the target doesn't.  Let's now give this to
8015        // the target.
8016
8017        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8018                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8019
8020        final String authority = grantUri.uri.getAuthority();
8021        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8022        if (pi == null) {
8023            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8024            return;
8025        }
8026
8027        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8028            grantUri.prefix = true;
8029        }
8030        final UriPermission perm = findOrCreateUriPermissionLocked(
8031                pi.packageName, targetPkg, targetUid, grantUri);
8032        perm.grantModes(modeFlags, owner);
8033    }
8034
8035    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8036            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8037        if (targetPkg == null) {
8038            throw new NullPointerException("targetPkg");
8039        }
8040        int targetUid;
8041        final IPackageManager pm = AppGlobals.getPackageManager();
8042        try {
8043            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8044        } catch (RemoteException ex) {
8045            return;
8046        }
8047
8048        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8049                targetUid);
8050        if (targetUid < 0) {
8051            return;
8052        }
8053
8054        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8055                owner);
8056    }
8057
8058    static class NeededUriGrants extends ArrayList<GrantUri> {
8059        final String targetPkg;
8060        final int targetUid;
8061        final int flags;
8062
8063        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8064            this.targetPkg = targetPkg;
8065            this.targetUid = targetUid;
8066            this.flags = flags;
8067        }
8068    }
8069
8070    /**
8071     * Like checkGrantUriPermissionLocked, but takes an Intent.
8072     */
8073    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8074            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8075        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8076                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8077                + " clip=" + (intent != null ? intent.getClipData() : null)
8078                + " from " + intent + "; flags=0x"
8079                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8080
8081        if (targetPkg == null) {
8082            throw new NullPointerException("targetPkg");
8083        }
8084
8085        if (intent == null) {
8086            return null;
8087        }
8088        Uri data = intent.getData();
8089        ClipData clip = intent.getClipData();
8090        if (data == null && clip == null) {
8091            return null;
8092        }
8093        // Default userId for uris in the intent (if they don't specify it themselves)
8094        int contentUserHint = intent.getContentUserHint();
8095        if (contentUserHint == UserHandle.USER_CURRENT) {
8096            contentUserHint = UserHandle.getUserId(callingUid);
8097        }
8098        final IPackageManager pm = AppGlobals.getPackageManager();
8099        int targetUid;
8100        if (needed != null) {
8101            targetUid = needed.targetUid;
8102        } else {
8103            try {
8104                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8105                        targetUserId);
8106            } catch (RemoteException ex) {
8107                return null;
8108            }
8109            if (targetUid < 0) {
8110                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8111                        "Can't grant URI permission no uid for: " + targetPkg
8112                        + " on user " + targetUserId);
8113                return null;
8114            }
8115        }
8116        if (data != null) {
8117            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8118            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8119                    targetUid);
8120            if (targetUid > 0) {
8121                if (needed == null) {
8122                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8123                }
8124                needed.add(grantUri);
8125            }
8126        }
8127        if (clip != null) {
8128            for (int i=0; i<clip.getItemCount(); i++) {
8129                Uri uri = clip.getItemAt(i).getUri();
8130                if (uri != null) {
8131                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8132                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8133                            targetUid);
8134                    if (targetUid > 0) {
8135                        if (needed == null) {
8136                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8137                        }
8138                        needed.add(grantUri);
8139                    }
8140                } else {
8141                    Intent clipIntent = clip.getItemAt(i).getIntent();
8142                    if (clipIntent != null) {
8143                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8144                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8145                        if (newNeeded != null) {
8146                            needed = newNeeded;
8147                        }
8148                    }
8149                }
8150            }
8151        }
8152
8153        return needed;
8154    }
8155
8156    /**
8157     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8158     */
8159    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8160            UriPermissionOwner owner) {
8161        if (needed != null) {
8162            for (int i=0; i<needed.size(); i++) {
8163                GrantUri grantUri = needed.get(i);
8164                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8165                        grantUri, needed.flags, owner);
8166            }
8167        }
8168    }
8169
8170    void grantUriPermissionFromIntentLocked(int callingUid,
8171            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8172        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8173                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8174        if (needed == null) {
8175            return;
8176        }
8177
8178        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8179    }
8180
8181    /**
8182     * @param uri This uri must NOT contain an embedded userId.
8183     * @param userId The userId in which the uri is to be resolved.
8184     */
8185    @Override
8186    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8187            final int modeFlags, int userId) {
8188        enforceNotIsolatedCaller("grantUriPermission");
8189        GrantUri grantUri = new GrantUri(userId, uri, false);
8190        synchronized(this) {
8191            final ProcessRecord r = getRecordForAppLocked(caller);
8192            if (r == null) {
8193                throw new SecurityException("Unable to find app for caller "
8194                        + caller
8195                        + " when granting permission to uri " + grantUri);
8196            }
8197            if (targetPkg == null) {
8198                throw new IllegalArgumentException("null target");
8199            }
8200            if (grantUri == null) {
8201                throw new IllegalArgumentException("null uri");
8202            }
8203
8204            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8205                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8206                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8207                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8208
8209            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8210                    UserHandle.getUserId(r.uid));
8211        }
8212    }
8213
8214    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8215        if (perm.modeFlags == 0) {
8216            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8217                    perm.targetUid);
8218            if (perms != null) {
8219                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8220                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8221
8222                perms.remove(perm.uri);
8223                if (perms.isEmpty()) {
8224                    mGrantedUriPermissions.remove(perm.targetUid);
8225                }
8226            }
8227        }
8228    }
8229
8230    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8231        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8232                "Revoking all granted permissions to " + grantUri);
8233
8234        final IPackageManager pm = AppGlobals.getPackageManager();
8235        final String authority = grantUri.uri.getAuthority();
8236        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8237        if (pi == null) {
8238            Slog.w(TAG, "No content provider found for permission revoke: "
8239                    + grantUri.toSafeString());
8240            return;
8241        }
8242
8243        // Does the caller have this permission on the URI?
8244        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8245            // If they don't have direct access to the URI, then revoke any
8246            // ownerless URI permissions that have been granted to them.
8247            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8248            if (perms != null) {
8249                boolean persistChanged = false;
8250                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8251                    final UriPermission perm = it.next();
8252                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8253                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8254                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8255                                "Revoking non-owned " + perm.targetUid
8256                                + " permission to " + perm.uri);
8257                        persistChanged |= perm.revokeModes(
8258                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8259                        if (perm.modeFlags == 0) {
8260                            it.remove();
8261                        }
8262                    }
8263                }
8264                if (perms.isEmpty()) {
8265                    mGrantedUriPermissions.remove(callingUid);
8266                }
8267                if (persistChanged) {
8268                    schedulePersistUriGrants();
8269                }
8270            }
8271            return;
8272        }
8273
8274        boolean persistChanged = false;
8275
8276        // Go through all of the permissions and remove any that match.
8277        int N = mGrantedUriPermissions.size();
8278        for (int i = 0; i < N; i++) {
8279            final int targetUid = mGrantedUriPermissions.keyAt(i);
8280            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8281
8282            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8283                final UriPermission perm = it.next();
8284                if (perm.uri.sourceUserId == grantUri.sourceUserId
8285                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8286                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8287                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8288                    persistChanged |= perm.revokeModes(
8289                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8290                    if (perm.modeFlags == 0) {
8291                        it.remove();
8292                    }
8293                }
8294            }
8295
8296            if (perms.isEmpty()) {
8297                mGrantedUriPermissions.remove(targetUid);
8298                N--;
8299                i--;
8300            }
8301        }
8302
8303        if (persistChanged) {
8304            schedulePersistUriGrants();
8305        }
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 revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8314            int userId) {
8315        enforceNotIsolatedCaller("revokeUriPermission");
8316        synchronized(this) {
8317            final ProcessRecord r = getRecordForAppLocked(caller);
8318            if (r == null) {
8319                throw new SecurityException("Unable to find app for caller "
8320                        + caller
8321                        + " when revoking permission to uri " + uri);
8322            }
8323            if (uri == null) {
8324                Slog.w(TAG, "revokeUriPermission: null uri");
8325                return;
8326            }
8327
8328            if (!Intent.isAccessUriMode(modeFlags)) {
8329                return;
8330            }
8331
8332            final String authority = uri.getAuthority();
8333            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8334            if (pi == null) {
8335                Slog.w(TAG, "No content provider found for permission revoke: "
8336                        + uri.toSafeString());
8337                return;
8338            }
8339
8340            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8341        }
8342    }
8343
8344    /**
8345     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8346     * given package.
8347     *
8348     * @param packageName Package name to match, or {@code null} to apply to all
8349     *            packages.
8350     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8351     *            to all users.
8352     * @param persistable If persistable grants should be removed.
8353     */
8354    private void removeUriPermissionsForPackageLocked(
8355            String packageName, int userHandle, boolean persistable) {
8356        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8357            throw new IllegalArgumentException("Must narrow by either package or user");
8358        }
8359
8360        boolean persistChanged = false;
8361
8362        int N = mGrantedUriPermissions.size();
8363        for (int i = 0; i < N; i++) {
8364            final int targetUid = mGrantedUriPermissions.keyAt(i);
8365            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8366
8367            // Only inspect grants matching user
8368            if (userHandle == UserHandle.USER_ALL
8369                    || userHandle == UserHandle.getUserId(targetUid)) {
8370                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8371                    final UriPermission perm = it.next();
8372
8373                    // Only inspect grants matching package
8374                    if (packageName == null || perm.sourcePkg.equals(packageName)
8375                            || perm.targetPkg.equals(packageName)) {
8376                        persistChanged |= perm.revokeModes(persistable
8377                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8378
8379                        // Only remove when no modes remain; any persisted grants
8380                        // will keep this alive.
8381                        if (perm.modeFlags == 0) {
8382                            it.remove();
8383                        }
8384                    }
8385                }
8386
8387                if (perms.isEmpty()) {
8388                    mGrantedUriPermissions.remove(targetUid);
8389                    N--;
8390                    i--;
8391                }
8392            }
8393        }
8394
8395        if (persistChanged) {
8396            schedulePersistUriGrants();
8397        }
8398    }
8399
8400    @Override
8401    public IBinder newUriPermissionOwner(String name) {
8402        enforceNotIsolatedCaller("newUriPermissionOwner");
8403        synchronized(this) {
8404            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8405            return owner.getExternalTokenLocked();
8406        }
8407    }
8408
8409    @Override
8410    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8411        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8412        synchronized(this) {
8413            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8414            if (r == null) {
8415                throw new IllegalArgumentException("Activity does not exist; token="
8416                        + activityToken);
8417            }
8418            return r.getUriPermissionsLocked().getExternalTokenLocked();
8419        }
8420    }
8421    /**
8422     * @param uri This uri must NOT contain an embedded userId.
8423     * @param sourceUserId The userId in which the uri is to be resolved.
8424     * @param targetUserId The userId of the app that receives the grant.
8425     */
8426    @Override
8427    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8428            final int modeFlags, int sourceUserId, int targetUserId) {
8429        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8430                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8431                "grantUriPermissionFromOwner", null);
8432        synchronized(this) {
8433            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8434            if (owner == null) {
8435                throw new IllegalArgumentException("Unknown owner: " + token);
8436            }
8437            if (fromUid != Binder.getCallingUid()) {
8438                if (Binder.getCallingUid() != Process.myUid()) {
8439                    // Only system code can grant URI permissions on behalf
8440                    // of other users.
8441                    throw new SecurityException("nice try");
8442                }
8443            }
8444            if (targetPkg == null) {
8445                throw new IllegalArgumentException("null target");
8446            }
8447            if (uri == null) {
8448                throw new IllegalArgumentException("null uri");
8449            }
8450
8451            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8452                    modeFlags, owner, targetUserId);
8453        }
8454    }
8455
8456    /**
8457     * @param uri This uri must NOT contain an embedded userId.
8458     * @param userId The userId in which the uri is to be resolved.
8459     */
8460    @Override
8461    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8462        synchronized(this) {
8463            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8464            if (owner == null) {
8465                throw new IllegalArgumentException("Unknown owner: " + token);
8466            }
8467
8468            if (uri == null) {
8469                owner.removeUriPermissionsLocked(mode);
8470            } else {
8471                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8472            }
8473        }
8474    }
8475
8476    private void schedulePersistUriGrants() {
8477        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8478            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8479                    10 * DateUtils.SECOND_IN_MILLIS);
8480        }
8481    }
8482
8483    private void writeGrantedUriPermissions() {
8484        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8485
8486        // Snapshot permissions so we can persist without lock
8487        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8488        synchronized (this) {
8489            final int size = mGrantedUriPermissions.size();
8490            for (int i = 0; i < size; i++) {
8491                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8492                for (UriPermission perm : perms.values()) {
8493                    if (perm.persistedModeFlags != 0) {
8494                        persist.add(perm.snapshot());
8495                    }
8496                }
8497            }
8498        }
8499
8500        FileOutputStream fos = null;
8501        try {
8502            fos = mGrantFile.startWrite();
8503
8504            XmlSerializer out = new FastXmlSerializer();
8505            out.setOutput(fos, StandardCharsets.UTF_8.name());
8506            out.startDocument(null, true);
8507            out.startTag(null, TAG_URI_GRANTS);
8508            for (UriPermission.Snapshot perm : persist) {
8509                out.startTag(null, TAG_URI_GRANT);
8510                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8511                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8512                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8513                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8514                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8515                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8516                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8517                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8518                out.endTag(null, TAG_URI_GRANT);
8519            }
8520            out.endTag(null, TAG_URI_GRANTS);
8521            out.endDocument();
8522
8523            mGrantFile.finishWrite(fos);
8524        } catch (IOException e) {
8525            if (fos != null) {
8526                mGrantFile.failWrite(fos);
8527            }
8528        }
8529    }
8530
8531    private void readGrantedUriPermissionsLocked() {
8532        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8533
8534        final long now = System.currentTimeMillis();
8535
8536        FileInputStream fis = null;
8537        try {
8538            fis = mGrantFile.openRead();
8539            final XmlPullParser in = Xml.newPullParser();
8540            in.setInput(fis, StandardCharsets.UTF_8.name());
8541
8542            int type;
8543            while ((type = in.next()) != END_DOCUMENT) {
8544                final String tag = in.getName();
8545                if (type == START_TAG) {
8546                    if (TAG_URI_GRANT.equals(tag)) {
8547                        final int sourceUserId;
8548                        final int targetUserId;
8549                        final int userHandle = readIntAttribute(in,
8550                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8551                        if (userHandle != UserHandle.USER_NULL) {
8552                            // For backwards compatibility.
8553                            sourceUserId = userHandle;
8554                            targetUserId = userHandle;
8555                        } else {
8556                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8557                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8558                        }
8559                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8560                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8561                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8562                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8563                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8564                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8565
8566                        // Sanity check that provider still belongs to source package
8567                        final ProviderInfo pi = getProviderInfoLocked(
8568                                uri.getAuthority(), sourceUserId);
8569                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8570                            int targetUid = -1;
8571                            try {
8572                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8573                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8574                            } catch (RemoteException e) {
8575                            }
8576                            if (targetUid != -1) {
8577                                final UriPermission perm = findOrCreateUriPermissionLocked(
8578                                        sourcePkg, targetPkg, targetUid,
8579                                        new GrantUri(sourceUserId, uri, prefix));
8580                                perm.initPersistedModes(modeFlags, createdTime);
8581                            }
8582                        } else {
8583                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8584                                    + " but instead found " + pi);
8585                        }
8586                    }
8587                }
8588            }
8589        } catch (FileNotFoundException e) {
8590            // Missing grants is okay
8591        } catch (IOException e) {
8592            Slog.wtf(TAG, "Failed reading Uri grants", e);
8593        } catch (XmlPullParserException e) {
8594            Slog.wtf(TAG, "Failed reading Uri grants", e);
8595        } finally {
8596            IoUtils.closeQuietly(fis);
8597        }
8598    }
8599
8600    /**
8601     * @param uri This uri must NOT contain an embedded userId.
8602     * @param userId The userId in which the uri is to be resolved.
8603     */
8604    @Override
8605    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8606        enforceNotIsolatedCaller("takePersistableUriPermission");
8607
8608        Preconditions.checkFlagsArgument(modeFlags,
8609                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8610
8611        synchronized (this) {
8612            final int callingUid = Binder.getCallingUid();
8613            boolean persistChanged = false;
8614            GrantUri grantUri = new GrantUri(userId, uri, false);
8615
8616            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8617                    new GrantUri(userId, uri, false));
8618            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8619                    new GrantUri(userId, uri, true));
8620
8621            final boolean exactValid = (exactPerm != null)
8622                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8623            final boolean prefixValid = (prefixPerm != null)
8624                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8625
8626            if (!(exactValid || prefixValid)) {
8627                throw new SecurityException("No persistable permission grants found for UID "
8628                        + callingUid + " and Uri " + grantUri.toSafeString());
8629            }
8630
8631            if (exactValid) {
8632                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8633            }
8634            if (prefixValid) {
8635                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8636            }
8637
8638            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8639
8640            if (persistChanged) {
8641                schedulePersistUriGrants();
8642            }
8643        }
8644    }
8645
8646    /**
8647     * @param uri This uri must NOT contain an embedded userId.
8648     * @param userId The userId in which the uri is to be resolved.
8649     */
8650    @Override
8651    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8652        enforceNotIsolatedCaller("releasePersistableUriPermission");
8653
8654        Preconditions.checkFlagsArgument(modeFlags,
8655                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8656
8657        synchronized (this) {
8658            final int callingUid = Binder.getCallingUid();
8659            boolean persistChanged = false;
8660
8661            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8662                    new GrantUri(userId, uri, false));
8663            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8664                    new GrantUri(userId, uri, true));
8665            if (exactPerm == null && prefixPerm == null) {
8666                throw new SecurityException("No permission grants found for UID " + callingUid
8667                        + " and Uri " + uri.toSafeString());
8668            }
8669
8670            if (exactPerm != null) {
8671                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8672                removeUriPermissionIfNeededLocked(exactPerm);
8673            }
8674            if (prefixPerm != null) {
8675                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8676                removeUriPermissionIfNeededLocked(prefixPerm);
8677            }
8678
8679            if (persistChanged) {
8680                schedulePersistUriGrants();
8681            }
8682        }
8683    }
8684
8685    /**
8686     * Prune any older {@link UriPermission} for the given UID until outstanding
8687     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8688     *
8689     * @return if any mutations occured that require persisting.
8690     */
8691    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8692        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8693        if (perms == null) return false;
8694        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8695
8696        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8697        for (UriPermission perm : perms.values()) {
8698            if (perm.persistedModeFlags != 0) {
8699                persisted.add(perm);
8700            }
8701        }
8702
8703        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8704        if (trimCount <= 0) return false;
8705
8706        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8707        for (int i = 0; i < trimCount; i++) {
8708            final UriPermission perm = persisted.get(i);
8709
8710            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8711                    "Trimming grant created at " + perm.persistedCreateTime);
8712
8713            perm.releasePersistableModes(~0);
8714            removeUriPermissionIfNeededLocked(perm);
8715        }
8716
8717        return true;
8718    }
8719
8720    @Override
8721    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8722            String packageName, boolean incoming) {
8723        enforceNotIsolatedCaller("getPersistedUriPermissions");
8724        Preconditions.checkNotNull(packageName, "packageName");
8725
8726        final int callingUid = Binder.getCallingUid();
8727        final IPackageManager pm = AppGlobals.getPackageManager();
8728        try {
8729            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8730                    UserHandle.getUserId(callingUid));
8731            if (packageUid != callingUid) {
8732                throw new SecurityException(
8733                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8734            }
8735        } catch (RemoteException e) {
8736            throw new SecurityException("Failed to verify package name ownership");
8737        }
8738
8739        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8740        synchronized (this) {
8741            if (incoming) {
8742                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8743                        callingUid);
8744                if (perms == null) {
8745                    Slog.w(TAG, "No permission grants found for " + packageName);
8746                } else {
8747                    for (UriPermission perm : perms.values()) {
8748                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8749                            result.add(perm.buildPersistedPublicApiObject());
8750                        }
8751                    }
8752                }
8753            } else {
8754                final int size = mGrantedUriPermissions.size();
8755                for (int i = 0; i < size; i++) {
8756                    final ArrayMap<GrantUri, UriPermission> perms =
8757                            mGrantedUriPermissions.valueAt(i);
8758                    for (UriPermission perm : perms.values()) {
8759                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8760                            result.add(perm.buildPersistedPublicApiObject());
8761                        }
8762                    }
8763                }
8764            }
8765        }
8766        return new ParceledListSlice<android.content.UriPermission>(result);
8767    }
8768
8769    @Override
8770    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8771            String packageName, int userId) {
8772        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8773                "getGrantedUriPermissions");
8774
8775        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8776        synchronized (this) {
8777            final int size = mGrantedUriPermissions.size();
8778            for (int i = 0; i < size; i++) {
8779                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8780                for (UriPermission perm : perms.values()) {
8781                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8782                            && perm.persistedModeFlags != 0) {
8783                        result.add(perm.buildPersistedPublicApiObject());
8784                    }
8785                }
8786            }
8787        }
8788        return new ParceledListSlice<android.content.UriPermission>(result);
8789    }
8790
8791    @Override
8792    public void clearGrantedUriPermissions(String packageName, int userId) {
8793        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8794                "clearGrantedUriPermissions");
8795        removeUriPermissionsForPackageLocked(packageName, userId, true);
8796    }
8797
8798    @Override
8799    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8800        synchronized (this) {
8801            ProcessRecord app =
8802                who != null ? getRecordForAppLocked(who) : null;
8803            if (app == null) return;
8804
8805            Message msg = Message.obtain();
8806            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8807            msg.obj = app;
8808            msg.arg1 = waiting ? 1 : 0;
8809            mUiHandler.sendMessage(msg);
8810        }
8811    }
8812
8813    @Override
8814    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8815        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8816        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8817        outInfo.availMem = Process.getFreeMemory();
8818        outInfo.totalMem = Process.getTotalMemory();
8819        outInfo.threshold = homeAppMem;
8820        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8821        outInfo.hiddenAppThreshold = cachedAppMem;
8822        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8823                ProcessList.SERVICE_ADJ);
8824        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8825                ProcessList.VISIBLE_APP_ADJ);
8826        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8827                ProcessList.FOREGROUND_APP_ADJ);
8828    }
8829
8830    // =========================================================
8831    // TASK MANAGEMENT
8832    // =========================================================
8833
8834    @Override
8835    public List<IAppTask> getAppTasks(String callingPackage) {
8836        int callingUid = Binder.getCallingUid();
8837        long ident = Binder.clearCallingIdentity();
8838
8839        synchronized(this) {
8840            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8841            try {
8842                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8843
8844                final int N = mRecentTasks.size();
8845                for (int i = 0; i < N; i++) {
8846                    TaskRecord tr = mRecentTasks.get(i);
8847                    // Skip tasks that do not match the caller.  We don't need to verify
8848                    // callingPackage, because we are also limiting to callingUid and know
8849                    // that will limit to the correct security sandbox.
8850                    if (tr.effectiveUid != callingUid) {
8851                        continue;
8852                    }
8853                    Intent intent = tr.getBaseIntent();
8854                    if (intent == null ||
8855                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8856                        continue;
8857                    }
8858                    ActivityManager.RecentTaskInfo taskInfo =
8859                            createRecentTaskInfoFromTaskRecord(tr);
8860                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8861                    list.add(taskImpl);
8862                }
8863            } finally {
8864                Binder.restoreCallingIdentity(ident);
8865            }
8866            return list;
8867        }
8868    }
8869
8870    @Override
8871    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8872        final int callingUid = Binder.getCallingUid();
8873        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8874
8875        synchronized(this) {
8876            if (DEBUG_ALL) Slog.v(
8877                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8878
8879            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8880                    callingUid);
8881
8882            // TODO: Improve with MRU list from all ActivityStacks.
8883            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8884        }
8885
8886        return list;
8887    }
8888
8889    /**
8890     * Creates a new RecentTaskInfo from a TaskRecord.
8891     */
8892    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8893        // Update the task description to reflect any changes in the task stack
8894        tr.updateTaskDescription();
8895
8896        // Compose the recent task info
8897        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8898        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8899        rti.persistentId = tr.taskId;
8900        rti.baseIntent = new Intent(tr.getBaseIntent());
8901        rti.origActivity = tr.origActivity;
8902        rti.realActivity = tr.realActivity;
8903        rti.description = tr.lastDescription;
8904        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8905        rti.userId = tr.userId;
8906        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8907        rti.firstActiveTime = tr.firstActiveTime;
8908        rti.lastActiveTime = tr.lastActiveTime;
8909        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8910        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8911        rti.numActivities = 0;
8912        if (tr.mBounds != null) {
8913            rti.bounds = new Rect(tr.mBounds);
8914        }
8915        rti.isDockable = tr.canGoInDockedStack();
8916        rti.resizeMode = tr.mResizeMode;
8917
8918        ActivityRecord base = null;
8919        ActivityRecord top = null;
8920        ActivityRecord tmp;
8921
8922        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8923            tmp = tr.mActivities.get(i);
8924            if (tmp.finishing) {
8925                continue;
8926            }
8927            base = tmp;
8928            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8929                top = base;
8930            }
8931            rti.numActivities++;
8932        }
8933
8934        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8935        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8936
8937        return rti;
8938    }
8939
8940    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8941        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8942                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8943        if (!allowed) {
8944            if (checkPermission(android.Manifest.permission.GET_TASKS,
8945                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8946                // Temporary compatibility: some existing apps on the system image may
8947                // still be requesting the old permission and not switched to the new
8948                // one; if so, we'll still allow them full access.  This means we need
8949                // to see if they are holding the old permission and are a system app.
8950                try {
8951                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8952                        allowed = true;
8953                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8954                                + " is using old GET_TASKS but privileged; allowing");
8955                    }
8956                } catch (RemoteException e) {
8957                }
8958            }
8959        }
8960        if (!allowed) {
8961            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8962                    + " does not hold REAL_GET_TASKS; limiting output");
8963        }
8964        return allowed;
8965    }
8966
8967    @Override
8968    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8969        final int callingUid = Binder.getCallingUid();
8970        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8971                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8972
8973        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8974        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8975        synchronized (this) {
8976            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8977                    callingUid);
8978            final boolean detailed = checkCallingPermission(
8979                    android.Manifest.permission.GET_DETAILED_TASKS)
8980                    == PackageManager.PERMISSION_GRANTED;
8981
8982            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8983                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8984                return Collections.emptyList();
8985            }
8986            mRecentTasks.loadUserRecentsLocked(userId);
8987
8988            final int recentsCount = mRecentTasks.size();
8989            ArrayList<ActivityManager.RecentTaskInfo> res =
8990                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8991
8992            final Set<Integer> includedUsers;
8993            if (includeProfiles) {
8994                includedUsers = mUserController.getProfileIds(userId);
8995            } else {
8996                includedUsers = new HashSet<>();
8997            }
8998            includedUsers.add(Integer.valueOf(userId));
8999
9000            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9001                TaskRecord tr = mRecentTasks.get(i);
9002                // Only add calling user or related users recent tasks
9003                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9004                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9005                    continue;
9006                }
9007
9008                if (tr.realActivitySuspended) {
9009                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9010                    continue;
9011                }
9012
9013                // Return the entry if desired by the caller.  We always return
9014                // the first entry, because callers always expect this to be the
9015                // foreground app.  We may filter others if the caller has
9016                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9017                // we should exclude the entry.
9018
9019                if (i == 0
9020                        || withExcluded
9021                        || (tr.intent == null)
9022                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9023                                == 0)) {
9024                    if (!allowed) {
9025                        // If the caller doesn't have the GET_TASKS permission, then only
9026                        // allow them to see a small subset of tasks -- their own and home.
9027                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9028                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9029                            continue;
9030                        }
9031                    }
9032                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9033                        if (tr.stack != null && tr.stack.isHomeStack()) {
9034                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9035                                    "Skipping, home stack task: " + tr);
9036                            continue;
9037                        }
9038                    }
9039                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9040                        final ActivityStack stack = tr.stack;
9041                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9042                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9043                                    "Skipping, top task in docked stack: " + tr);
9044                            continue;
9045                        }
9046                    }
9047                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9048                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9049                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9050                                    "Skipping, pinned stack task: " + tr);
9051                            continue;
9052                        }
9053                    }
9054                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9055                        // Don't include auto remove tasks that are finished or finishing.
9056                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9057                                "Skipping, auto-remove without activity: " + tr);
9058                        continue;
9059                    }
9060                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9061                            && !tr.isAvailable) {
9062                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9063                                "Skipping, unavail real act: " + tr);
9064                        continue;
9065                    }
9066
9067                    if (!tr.mUserSetupComplete) {
9068                        // Don't include task launched while user is not done setting-up.
9069                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9070                                "Skipping, user setup not complete: " + tr);
9071                        continue;
9072                    }
9073
9074                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9075                    if (!detailed) {
9076                        rti.baseIntent.replaceExtras((Bundle)null);
9077                    }
9078
9079                    res.add(rti);
9080                    maxNum--;
9081                }
9082            }
9083            return res;
9084        }
9085    }
9086
9087    @Override
9088    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9089        synchronized (this) {
9090            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9091                    "getTaskThumbnail()");
9092            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9093                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9094            if (tr != null) {
9095                return tr.getTaskThumbnailLocked();
9096            }
9097        }
9098        return null;
9099    }
9100
9101    @Override
9102    public int addAppTask(IBinder activityToken, Intent intent,
9103            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9104        final int callingUid = Binder.getCallingUid();
9105        final long callingIdent = Binder.clearCallingIdentity();
9106
9107        try {
9108            synchronized (this) {
9109                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9110                if (r == null) {
9111                    throw new IllegalArgumentException("Activity does not exist; token="
9112                            + activityToken);
9113                }
9114                ComponentName comp = intent.getComponent();
9115                if (comp == null) {
9116                    throw new IllegalArgumentException("Intent " + intent
9117                            + " must specify explicit component");
9118                }
9119                if (thumbnail.getWidth() != mThumbnailWidth
9120                        || thumbnail.getHeight() != mThumbnailHeight) {
9121                    throw new IllegalArgumentException("Bad thumbnail size: got "
9122                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9123                            + mThumbnailWidth + "x" + mThumbnailHeight);
9124                }
9125                if (intent.getSelector() != null) {
9126                    intent.setSelector(null);
9127                }
9128                if (intent.getSourceBounds() != null) {
9129                    intent.setSourceBounds(null);
9130                }
9131                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9132                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9133                        // The caller has added this as an auto-remove task...  that makes no
9134                        // sense, so turn off auto-remove.
9135                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9136                    }
9137                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9138                    // Must be a new task.
9139                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9140                }
9141                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9142                    mLastAddedTaskActivity = null;
9143                }
9144                ActivityInfo ainfo = mLastAddedTaskActivity;
9145                if (ainfo == null) {
9146                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9147                            comp, 0, UserHandle.getUserId(callingUid));
9148                    if (ainfo.applicationInfo.uid != callingUid) {
9149                        throw new SecurityException(
9150                                "Can't add task for another application: target uid="
9151                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9152                    }
9153                }
9154
9155                // Use the full screen as the context for the task thumbnail
9156                final Point displaySize = new Point();
9157                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9158                r.task.stack.getDisplaySize(displaySize);
9159                thumbnailInfo.taskWidth = displaySize.x;
9160                thumbnailInfo.taskHeight = displaySize.y;
9161                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9162
9163                TaskRecord task = new TaskRecord(this,
9164                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9165                        ainfo, intent, description, thumbnailInfo);
9166
9167                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9168                if (trimIdx >= 0) {
9169                    // If this would have caused a trim, then we'll abort because that
9170                    // means it would be added at the end of the list but then just removed.
9171                    return INVALID_TASK_ID;
9172                }
9173
9174                final int N = mRecentTasks.size();
9175                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9176                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9177                    tr.removedFromRecents();
9178                }
9179
9180                task.inRecents = true;
9181                mRecentTasks.add(task);
9182                r.task.stack.addTask(task, false, "addAppTask");
9183
9184                task.setLastThumbnailLocked(thumbnail);
9185                task.freeLastThumbnail();
9186
9187                return task.taskId;
9188            }
9189        } finally {
9190            Binder.restoreCallingIdentity(callingIdent);
9191        }
9192    }
9193
9194    @Override
9195    public Point getAppTaskThumbnailSize() {
9196        synchronized (this) {
9197            return new Point(mThumbnailWidth,  mThumbnailHeight);
9198        }
9199    }
9200
9201    @Override
9202    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9203        synchronized (this) {
9204            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9205            if (r != null) {
9206                r.setTaskDescription(td);
9207                r.task.updateTaskDescription();
9208            }
9209        }
9210    }
9211
9212    @Override
9213    public void setTaskResizeable(int taskId, int resizeableMode) {
9214        synchronized (this) {
9215            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9216                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9217            if (task == null) {
9218                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9219                return;
9220            }
9221            if (task.mResizeMode != resizeableMode) {
9222                task.mResizeMode = resizeableMode;
9223                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9224                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9225                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9226            }
9227        }
9228    }
9229
9230    @Override
9231    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9232        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9233        long ident = Binder.clearCallingIdentity();
9234        try {
9235            synchronized (this) {
9236                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9237                if (task == null) {
9238                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9239                    return;
9240                }
9241                int stackId = task.stack.mStackId;
9242                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9243                // in crop windows resize mode or if the task size is affected by the docked stack
9244                // changing size. No need to update configuration.
9245                if (bounds != null && task.inCropWindowsResizeMode()
9246                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9247                    mWindowManager.scrollTask(task.taskId, bounds);
9248                    return;
9249                }
9250
9251                // Place the task in the right stack if it isn't there already based on
9252                // the requested bounds.
9253                // The stack transition logic is:
9254                // - a null bounds on a freeform task moves that task to fullscreen
9255                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9256                //   that task to freeform
9257                // - otherwise the task is not moved
9258                if (!StackId.isTaskResizeAllowed(stackId)) {
9259                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9260                }
9261                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9262                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9263                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9264                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9265                }
9266                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9267                if (stackId != task.stack.mStackId) {
9268                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9269                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9270                    preserveWindow = false;
9271                }
9272
9273                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9274                        false /* deferResume */);
9275            }
9276        } finally {
9277            Binder.restoreCallingIdentity(ident);
9278        }
9279    }
9280
9281    @Override
9282    public Rect getTaskBounds(int taskId) {
9283        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9284        long ident = Binder.clearCallingIdentity();
9285        Rect rect = new Rect();
9286        try {
9287            synchronized (this) {
9288                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9289                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9290                if (task == null) {
9291                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9292                    return rect;
9293                }
9294                if (task.stack != null) {
9295                    // Return the bounds from window manager since it will be adjusted for various
9296                    // things like the presense of a docked stack for tasks that aren't resizeable.
9297                    mWindowManager.getTaskBounds(task.taskId, rect);
9298                } else {
9299                    // Task isn't in window manager yet since it isn't associated with a stack.
9300                    // Return the persist value from activity manager
9301                    if (task.mBounds != null) {
9302                        rect.set(task.mBounds);
9303                    } else if (task.mLastNonFullscreenBounds != null) {
9304                        rect.set(task.mLastNonFullscreenBounds);
9305                    }
9306                }
9307            }
9308        } finally {
9309            Binder.restoreCallingIdentity(ident);
9310        }
9311        return rect;
9312    }
9313
9314    @Override
9315    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9316        if (userId != UserHandle.getCallingUserId()) {
9317            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9318                    "getTaskDescriptionIcon");
9319        }
9320        final File passedIconFile = new File(filePath);
9321        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9322                passedIconFile.getName());
9323        if (!legitIconFile.getPath().equals(filePath)
9324                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9325            throw new IllegalArgumentException("Bad file path: " + filePath
9326                    + " passed for userId " + userId);
9327        }
9328        return mRecentTasks.getTaskDescriptionIcon(filePath);
9329    }
9330
9331    @Override
9332    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9333            throws RemoteException {
9334        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9335                opts.getCustomInPlaceResId() == 0) {
9336            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9337                    "with valid animation");
9338        }
9339        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9340        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9341                opts.getCustomInPlaceResId());
9342        mWindowManager.executeAppTransition();
9343    }
9344
9345    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9346            boolean removeFromRecents) {
9347        if (removeFromRecents) {
9348            mRecentTasks.remove(tr);
9349            tr.removedFromRecents();
9350        }
9351        ComponentName component = tr.getBaseIntent().getComponent();
9352        if (component == null) {
9353            Slog.w(TAG, "No component for base intent of task: " + tr);
9354            return;
9355        }
9356
9357        // Find any running services associated with this app and stop if needed.
9358        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9359
9360        if (!killProcess) {
9361            return;
9362        }
9363
9364        // Determine if the process(es) for this task should be killed.
9365        final String pkg = component.getPackageName();
9366        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9367        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9368        for (int i = 0; i < pmap.size(); i++) {
9369
9370            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9371            for (int j = 0; j < uids.size(); j++) {
9372                ProcessRecord proc = uids.valueAt(j);
9373                if (proc.userId != tr.userId) {
9374                    // Don't kill process for a different user.
9375                    continue;
9376                }
9377                if (proc == mHomeProcess) {
9378                    // Don't kill the home process along with tasks from the same package.
9379                    continue;
9380                }
9381                if (!proc.pkgList.containsKey(pkg)) {
9382                    // Don't kill process that is not associated with this task.
9383                    continue;
9384                }
9385
9386                for (int k = 0; k < proc.activities.size(); k++) {
9387                    TaskRecord otherTask = proc.activities.get(k).task;
9388                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9389                        // Don't kill process(es) that has an activity in a different task that is
9390                        // also in recents.
9391                        return;
9392                    }
9393                }
9394
9395                if (proc.foregroundServices) {
9396                    // Don't kill process(es) with foreground service.
9397                    return;
9398                }
9399
9400                // Add process to kill list.
9401                procsToKill.add(proc);
9402            }
9403        }
9404
9405        // Kill the running processes.
9406        for (int i = 0; i < procsToKill.size(); i++) {
9407            ProcessRecord pr = procsToKill.get(i);
9408            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9409                    && pr.curReceiver == null) {
9410                pr.kill("remove task", true);
9411            } else {
9412                // We delay killing processes that are not in the background or running a receiver.
9413                pr.waitingToKill = "remove task";
9414            }
9415        }
9416    }
9417
9418    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9419        // Remove all tasks with activities in the specified package from the list of recent tasks
9420        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9421            TaskRecord tr = mRecentTasks.get(i);
9422            if (tr.userId != userId) continue;
9423
9424            ComponentName cn = tr.intent.getComponent();
9425            if (cn != null && cn.getPackageName().equals(packageName)) {
9426                // If the package name matches, remove the task.
9427                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9428            }
9429        }
9430    }
9431
9432    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9433            int userId) {
9434
9435        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9436            TaskRecord tr = mRecentTasks.get(i);
9437            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9438                continue;
9439            }
9440
9441            ComponentName cn = tr.intent.getComponent();
9442            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9443                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9444            if (sameComponent) {
9445                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9446            }
9447        }
9448    }
9449
9450    /**
9451     * Removes the task with the specified task id.
9452     *
9453     * @param taskId Identifier of the task to be removed.
9454     * @param killProcess Kill any process associated with the task if possible.
9455     * @param removeFromRecents Whether to also remove the task from recents.
9456     * @return Returns true if the given task was found and removed.
9457     */
9458    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9459            boolean removeFromRecents) {
9460        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9461                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9462        if (tr != null) {
9463            tr.removeTaskActivitiesLocked();
9464            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9465            if (tr.isPersistable) {
9466                notifyTaskPersisterLocked(null, true);
9467            }
9468            return true;
9469        }
9470        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9471        return false;
9472    }
9473
9474    @Override
9475    public void removeStack(int stackId) {
9476        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9477        if (stackId == HOME_STACK_ID) {
9478            throw new IllegalArgumentException("Removing home stack is not allowed.");
9479        }
9480
9481        synchronized (this) {
9482            final long ident = Binder.clearCallingIdentity();
9483            try {
9484                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9485                if (stack == null) {
9486                    return;
9487                }
9488                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9489                for (int i = tasks.size() - 1; i >= 0; i--) {
9490                    removeTaskByIdLocked(
9491                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9492                }
9493            } finally {
9494                Binder.restoreCallingIdentity(ident);
9495            }
9496        }
9497    }
9498
9499    @Override
9500    public boolean removeTask(int taskId) {
9501        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9502        synchronized (this) {
9503            final long ident = Binder.clearCallingIdentity();
9504            try {
9505                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9506            } finally {
9507                Binder.restoreCallingIdentity(ident);
9508            }
9509        }
9510    }
9511
9512    /**
9513     * TODO: Add mController hook
9514     */
9515    @Override
9516    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9517        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9518
9519        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9520        synchronized(this) {
9521            moveTaskToFrontLocked(taskId, flags, bOptions);
9522        }
9523    }
9524
9525    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9526        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9527
9528        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9529                Binder.getCallingUid(), -1, -1, "Task to front")) {
9530            ActivityOptions.abort(options);
9531            return;
9532        }
9533        final long origId = Binder.clearCallingIdentity();
9534        try {
9535            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9536            if (task == null) {
9537                Slog.d(TAG, "Could not find task for id: "+ taskId);
9538                return;
9539            }
9540            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9541                mStackSupervisor.showLockTaskToast();
9542                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9543                return;
9544            }
9545            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9546            if (prev != null && prev.isRecentsActivity()) {
9547                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9548            }
9549            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9550                    false /* forceNonResizable */);
9551        } finally {
9552            Binder.restoreCallingIdentity(origId);
9553        }
9554        ActivityOptions.abort(options);
9555    }
9556
9557    /**
9558     * Moves an activity, and all of the other activities within the same task, to the bottom
9559     * of the history stack.  The activity's order within the task is unchanged.
9560     *
9561     * @param token A reference to the activity we wish to move
9562     * @param nonRoot If false then this only works if the activity is the root
9563     *                of a task; if true it will work for any activity in a task.
9564     * @return Returns true if the move completed, false if not.
9565     */
9566    @Override
9567    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9568        enforceNotIsolatedCaller("moveActivityTaskToBack");
9569        synchronized(this) {
9570            final long origId = Binder.clearCallingIdentity();
9571            try {
9572                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9573                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9574                if (task != null) {
9575                    if (mStackSupervisor.isLockedTask(task)) {
9576                        mStackSupervisor.showLockTaskToast();
9577                        return false;
9578                    }
9579                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9580                }
9581            } finally {
9582                Binder.restoreCallingIdentity(origId);
9583            }
9584        }
9585        return false;
9586    }
9587
9588    @Override
9589    public void moveTaskBackwards(int task) {
9590        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9591                "moveTaskBackwards()");
9592
9593        synchronized(this) {
9594            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9595                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9596                return;
9597            }
9598            final long origId = Binder.clearCallingIdentity();
9599            moveTaskBackwardsLocked(task);
9600            Binder.restoreCallingIdentity(origId);
9601        }
9602    }
9603
9604    private final void moveTaskBackwardsLocked(int task) {
9605        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9606    }
9607
9608    @Override
9609    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9610            IActivityContainerCallback callback) throws RemoteException {
9611        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9612        synchronized (this) {
9613            if (parentActivityToken == null) {
9614                throw new IllegalArgumentException("parent token must not be null");
9615            }
9616            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9617            if (r == null) {
9618                return null;
9619            }
9620            if (callback == null) {
9621                throw new IllegalArgumentException("callback must not be null");
9622            }
9623            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9624        }
9625    }
9626
9627    @Override
9628    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9629        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9630        synchronized (this) {
9631            mStackSupervisor.deleteActivityContainer(container);
9632        }
9633    }
9634
9635    @Override
9636    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9637        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9638        synchronized (this) {
9639            final int stackId = mStackSupervisor.getNextStackId();
9640            final ActivityStack stack =
9641                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9642            if (stack == null) {
9643                return null;
9644            }
9645            return stack.mActivityContainer;
9646        }
9647    }
9648
9649    @Override
9650    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9651        synchronized (this) {
9652            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9653            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9654                return stack.mActivityContainer.getDisplayId();
9655            }
9656            return Display.DEFAULT_DISPLAY;
9657        }
9658    }
9659
9660    @Override
9661    public int getActivityStackId(IBinder token) throws RemoteException {
9662        synchronized (this) {
9663            ActivityStack stack = ActivityRecord.getStackLocked(token);
9664            if (stack == null) {
9665                return INVALID_STACK_ID;
9666            }
9667            return stack.mStackId;
9668        }
9669    }
9670
9671    @Override
9672    public void exitFreeformMode(IBinder token) throws RemoteException {
9673        synchronized (this) {
9674            long ident = Binder.clearCallingIdentity();
9675            try {
9676                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9677                if (r == null) {
9678                    throw new IllegalArgumentException(
9679                            "exitFreeformMode: No activity record matching token=" + token);
9680                }
9681                final ActivityStack stack = r.getStackLocked(token);
9682                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9683                    throw new IllegalStateException(
9684                            "exitFreeformMode: You can only go fullscreen from freeform.");
9685                }
9686                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9687                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9688                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9689            } finally {
9690                Binder.restoreCallingIdentity(ident);
9691            }
9692        }
9693    }
9694
9695    @Override
9696    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9697        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9698        if (stackId == HOME_STACK_ID) {
9699            throw new IllegalArgumentException(
9700                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9701        }
9702        synchronized (this) {
9703            long ident = Binder.clearCallingIdentity();
9704            try {
9705                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9706                        + " to stackId=" + stackId + " toTop=" + toTop);
9707                if (stackId == DOCKED_STACK_ID) {
9708                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9709                            null /* initialBounds */);
9710                }
9711                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9712                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9713                if (result && stackId == DOCKED_STACK_ID) {
9714                    // If task moved to docked stack - show recents if needed.
9715                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9716                            "moveTaskToDockedStack");
9717                }
9718            } finally {
9719                Binder.restoreCallingIdentity(ident);
9720            }
9721        }
9722    }
9723
9724    @Override
9725    public void swapDockedAndFullscreenStack() throws RemoteException {
9726        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9727        synchronized (this) {
9728            long ident = Binder.clearCallingIdentity();
9729            try {
9730                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9731                        FULLSCREEN_WORKSPACE_STACK_ID);
9732                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9733                        : null;
9734                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9735                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9736                        : null;
9737                if (topTask == null || tasks == null || tasks.size() == 0) {
9738                    Slog.w(TAG,
9739                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9740                    return;
9741                }
9742
9743                // TODO: App transition
9744                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9745
9746                // Defer the resume so resume/pausing while moving stacks is dangerous.
9747                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9748                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9749                        ANIMATE, true /* deferResume */);
9750                final int size = tasks.size();
9751                for (int i = 0; i < size; i++) {
9752                    final int id = tasks.get(i).taskId;
9753                    if (id == topTask.taskId) {
9754                        continue;
9755                    }
9756                    mStackSupervisor.moveTaskToStackLocked(id,
9757                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9758                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9759                }
9760
9761                // Because we deferred the resume, to avoid conflicts with stack switches while
9762                // resuming, we need to do it after all the tasks are moved.
9763                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9764                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9765
9766                mWindowManager.executeAppTransition();
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771    }
9772
9773    /**
9774     * Moves the input task to the docked stack.
9775     *
9776     * @param taskId Id of task to move.
9777     * @param createMode The mode the docked stack should be created in if it doesn't exist
9778     *                   already. See
9779     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9780     *                   and
9781     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9782     * @param toTop If the task and stack should be moved to the top.
9783     * @param animate Whether we should play an animation for the moving the task
9784     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9785     *                      docked stack. Pass {@code null} to use default bounds.
9786     */
9787    @Override
9788    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9789            Rect initialBounds, boolean moveHomeStackFront) {
9790        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9791        synchronized (this) {
9792            long ident = Binder.clearCallingIdentity();
9793            try {
9794                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9795                        + " to createMode=" + createMode + " toTop=" + toTop);
9796                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9797                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9798                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9799                        animate, DEFER_RESUME);
9800                if (moved) {
9801                    if (moveHomeStackFront) {
9802                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9803                    }
9804                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9805                }
9806                return moved;
9807            } finally {
9808                Binder.restoreCallingIdentity(ident);
9809            }
9810        }
9811    }
9812
9813    /**
9814     * Moves the top activity in the input stackId to the pinned stack.
9815     *
9816     * @param stackId Id of stack to move the top activity to pinned stack.
9817     * @param bounds Bounds to use for pinned stack.
9818     *
9819     * @return True if the top activity of the input stack was successfully moved to the pinned
9820     *          stack.
9821     */
9822    @Override
9823    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9824        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9825        synchronized (this) {
9826            if (!mSupportsPictureInPicture) {
9827                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9828                        + "Device doesn't support picture-in-pciture mode");
9829            }
9830
9831            long ident = Binder.clearCallingIdentity();
9832            try {
9833                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9834            } finally {
9835                Binder.restoreCallingIdentity(ident);
9836            }
9837        }
9838    }
9839
9840    @Override
9841    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9842            boolean preserveWindows, boolean animate, int animationDuration) {
9843        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9844        long ident = Binder.clearCallingIdentity();
9845        try {
9846            synchronized (this) {
9847                if (animate) {
9848                    if (stackId == PINNED_STACK_ID) {
9849                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9850                    } else {
9851                        throw new IllegalArgumentException("Stack: " + stackId
9852                                + " doesn't support animated resize.");
9853                    }
9854                } else {
9855                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9856                            null /* tempTaskInsetBounds */, preserveWindows,
9857                            allowResizeInDockedMode, !DEFER_RESUME);
9858                }
9859            }
9860        } finally {
9861            Binder.restoreCallingIdentity(ident);
9862        }
9863    }
9864
9865    @Override
9866    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9867            Rect tempDockedTaskInsetBounds,
9868            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9870                "resizeDockedStack()");
9871        long ident = Binder.clearCallingIdentity();
9872        try {
9873            synchronized (this) {
9874                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9875                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9876                        PRESERVE_WINDOWS);
9877            }
9878        } finally {
9879            Binder.restoreCallingIdentity(ident);
9880        }
9881    }
9882
9883    @Override
9884    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9885        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9886                "resizePinnedStack()");
9887        final long ident = Binder.clearCallingIdentity();
9888        try {
9889            synchronized (this) {
9890                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9891            }
9892        } finally {
9893            Binder.restoreCallingIdentity(ident);
9894        }
9895    }
9896
9897    @Override
9898    public void positionTaskInStack(int taskId, int stackId, int position) {
9899        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9900        if (stackId == HOME_STACK_ID) {
9901            throw new IllegalArgumentException(
9902                    "positionTaskInStack: Attempt to change the position of task "
9903                    + taskId + " in/to home stack");
9904        }
9905        synchronized (this) {
9906            long ident = Binder.clearCallingIdentity();
9907            try {
9908                if (DEBUG_STACK) Slog.d(TAG_STACK,
9909                        "positionTaskInStack: positioning task=" + taskId
9910                        + " in stackId=" + stackId + " at position=" + position);
9911                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9912            } finally {
9913                Binder.restoreCallingIdentity(ident);
9914            }
9915        }
9916    }
9917
9918    @Override
9919    public List<StackInfo> getAllStackInfos() {
9920        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9921        long ident = Binder.clearCallingIdentity();
9922        try {
9923            synchronized (this) {
9924                return mStackSupervisor.getAllStackInfosLocked();
9925            }
9926        } finally {
9927            Binder.restoreCallingIdentity(ident);
9928        }
9929    }
9930
9931    @Override
9932    public StackInfo getStackInfo(int stackId) {
9933        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9934        long ident = Binder.clearCallingIdentity();
9935        try {
9936            synchronized (this) {
9937                return mStackSupervisor.getStackInfoLocked(stackId);
9938            }
9939        } finally {
9940            Binder.restoreCallingIdentity(ident);
9941        }
9942    }
9943
9944    @Override
9945    public boolean isInHomeStack(int taskId) {
9946        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9947        long ident = Binder.clearCallingIdentity();
9948        try {
9949            synchronized (this) {
9950                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9951                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9952                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9953            }
9954        } finally {
9955            Binder.restoreCallingIdentity(ident);
9956        }
9957    }
9958
9959    @Override
9960    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9961        synchronized(this) {
9962            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9963        }
9964    }
9965
9966    @Override
9967    public void updateDeviceOwner(String packageName) {
9968        final int callingUid = Binder.getCallingUid();
9969        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9970            throw new SecurityException("updateDeviceOwner called from non-system process");
9971        }
9972        synchronized (this) {
9973            mDeviceOwnerName = packageName;
9974        }
9975    }
9976
9977    @Override
9978    public void updateLockTaskPackages(int userId, String[] packages) {
9979        final int callingUid = Binder.getCallingUid();
9980        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9981            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9982                    "updateLockTaskPackages()");
9983        }
9984        synchronized (this) {
9985            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9986                    Arrays.toString(packages));
9987            mLockTaskPackages.put(userId, packages);
9988            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9989        }
9990    }
9991
9992
9993    void startLockTaskModeLocked(TaskRecord task) {
9994        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9995        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9996            return;
9997        }
9998
9999        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10000        // is initiated by system after the pinning request was shown and locked mode is initiated
10001        // by an authorized app directly
10002        final int callingUid = Binder.getCallingUid();
10003        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10004        long ident = Binder.clearCallingIdentity();
10005        try {
10006            if (!isSystemInitiated) {
10007                task.mLockTaskUid = callingUid;
10008                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10009                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10010                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10011                    StatusBarManagerInternal statusBarManager =
10012                            LocalServices.getService(StatusBarManagerInternal.class);
10013                    if (statusBarManager != null) {
10014                        statusBarManager.showScreenPinningRequest(task.taskId);
10015                    }
10016                    return;
10017                }
10018
10019                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10020                if (stack == null || task != stack.topTask()) {
10021                    throw new IllegalArgumentException("Invalid task, not in foreground");
10022                }
10023            }
10024            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10025                    "Locking fully");
10026            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10027                    ActivityManager.LOCK_TASK_MODE_PINNED :
10028                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10029                    "startLockTask", true);
10030        } finally {
10031            Binder.restoreCallingIdentity(ident);
10032        }
10033    }
10034
10035    @Override
10036    public void startLockTaskMode(int taskId) {
10037        synchronized (this) {
10038            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10039            if (task != null) {
10040                startLockTaskModeLocked(task);
10041            }
10042        }
10043    }
10044
10045    @Override
10046    public void startLockTaskMode(IBinder token) {
10047        synchronized (this) {
10048            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10049            if (r == null) {
10050                return;
10051            }
10052            final TaskRecord task = r.task;
10053            if (task != null) {
10054                startLockTaskModeLocked(task);
10055            }
10056        }
10057    }
10058
10059    @Override
10060    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10061        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10062        // This makes inner call to look as if it was initiated by system.
10063        long ident = Binder.clearCallingIdentity();
10064        try {
10065            synchronized (this) {
10066                startLockTaskMode(taskId);
10067            }
10068        } finally {
10069            Binder.restoreCallingIdentity(ident);
10070        }
10071    }
10072
10073    @Override
10074    public void stopLockTaskMode() {
10075        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10076        if (lockTask == null) {
10077            // Our work here is done.
10078            return;
10079        }
10080
10081        final int callingUid = Binder.getCallingUid();
10082        final int lockTaskUid = lockTask.mLockTaskUid;
10083        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10084        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10085            // Done.
10086            return;
10087        } else {
10088            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10089            // It is possible lockTaskMode was started by the system process because
10090            // android:lockTaskMode is set to a locking value in the application manifest
10091            // instead of the app calling startLockTaskMode. In this case
10092            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10093            // {@link TaskRecord.effectiveUid} instead. Also caller with
10094            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10095            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10096                    && callingUid != lockTaskUid
10097                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10098                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10099                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10100            }
10101        }
10102        long ident = Binder.clearCallingIdentity();
10103        try {
10104            Log.d(TAG, "stopLockTaskMode");
10105            // Stop lock task
10106            synchronized (this) {
10107                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10108                        "stopLockTask", true);
10109            }
10110        } finally {
10111            Binder.restoreCallingIdentity(ident);
10112        }
10113    }
10114
10115    /**
10116     * This API should be called by SystemUI only when user perform certain action to dismiss
10117     * lock task mode. We should only dismiss pinned lock task mode in this case.
10118     */
10119    @Override
10120    public void stopSystemLockTaskMode() throws RemoteException {
10121        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10122            stopLockTaskMode();
10123        } else {
10124            mStackSupervisor.showLockTaskToast();
10125        }
10126    }
10127
10128    @Override
10129    public boolean isInLockTaskMode() {
10130        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10131    }
10132
10133    @Override
10134    public int getLockTaskModeState() {
10135        synchronized (this) {
10136            return mStackSupervisor.getLockTaskModeState();
10137        }
10138    }
10139
10140    @Override
10141    public void showLockTaskEscapeMessage(IBinder token) {
10142        synchronized (this) {
10143            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10144            if (r == null) {
10145                return;
10146            }
10147            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10148        }
10149    }
10150
10151    // =========================================================
10152    // CONTENT PROVIDERS
10153    // =========================================================
10154
10155    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10156        List<ProviderInfo> providers = null;
10157        try {
10158            providers = AppGlobals.getPackageManager()
10159                    .queryContentProviders(app.processName, app.uid,
10160                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10161                                    | MATCH_DEBUG_TRIAGED_MISSING)
10162                    .getList();
10163        } catch (RemoteException ex) {
10164        }
10165        if (DEBUG_MU) Slog.v(TAG_MU,
10166                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10167        int userId = app.userId;
10168        if (providers != null) {
10169            int N = providers.size();
10170            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10171            for (int i=0; i<N; i++) {
10172                ProviderInfo cpi =
10173                    (ProviderInfo)providers.get(i);
10174                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10175                        cpi.name, cpi.flags);
10176                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10177                    // This is a singleton provider, but a user besides the
10178                    // default user is asking to initialize a process it runs
10179                    // in...  well, no, it doesn't actually run in this process,
10180                    // it runs in the process of the default user.  Get rid of it.
10181                    providers.remove(i);
10182                    N--;
10183                    i--;
10184                    continue;
10185                }
10186
10187                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10188                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10189                if (cpr == null) {
10190                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10191                    mProviderMap.putProviderByClass(comp, cpr);
10192                }
10193                if (DEBUG_MU) Slog.v(TAG_MU,
10194                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10195                app.pubProviders.put(cpi.name, cpr);
10196                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10197                    // Don't add this if it is a platform component that is marked
10198                    // to run in multiple processes, because this is actually
10199                    // part of the framework so doesn't make sense to track as a
10200                    // separate apk in the process.
10201                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10202                            mProcessStats);
10203                }
10204                notifyPackageUse(cpi.applicationInfo.packageName,
10205                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10206            }
10207        }
10208        return providers;
10209    }
10210
10211    /**
10212     * Check if {@link ProcessRecord} has a possible chance at accessing the
10213     * given {@link ProviderInfo}. Final permission checking is always done
10214     * in {@link ContentProvider}.
10215     */
10216    private final String checkContentProviderPermissionLocked(
10217            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10218        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10219        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10220        boolean checkedGrants = false;
10221        if (checkUser) {
10222            // Looking for cross-user grants before enforcing the typical cross-users permissions
10223            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10224            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10225                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10226                    return null;
10227                }
10228                checkedGrants = true;
10229            }
10230            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10231                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10232            if (userId != tmpTargetUserId) {
10233                // When we actually went to determine the final targer user ID, this ended
10234                // up different than our initial check for the authority.  This is because
10235                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10236                // SELF.  So we need to re-check the grants again.
10237                checkedGrants = false;
10238            }
10239        }
10240        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10241                cpi.applicationInfo.uid, cpi.exported)
10242                == PackageManager.PERMISSION_GRANTED) {
10243            return null;
10244        }
10245        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10246                cpi.applicationInfo.uid, cpi.exported)
10247                == PackageManager.PERMISSION_GRANTED) {
10248            return null;
10249        }
10250
10251        PathPermission[] pps = cpi.pathPermissions;
10252        if (pps != null) {
10253            int i = pps.length;
10254            while (i > 0) {
10255                i--;
10256                PathPermission pp = pps[i];
10257                String pprperm = pp.getReadPermission();
10258                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10259                        cpi.applicationInfo.uid, cpi.exported)
10260                        == PackageManager.PERMISSION_GRANTED) {
10261                    return null;
10262                }
10263                String ppwperm = pp.getWritePermission();
10264                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10265                        cpi.applicationInfo.uid, cpi.exported)
10266                        == PackageManager.PERMISSION_GRANTED) {
10267                    return null;
10268                }
10269            }
10270        }
10271        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10272            return null;
10273        }
10274
10275        String msg;
10276        if (!cpi.exported) {
10277            msg = "Permission Denial: opening provider " + cpi.name
10278                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10279                    + ", uid=" + callingUid + ") that is not exported from uid "
10280                    + cpi.applicationInfo.uid;
10281        } else {
10282            msg = "Permission Denial: opening provider " + cpi.name
10283                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10284                    + ", uid=" + callingUid + ") requires "
10285                    + cpi.readPermission + " or " + cpi.writePermission;
10286        }
10287        Slog.w(TAG, msg);
10288        return msg;
10289    }
10290
10291    /**
10292     * Returns if the ContentProvider has granted a uri to callingUid
10293     */
10294    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10295        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10296        if (perms != null) {
10297            for (int i=perms.size()-1; i>=0; i--) {
10298                GrantUri grantUri = perms.keyAt(i);
10299                if (grantUri.sourceUserId == userId || !checkUser) {
10300                    if (matchesProvider(grantUri.uri, cpi)) {
10301                        return true;
10302                    }
10303                }
10304            }
10305        }
10306        return false;
10307    }
10308
10309    /**
10310     * Returns true if the uri authority is one of the authorities specified in the provider.
10311     */
10312    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10313        String uriAuth = uri.getAuthority();
10314        String cpiAuth = cpi.authority;
10315        if (cpiAuth.indexOf(';') == -1) {
10316            return cpiAuth.equals(uriAuth);
10317        }
10318        String[] cpiAuths = cpiAuth.split(";");
10319        int length = cpiAuths.length;
10320        for (int i = 0; i < length; i++) {
10321            if (cpiAuths[i].equals(uriAuth)) return true;
10322        }
10323        return false;
10324    }
10325
10326    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10327            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10328        if (r != null) {
10329            for (int i=0; i<r.conProviders.size(); i++) {
10330                ContentProviderConnection conn = r.conProviders.get(i);
10331                if (conn.provider == cpr) {
10332                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10333                            "Adding provider requested by "
10334                            + r.processName + " from process "
10335                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10336                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10337                    if (stable) {
10338                        conn.stableCount++;
10339                        conn.numStableIncs++;
10340                    } else {
10341                        conn.unstableCount++;
10342                        conn.numUnstableIncs++;
10343                    }
10344                    return conn;
10345                }
10346            }
10347            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10348            if (stable) {
10349                conn.stableCount = 1;
10350                conn.numStableIncs = 1;
10351            } else {
10352                conn.unstableCount = 1;
10353                conn.numUnstableIncs = 1;
10354            }
10355            cpr.connections.add(conn);
10356            r.conProviders.add(conn);
10357            startAssociationLocked(r.uid, r.processName, r.curProcState,
10358                    cpr.uid, cpr.name, cpr.info.processName);
10359            return conn;
10360        }
10361        cpr.addExternalProcessHandleLocked(externalProcessToken);
10362        return null;
10363    }
10364
10365    boolean decProviderCountLocked(ContentProviderConnection conn,
10366            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10367        if (conn != null) {
10368            cpr = conn.provider;
10369            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10370                    "Removing provider requested by "
10371                    + conn.client.processName + " from process "
10372                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10373                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10374            if (stable) {
10375                conn.stableCount--;
10376            } else {
10377                conn.unstableCount--;
10378            }
10379            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10380                cpr.connections.remove(conn);
10381                conn.client.conProviders.remove(conn);
10382                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10383                    // The client is more important than last activity -- note the time this
10384                    // is happening, so we keep the old provider process around a bit as last
10385                    // activity to avoid thrashing it.
10386                    if (cpr.proc != null) {
10387                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10388                    }
10389                }
10390                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10391                return true;
10392            }
10393            return false;
10394        }
10395        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10396        return false;
10397    }
10398
10399    private void checkTime(long startTime, String where) {
10400        long now = SystemClock.uptimeMillis();
10401        if ((now-startTime) > 50) {
10402            // If we are taking more than 50ms, log about it.
10403            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10404        }
10405    }
10406
10407    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10408            String name, IBinder token, boolean stable, int userId) {
10409        ContentProviderRecord cpr;
10410        ContentProviderConnection conn = null;
10411        ProviderInfo cpi = null;
10412
10413        synchronized(this) {
10414            long startTime = SystemClock.uptimeMillis();
10415
10416            ProcessRecord r = null;
10417            if (caller != null) {
10418                r = getRecordForAppLocked(caller);
10419                if (r == null) {
10420                    throw new SecurityException(
10421                            "Unable to find app for caller " + caller
10422                          + " (pid=" + Binder.getCallingPid()
10423                          + ") when getting content provider " + name);
10424                }
10425            }
10426
10427            boolean checkCrossUser = true;
10428
10429            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10430
10431            // First check if this content provider has been published...
10432            cpr = mProviderMap.getProviderByName(name, userId);
10433            // If that didn't work, check if it exists for user 0 and then
10434            // verify that it's a singleton provider before using it.
10435            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10436                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10437                if (cpr != null) {
10438                    cpi = cpr.info;
10439                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10440                            cpi.name, cpi.flags)
10441                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10442                        userId = UserHandle.USER_SYSTEM;
10443                        checkCrossUser = false;
10444                    } else {
10445                        cpr = null;
10446                        cpi = null;
10447                    }
10448                }
10449            }
10450
10451            boolean providerRunning = cpr != null;
10452            if (providerRunning) {
10453                cpi = cpr.info;
10454                String msg;
10455                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10456                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10457                        != null) {
10458                    throw new SecurityException(msg);
10459                }
10460                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10461
10462                if (r != null && cpr.canRunHere(r)) {
10463                    // This provider has been published or is in the process
10464                    // of being published...  but it is also allowed to run
10465                    // in the caller's process, so don't make a connection
10466                    // and just let the caller instantiate its own instance.
10467                    ContentProviderHolder holder = cpr.newHolder(null);
10468                    // don't give caller the provider object, it needs
10469                    // to make its own.
10470                    holder.provider = null;
10471                    return holder;
10472                }
10473
10474                final long origId = Binder.clearCallingIdentity();
10475
10476                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10477
10478                // In this case the provider instance already exists, so we can
10479                // return it right away.
10480                conn = incProviderCountLocked(r, cpr, token, stable);
10481                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10482                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10483                        // If this is a perceptible app accessing the provider,
10484                        // make sure to count it as being accessed and thus
10485                        // back up on the LRU list.  This is good because
10486                        // content providers are often expensive to start.
10487                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10488                        updateLruProcessLocked(cpr.proc, false, null);
10489                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10490                    }
10491                }
10492
10493                if (cpr.proc != null) {
10494                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10495                    boolean success = updateOomAdjLocked(cpr.proc);
10496                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10497                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10498                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10499                    // NOTE: there is still a race here where a signal could be
10500                    // pending on the process even though we managed to update its
10501                    // adj level.  Not sure what to do about this, but at least
10502                    // the race is now smaller.
10503                    if (!success) {
10504                        // Uh oh...  it looks like the provider's process
10505                        // has been killed on us.  We need to wait for a new
10506                        // process to be started, and make sure its death
10507                        // doesn't kill our process.
10508                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10509                                + " is crashing; detaching " + r);
10510                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10511                        checkTime(startTime, "getContentProviderImpl: before appDied");
10512                        appDiedLocked(cpr.proc);
10513                        checkTime(startTime, "getContentProviderImpl: after appDied");
10514                        if (!lastRef) {
10515                            // This wasn't the last ref our process had on
10516                            // the provider...  we have now been killed, bail.
10517                            return null;
10518                        }
10519                        providerRunning = false;
10520                        conn = null;
10521                    }
10522                }
10523
10524                Binder.restoreCallingIdentity(origId);
10525            }
10526
10527            if (!providerRunning) {
10528                try {
10529                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10530                    cpi = AppGlobals.getPackageManager().
10531                        resolveContentProvider(name,
10532                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10533                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10534                } catch (RemoteException ex) {
10535                }
10536                if (cpi == null) {
10537                    return null;
10538                }
10539                // If the provider is a singleton AND
10540                // (it's a call within the same user || the provider is a
10541                // privileged app)
10542                // Then allow connecting to the singleton provider
10543                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10544                        cpi.name, cpi.flags)
10545                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10546                if (singleton) {
10547                    userId = UserHandle.USER_SYSTEM;
10548                }
10549                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10550                checkTime(startTime, "getContentProviderImpl: got app info for user");
10551
10552                String msg;
10553                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10554                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10555                        != null) {
10556                    throw new SecurityException(msg);
10557                }
10558                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10559
10560                if (!mProcessesReady
10561                        && !cpi.processName.equals("system")) {
10562                    // If this content provider does not run in the system
10563                    // process, and the system is not yet ready to run other
10564                    // processes, then fail fast instead of hanging.
10565                    throw new IllegalArgumentException(
10566                            "Attempt to launch content provider before system ready");
10567                }
10568
10569                // Make sure that the user who owns this provider is running.  If not,
10570                // we don't want to allow it to run.
10571                if (!mUserController.isUserRunningLocked(userId, 0)) {
10572                    Slog.w(TAG, "Unable to launch app "
10573                            + cpi.applicationInfo.packageName + "/"
10574                            + cpi.applicationInfo.uid + " for provider "
10575                            + name + ": user " + userId + " is stopped");
10576                    return null;
10577                }
10578
10579                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10580                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10581                cpr = mProviderMap.getProviderByClass(comp, userId);
10582                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10583                final boolean firstClass = cpr == null;
10584                if (firstClass) {
10585                    final long ident = Binder.clearCallingIdentity();
10586
10587                    // If permissions need a review before any of the app components can run,
10588                    // we return no provider and launch a review activity if the calling app
10589                    // is in the foreground.
10590                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10591                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10592                            return null;
10593                        }
10594                    }
10595
10596                    try {
10597                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10598                        ApplicationInfo ai =
10599                            AppGlobals.getPackageManager().
10600                                getApplicationInfo(
10601                                        cpi.applicationInfo.packageName,
10602                                        STOCK_PM_FLAGS, userId);
10603                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10604                        if (ai == null) {
10605                            Slog.w(TAG, "No package info for content provider "
10606                                    + cpi.name);
10607                            return null;
10608                        }
10609                        ai = getAppInfoForUser(ai, userId);
10610                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10611                    } catch (RemoteException ex) {
10612                        // pm is in same process, this will never happen.
10613                    } finally {
10614                        Binder.restoreCallingIdentity(ident);
10615                    }
10616                }
10617
10618                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10619
10620                if (r != null && cpr.canRunHere(r)) {
10621                    // If this is a multiprocess provider, then just return its
10622                    // info and allow the caller to instantiate it.  Only do
10623                    // this if the provider is the same user as the caller's
10624                    // process, or can run as root (so can be in any process).
10625                    return cpr.newHolder(null);
10626                }
10627
10628                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10629                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10630                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10631
10632                // This is single process, and our app is now connecting to it.
10633                // See if we are already in the process of launching this
10634                // provider.
10635                final int N = mLaunchingProviders.size();
10636                int i;
10637                for (i = 0; i < N; i++) {
10638                    if (mLaunchingProviders.get(i) == cpr) {
10639                        break;
10640                    }
10641                }
10642
10643                // If the provider is not already being launched, then get it
10644                // started.
10645                if (i >= N) {
10646                    final long origId = Binder.clearCallingIdentity();
10647
10648                    try {
10649                        // Content provider is now in use, its package can't be stopped.
10650                        try {
10651                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10652                            AppGlobals.getPackageManager().setPackageStoppedState(
10653                                    cpr.appInfo.packageName, false, userId);
10654                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10655                        } catch (RemoteException e) {
10656                        } catch (IllegalArgumentException e) {
10657                            Slog.w(TAG, "Failed trying to unstop package "
10658                                    + cpr.appInfo.packageName + ": " + e);
10659                        }
10660
10661                        // Use existing process if already started
10662                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10663                        ProcessRecord proc = getProcessRecordLocked(
10664                                cpi.processName, cpr.appInfo.uid, false);
10665                        if (proc != null && proc.thread != null) {
10666                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10667                                    "Installing in existing process " + proc);
10668                            if (!proc.pubProviders.containsKey(cpi.name)) {
10669                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10670                                proc.pubProviders.put(cpi.name, cpr);
10671                                try {
10672                                    proc.thread.scheduleInstallProvider(cpi);
10673                                } catch (RemoteException e) {
10674                                }
10675                            }
10676                        } else {
10677                            checkTime(startTime, "getContentProviderImpl: before start process");
10678                            proc = startProcessLocked(cpi.processName,
10679                                    cpr.appInfo, false, 0, "content provider",
10680                                    new ComponentName(cpi.applicationInfo.packageName,
10681                                            cpi.name), false, false, false);
10682                            checkTime(startTime, "getContentProviderImpl: after start process");
10683                            if (proc == null) {
10684                                Slog.w(TAG, "Unable to launch app "
10685                                        + cpi.applicationInfo.packageName + "/"
10686                                        + cpi.applicationInfo.uid + " for provider "
10687                                        + name + ": process is bad");
10688                                return null;
10689                            }
10690                        }
10691                        cpr.launchingApp = proc;
10692                        mLaunchingProviders.add(cpr);
10693                    } finally {
10694                        Binder.restoreCallingIdentity(origId);
10695                    }
10696                }
10697
10698                checkTime(startTime, "getContentProviderImpl: updating data structures");
10699
10700                // Make sure the provider is published (the same provider class
10701                // may be published under multiple names).
10702                if (firstClass) {
10703                    mProviderMap.putProviderByClass(comp, cpr);
10704                }
10705
10706                mProviderMap.putProviderByName(name, cpr);
10707                conn = incProviderCountLocked(r, cpr, token, stable);
10708                if (conn != null) {
10709                    conn.waiting = true;
10710                }
10711            }
10712            checkTime(startTime, "getContentProviderImpl: done!");
10713        }
10714
10715        // Wait for the provider to be published...
10716        synchronized (cpr) {
10717            while (cpr.provider == null) {
10718                if (cpr.launchingApp == null) {
10719                    Slog.w(TAG, "Unable to launch app "
10720                            + cpi.applicationInfo.packageName + "/"
10721                            + cpi.applicationInfo.uid + " for provider "
10722                            + name + ": launching app became null");
10723                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10724                            UserHandle.getUserId(cpi.applicationInfo.uid),
10725                            cpi.applicationInfo.packageName,
10726                            cpi.applicationInfo.uid, name);
10727                    return null;
10728                }
10729                try {
10730                    if (DEBUG_MU) Slog.v(TAG_MU,
10731                            "Waiting to start provider " + cpr
10732                            + " launchingApp=" + cpr.launchingApp);
10733                    if (conn != null) {
10734                        conn.waiting = true;
10735                    }
10736                    cpr.wait();
10737                } catch (InterruptedException ex) {
10738                } finally {
10739                    if (conn != null) {
10740                        conn.waiting = false;
10741                    }
10742                }
10743            }
10744        }
10745        return cpr != null ? cpr.newHolder(conn) : null;
10746    }
10747
10748    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10749            ProcessRecord r, final int userId) {
10750        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10751                cpi.packageName, userId)) {
10752
10753            final boolean callerForeground = r == null || r.setSchedGroup
10754                    != ProcessList.SCHED_GROUP_BACKGROUND;
10755
10756            // Show a permission review UI only for starting from a foreground app
10757            if (!callerForeground) {
10758                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10759                        + cpi.packageName + " requires a permissions review");
10760                return false;
10761            }
10762
10763            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10764            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10765                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10766            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10767
10768            if (DEBUG_PERMISSIONS_REVIEW) {
10769                Slog.i(TAG, "u" + userId + " Launching permission review "
10770                        + "for package " + cpi.packageName);
10771            }
10772
10773            final UserHandle userHandle = new UserHandle(userId);
10774            mHandler.post(new Runnable() {
10775                @Override
10776                public void run() {
10777                    mContext.startActivityAsUser(intent, userHandle);
10778                }
10779            });
10780
10781            return false;
10782        }
10783
10784        return true;
10785    }
10786
10787    PackageManagerInternal getPackageManagerInternalLocked() {
10788        if (mPackageManagerInt == null) {
10789            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10790        }
10791        return mPackageManagerInt;
10792    }
10793
10794    @Override
10795    public final ContentProviderHolder getContentProvider(
10796            IApplicationThread caller, String name, int userId, boolean stable) {
10797        enforceNotIsolatedCaller("getContentProvider");
10798        if (caller == null) {
10799            String msg = "null IApplicationThread when getting content provider "
10800                    + name;
10801            Slog.w(TAG, msg);
10802            throw new SecurityException(msg);
10803        }
10804        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10805        // with cross-user grant.
10806        return getContentProviderImpl(caller, name, null, stable, userId);
10807    }
10808
10809    public ContentProviderHolder getContentProviderExternal(
10810            String name, int userId, IBinder token) {
10811        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10812            "Do not have permission in call getContentProviderExternal()");
10813        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10814                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10815        return getContentProviderExternalUnchecked(name, token, userId);
10816    }
10817
10818    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10819            IBinder token, int userId) {
10820        return getContentProviderImpl(null, name, token, true, userId);
10821    }
10822
10823    /**
10824     * Drop a content provider from a ProcessRecord's bookkeeping
10825     */
10826    public void removeContentProvider(IBinder connection, boolean stable) {
10827        enforceNotIsolatedCaller("removeContentProvider");
10828        long ident = Binder.clearCallingIdentity();
10829        try {
10830            synchronized (this) {
10831                ContentProviderConnection conn;
10832                try {
10833                    conn = (ContentProviderConnection)connection;
10834                } catch (ClassCastException e) {
10835                    String msg ="removeContentProvider: " + connection
10836                            + " not a ContentProviderConnection";
10837                    Slog.w(TAG, msg);
10838                    throw new IllegalArgumentException(msg);
10839                }
10840                if (conn == null) {
10841                    throw new NullPointerException("connection is null");
10842                }
10843                if (decProviderCountLocked(conn, null, null, stable)) {
10844                    updateOomAdjLocked();
10845                }
10846            }
10847        } finally {
10848            Binder.restoreCallingIdentity(ident);
10849        }
10850    }
10851
10852    public void removeContentProviderExternal(String name, IBinder token) {
10853        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10854            "Do not have permission in call removeContentProviderExternal()");
10855        int userId = UserHandle.getCallingUserId();
10856        long ident = Binder.clearCallingIdentity();
10857        try {
10858            removeContentProviderExternalUnchecked(name, token, userId);
10859        } finally {
10860            Binder.restoreCallingIdentity(ident);
10861        }
10862    }
10863
10864    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10865        synchronized (this) {
10866            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10867            if(cpr == null) {
10868                //remove from mProvidersByClass
10869                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10870                return;
10871            }
10872
10873            //update content provider record entry info
10874            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10875            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10876            if (localCpr.hasExternalProcessHandles()) {
10877                if (localCpr.removeExternalProcessHandleLocked(token)) {
10878                    updateOomAdjLocked();
10879                } else {
10880                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10881                            + " with no external reference for token: "
10882                            + token + ".");
10883                }
10884            } else {
10885                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10886                        + " with no external references.");
10887            }
10888        }
10889    }
10890
10891    public final void publishContentProviders(IApplicationThread caller,
10892            List<ContentProviderHolder> providers) {
10893        if (providers == null) {
10894            return;
10895        }
10896
10897        enforceNotIsolatedCaller("publishContentProviders");
10898        synchronized (this) {
10899            final ProcessRecord r = getRecordForAppLocked(caller);
10900            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10901            if (r == null) {
10902                throw new SecurityException(
10903                        "Unable to find app for caller " + caller
10904                      + " (pid=" + Binder.getCallingPid()
10905                      + ") when publishing content providers");
10906            }
10907
10908            final long origId = Binder.clearCallingIdentity();
10909
10910            final int N = providers.size();
10911            for (int i = 0; i < N; i++) {
10912                ContentProviderHolder src = providers.get(i);
10913                if (src == null || src.info == null || src.provider == null) {
10914                    continue;
10915                }
10916                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10917                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10918                if (dst != null) {
10919                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10920                    mProviderMap.putProviderByClass(comp, dst);
10921                    String names[] = dst.info.authority.split(";");
10922                    for (int j = 0; j < names.length; j++) {
10923                        mProviderMap.putProviderByName(names[j], dst);
10924                    }
10925
10926                    int launchingCount = mLaunchingProviders.size();
10927                    int j;
10928                    boolean wasInLaunchingProviders = false;
10929                    for (j = 0; j < launchingCount; j++) {
10930                        if (mLaunchingProviders.get(j) == dst) {
10931                            mLaunchingProviders.remove(j);
10932                            wasInLaunchingProviders = true;
10933                            j--;
10934                            launchingCount--;
10935                        }
10936                    }
10937                    if (wasInLaunchingProviders) {
10938                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10939                    }
10940                    synchronized (dst) {
10941                        dst.provider = src.provider;
10942                        dst.proc = r;
10943                        dst.notifyAll();
10944                    }
10945                    updateOomAdjLocked(r);
10946                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10947                            src.info.authority);
10948                }
10949            }
10950
10951            Binder.restoreCallingIdentity(origId);
10952        }
10953    }
10954
10955    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10956        ContentProviderConnection conn;
10957        try {
10958            conn = (ContentProviderConnection)connection;
10959        } catch (ClassCastException e) {
10960            String msg ="refContentProvider: " + connection
10961                    + " not a ContentProviderConnection";
10962            Slog.w(TAG, msg);
10963            throw new IllegalArgumentException(msg);
10964        }
10965        if (conn == null) {
10966            throw new NullPointerException("connection is null");
10967        }
10968
10969        synchronized (this) {
10970            if (stable > 0) {
10971                conn.numStableIncs += stable;
10972            }
10973            stable = conn.stableCount + stable;
10974            if (stable < 0) {
10975                throw new IllegalStateException("stableCount < 0: " + stable);
10976            }
10977
10978            if (unstable > 0) {
10979                conn.numUnstableIncs += unstable;
10980            }
10981            unstable = conn.unstableCount + unstable;
10982            if (unstable < 0) {
10983                throw new IllegalStateException("unstableCount < 0: " + unstable);
10984            }
10985
10986            if ((stable+unstable) <= 0) {
10987                throw new IllegalStateException("ref counts can't go to zero here: stable="
10988                        + stable + " unstable=" + unstable);
10989            }
10990            conn.stableCount = stable;
10991            conn.unstableCount = unstable;
10992            return !conn.dead;
10993        }
10994    }
10995
10996    public void unstableProviderDied(IBinder connection) {
10997        ContentProviderConnection conn;
10998        try {
10999            conn = (ContentProviderConnection)connection;
11000        } catch (ClassCastException e) {
11001            String msg ="refContentProvider: " + connection
11002                    + " not a ContentProviderConnection";
11003            Slog.w(TAG, msg);
11004            throw new IllegalArgumentException(msg);
11005        }
11006        if (conn == null) {
11007            throw new NullPointerException("connection is null");
11008        }
11009
11010        // Safely retrieve the content provider associated with the connection.
11011        IContentProvider provider;
11012        synchronized (this) {
11013            provider = conn.provider.provider;
11014        }
11015
11016        if (provider == null) {
11017            // Um, yeah, we're way ahead of you.
11018            return;
11019        }
11020
11021        // Make sure the caller is being honest with us.
11022        if (provider.asBinder().pingBinder()) {
11023            // Er, no, still looks good to us.
11024            synchronized (this) {
11025                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11026                        + " says " + conn + " died, but we don't agree");
11027                return;
11028            }
11029        }
11030
11031        // Well look at that!  It's dead!
11032        synchronized (this) {
11033            if (conn.provider.provider != provider) {
11034                // But something changed...  good enough.
11035                return;
11036            }
11037
11038            ProcessRecord proc = conn.provider.proc;
11039            if (proc == null || proc.thread == null) {
11040                // Seems like the process is already cleaned up.
11041                return;
11042            }
11043
11044            // As far as we're concerned, this is just like receiving a
11045            // death notification...  just a bit prematurely.
11046            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11047                    + ") early provider death");
11048            final long ident = Binder.clearCallingIdentity();
11049            try {
11050                appDiedLocked(proc);
11051            } finally {
11052                Binder.restoreCallingIdentity(ident);
11053            }
11054        }
11055    }
11056
11057    @Override
11058    public void appNotRespondingViaProvider(IBinder connection) {
11059        enforceCallingPermission(
11060                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11061
11062        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11063        if (conn == null) {
11064            Slog.w(TAG, "ContentProviderConnection is null");
11065            return;
11066        }
11067
11068        final ProcessRecord host = conn.provider.proc;
11069        if (host == null) {
11070            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11071            return;
11072        }
11073
11074        mHandler.post(new Runnable() {
11075            @Override
11076            public void run() {
11077                mAppErrors.appNotResponding(host, null, null, false,
11078                        "ContentProvider not responding");
11079            }
11080        });
11081    }
11082
11083    public final void installSystemProviders() {
11084        List<ProviderInfo> providers;
11085        synchronized (this) {
11086            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11087            providers = generateApplicationProvidersLocked(app);
11088            if (providers != null) {
11089                for (int i=providers.size()-1; i>=0; i--) {
11090                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11091                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11092                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11093                                + ": not system .apk");
11094                        providers.remove(i);
11095                    }
11096                }
11097            }
11098        }
11099        if (providers != null) {
11100            mSystemThread.installSystemProviders(providers);
11101        }
11102
11103        mCoreSettingsObserver = new CoreSettingsObserver(this);
11104        mFontScaleSettingObserver = new FontScaleSettingObserver();
11105
11106        //mUsageStatsService.monitorPackages();
11107    }
11108
11109    private void startPersistentApps(int matchFlags) {
11110        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11111
11112        synchronized (this) {
11113            try {
11114                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11115                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11116                for (ApplicationInfo app : apps) {
11117                    if (!"android".equals(app.packageName)) {
11118                        addAppLocked(app, false, null /* ABI override */);
11119                    }
11120                }
11121            } catch (RemoteException ex) {
11122            }
11123        }
11124    }
11125
11126    /**
11127     * When a user is unlocked, we need to install encryption-unaware providers
11128     * belonging to any running apps.
11129     */
11130    private void installEncryptionUnawareProviders(int userId) {
11131        // We're only interested in providers that are encryption unaware, and
11132        // we don't care about uninstalled apps, since there's no way they're
11133        // running at this point.
11134        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11135
11136        synchronized (this) {
11137            final int NP = mProcessNames.getMap().size();
11138            for (int ip = 0; ip < NP; ip++) {
11139                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11140                final int NA = apps.size();
11141                for (int ia = 0; ia < NA; ia++) {
11142                    final ProcessRecord app = apps.valueAt(ia);
11143                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11144
11145                    final int NG = app.pkgList.size();
11146                    for (int ig = 0; ig < NG; ig++) {
11147                        try {
11148                            final String pkgName = app.pkgList.keyAt(ig);
11149                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11150                                    .getPackageInfo(pkgName, matchFlags, userId);
11151                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11152                                for (ProviderInfo provInfo : pkgInfo.providers) {
11153                                    if (Objects.equals(provInfo.processName, app.processName)) {
11154                                        Log.v(TAG, "Installing " + provInfo);
11155                                        app.thread.scheduleInstallProvider(provInfo);
11156                                    } else {
11157                                        Log.v(TAG, "Skipping " + provInfo);
11158                                    }
11159                                }
11160                            }
11161                        } catch (RemoteException ignored) {
11162                        }
11163                    }
11164                }
11165            }
11166        }
11167    }
11168
11169    /**
11170     * Allows apps to retrieve the MIME type of a URI.
11171     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11172     * users, then it does not need permission to access the ContentProvider.
11173     * Either, it needs cross-user uri grants.
11174     *
11175     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11176     *
11177     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11178     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11179     */
11180    public String getProviderMimeType(Uri uri, int userId) {
11181        enforceNotIsolatedCaller("getProviderMimeType");
11182        final String name = uri.getAuthority();
11183        int callingUid = Binder.getCallingUid();
11184        int callingPid = Binder.getCallingPid();
11185        long ident = 0;
11186        boolean clearedIdentity = false;
11187        synchronized (this) {
11188            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11189        }
11190        if (canClearIdentity(callingPid, callingUid, userId)) {
11191            clearedIdentity = true;
11192            ident = Binder.clearCallingIdentity();
11193        }
11194        ContentProviderHolder holder = null;
11195        try {
11196            holder = getContentProviderExternalUnchecked(name, null, userId);
11197            if (holder != null) {
11198                return holder.provider.getType(uri);
11199            }
11200        } catch (RemoteException e) {
11201            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11202            return null;
11203        } finally {
11204            // We need to clear the identity to call removeContentProviderExternalUnchecked
11205            if (!clearedIdentity) {
11206                ident = Binder.clearCallingIdentity();
11207            }
11208            try {
11209                if (holder != null) {
11210                    removeContentProviderExternalUnchecked(name, null, userId);
11211                }
11212            } finally {
11213                Binder.restoreCallingIdentity(ident);
11214            }
11215        }
11216
11217        return null;
11218    }
11219
11220    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11221        if (UserHandle.getUserId(callingUid) == userId) {
11222            return true;
11223        }
11224        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11225                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11226                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11227                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11228                return true;
11229        }
11230        return false;
11231    }
11232
11233    // =========================================================
11234    // GLOBAL MANAGEMENT
11235    // =========================================================
11236
11237    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11238            boolean isolated, int isolatedUid) {
11239        String proc = customProcess != null ? customProcess : info.processName;
11240        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11241        final int userId = UserHandle.getUserId(info.uid);
11242        int uid = info.uid;
11243        if (isolated) {
11244            if (isolatedUid == 0) {
11245                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11246                while (true) {
11247                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11248                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11249                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11250                    }
11251                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11252                    mNextIsolatedProcessUid++;
11253                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11254                        // No process for this uid, use it.
11255                        break;
11256                    }
11257                    stepsLeft--;
11258                    if (stepsLeft <= 0) {
11259                        return null;
11260                    }
11261                }
11262            } else {
11263                // Special case for startIsolatedProcess (internal only), where
11264                // the uid of the isolated process is specified by the caller.
11265                uid = isolatedUid;
11266            }
11267        }
11268        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11269        if (!mBooted && !mBooting
11270                && userId == UserHandle.USER_SYSTEM
11271                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11272            r.persistent = true;
11273        }
11274        addProcessNameLocked(r);
11275        return r;
11276    }
11277
11278    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11279            String abiOverride) {
11280        ProcessRecord app;
11281        if (!isolated) {
11282            app = getProcessRecordLocked(info.processName, info.uid, true);
11283        } else {
11284            app = null;
11285        }
11286
11287        if (app == null) {
11288            app = newProcessRecordLocked(info, null, isolated, 0);
11289            updateLruProcessLocked(app, false, null);
11290            updateOomAdjLocked();
11291        }
11292
11293        // This package really, really can not be stopped.
11294        try {
11295            AppGlobals.getPackageManager().setPackageStoppedState(
11296                    info.packageName, false, UserHandle.getUserId(app.uid));
11297        } catch (RemoteException e) {
11298        } catch (IllegalArgumentException e) {
11299            Slog.w(TAG, "Failed trying to unstop package "
11300                    + info.packageName + ": " + e);
11301        }
11302
11303        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11304            app.persistent = true;
11305            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11306        }
11307        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11308            mPersistentStartingProcesses.add(app);
11309            startProcessLocked(app, "added application", app.processName, abiOverride,
11310                    null /* entryPoint */, null /* entryPointArgs */);
11311        }
11312
11313        return app;
11314    }
11315
11316    public void unhandledBack() {
11317        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11318                "unhandledBack()");
11319
11320        synchronized(this) {
11321            final long origId = Binder.clearCallingIdentity();
11322            try {
11323                getFocusedStack().unhandledBackLocked();
11324            } finally {
11325                Binder.restoreCallingIdentity(origId);
11326            }
11327        }
11328    }
11329
11330    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11331        enforceNotIsolatedCaller("openContentUri");
11332        final int userId = UserHandle.getCallingUserId();
11333        String name = uri.getAuthority();
11334        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11335        ParcelFileDescriptor pfd = null;
11336        if (cph != null) {
11337            // We record the binder invoker's uid in thread-local storage before
11338            // going to the content provider to open the file.  Later, in the code
11339            // that handles all permissions checks, we look for this uid and use
11340            // that rather than the Activity Manager's own uid.  The effect is that
11341            // we do the check against the caller's permissions even though it looks
11342            // to the content provider like the Activity Manager itself is making
11343            // the request.
11344            Binder token = new Binder();
11345            sCallerIdentity.set(new Identity(
11346                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11347            try {
11348                pfd = cph.provider.openFile(null, uri, "r", null, token);
11349            } catch (FileNotFoundException e) {
11350                // do nothing; pfd will be returned null
11351            } finally {
11352                // Ensure that whatever happens, we clean up the identity state
11353                sCallerIdentity.remove();
11354                // Ensure we're done with the provider.
11355                removeContentProviderExternalUnchecked(name, null, userId);
11356            }
11357        } else {
11358            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11359        }
11360        return pfd;
11361    }
11362
11363    // Actually is sleeping or shutting down or whatever else in the future
11364    // is an inactive state.
11365    public boolean isSleepingOrShuttingDown() {
11366        return isSleeping() || mShuttingDown;
11367    }
11368
11369    public boolean isSleeping() {
11370        return mSleeping;
11371    }
11372
11373    void onWakefulnessChanged(int wakefulness) {
11374        synchronized(this) {
11375            mWakefulness = wakefulness;
11376            updateSleepIfNeededLocked();
11377        }
11378    }
11379
11380    void finishRunningVoiceLocked() {
11381        if (mRunningVoice != null) {
11382            mRunningVoice = null;
11383            mVoiceWakeLock.release();
11384            updateSleepIfNeededLocked();
11385        }
11386    }
11387
11388    void startTimeTrackingFocusedActivityLocked() {
11389        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11390            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11391        }
11392    }
11393
11394    void updateSleepIfNeededLocked() {
11395        if (mSleeping && !shouldSleepLocked()) {
11396            mSleeping = false;
11397            startTimeTrackingFocusedActivityLocked();
11398            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11399            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11400            updateOomAdjLocked();
11401        } else if (!mSleeping && shouldSleepLocked()) {
11402            mSleeping = true;
11403            if (mCurAppTimeTracker != null) {
11404                mCurAppTimeTracker.stop();
11405            }
11406            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11407            mStackSupervisor.goingToSleepLocked();
11408            updateOomAdjLocked();
11409
11410            // Initialize the wake times of all processes.
11411            checkExcessivePowerUsageLocked(false);
11412            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11413            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11414            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11415        }
11416    }
11417
11418    private boolean shouldSleepLocked() {
11419        // Resume applications while running a voice interactor.
11420        if (mRunningVoice != null) {
11421            return false;
11422        }
11423
11424        // TODO: Transform the lock screen state into a sleep token instead.
11425        switch (mWakefulness) {
11426            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11427            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11428            case PowerManagerInternal.WAKEFULNESS_DOZING:
11429                // Pause applications whenever the lock screen is shown or any sleep
11430                // tokens have been acquired.
11431                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11432            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11433            default:
11434                // If we're asleep then pause applications unconditionally.
11435                return true;
11436        }
11437    }
11438
11439    /** Pokes the task persister. */
11440    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11441        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11442    }
11443
11444    /** Notifies all listeners when the task stack has changed. */
11445    void notifyTaskStackChangedLocked() {
11446        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11447        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11448        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11449        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11450    }
11451
11452    /** Notifies all listeners when an Activity is pinned. */
11453    void notifyActivityPinnedLocked() {
11454        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11455        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11456    }
11457
11458    /**
11459     * Notifies all listeners when an attempt was made to start an an activity that is already
11460     * running in the pinned stack and the activity was not actually started, but the task is
11461     * either brought to the front or a new Intent is delivered to it.
11462     */
11463    void notifyPinnedActivityRestartAttemptLocked() {
11464        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11465        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11466    }
11467
11468    /** Notifies all listeners when the pinned stack animation ends. */
11469    @Override
11470    public void notifyPinnedStackAnimationEnded() {
11471        synchronized (this) {
11472            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11473            mHandler.obtainMessage(
11474                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11475        }
11476    }
11477
11478    @Override
11479    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11480        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11481    }
11482
11483    @Override
11484    public boolean shutdown(int timeout) {
11485        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11486                != PackageManager.PERMISSION_GRANTED) {
11487            throw new SecurityException("Requires permission "
11488                    + android.Manifest.permission.SHUTDOWN);
11489        }
11490
11491        boolean timedout = false;
11492
11493        synchronized(this) {
11494            mShuttingDown = true;
11495            updateEventDispatchingLocked();
11496            timedout = mStackSupervisor.shutdownLocked(timeout);
11497        }
11498
11499        mAppOpsService.shutdown();
11500        if (mUsageStatsService != null) {
11501            mUsageStatsService.prepareShutdown();
11502        }
11503        mBatteryStatsService.shutdown();
11504        synchronized (this) {
11505            mProcessStats.shutdownLocked();
11506            notifyTaskPersisterLocked(null, true);
11507        }
11508
11509        return timedout;
11510    }
11511
11512    public final void activitySlept(IBinder token) {
11513        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11514
11515        final long origId = Binder.clearCallingIdentity();
11516
11517        synchronized (this) {
11518            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11519            if (r != null) {
11520                mStackSupervisor.activitySleptLocked(r);
11521            }
11522        }
11523
11524        Binder.restoreCallingIdentity(origId);
11525    }
11526
11527    private String lockScreenShownToString() {
11528        switch (mLockScreenShown) {
11529            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11530            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11531            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11532            default: return "Unknown=" + mLockScreenShown;
11533        }
11534    }
11535
11536    void logLockScreen(String msg) {
11537        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11538                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11539                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11540                + " mSleeping=" + mSleeping);
11541    }
11542
11543    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11544        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11545        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11546        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11547            boolean wasRunningVoice = mRunningVoice != null;
11548            mRunningVoice = session;
11549            if (!wasRunningVoice) {
11550                mVoiceWakeLock.acquire();
11551                updateSleepIfNeededLocked();
11552            }
11553        }
11554    }
11555
11556    private void updateEventDispatchingLocked() {
11557        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11558    }
11559
11560    public void setLockScreenShown(boolean showing, boolean occluded) {
11561        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11562                != PackageManager.PERMISSION_GRANTED) {
11563            throw new SecurityException("Requires permission "
11564                    + android.Manifest.permission.DEVICE_POWER);
11565        }
11566
11567        synchronized(this) {
11568            long ident = Binder.clearCallingIdentity();
11569            try {
11570                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11571                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11572                if (showing && occluded) {
11573                    // The lock screen is currently showing, but is occluded by a window that can
11574                    // show on top of the lock screen. In this can we want to dismiss the docked
11575                    // stack since it will be complicated/risky to try to put the activity on top
11576                    // of the lock screen in the right fullscreen configuration.
11577                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11578                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11579                }
11580
11581                updateSleepIfNeededLocked();
11582            } finally {
11583                Binder.restoreCallingIdentity(ident);
11584            }
11585        }
11586    }
11587
11588    @Override
11589    public void notifyLockedProfile(@UserIdInt int userId) {
11590        try {
11591            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11592                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11593            }
11594        } catch (RemoteException ex) {
11595            throw new SecurityException("Fail to check is caller a privileged app", ex);
11596        }
11597
11598        synchronized (this) {
11599            if (mStackSupervisor.isUserLockedProfile(userId)) {
11600                final long ident = Binder.clearCallingIdentity();
11601                try {
11602                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11603                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11604                        // If there is no device lock, we will show the profile's credential page.
11605                        mActivityStarter.showConfirmDeviceCredential(userId);
11606                    } else {
11607                        // Showing launcher to avoid user entering credential twice.
11608                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11609                    }
11610                } finally {
11611                    Binder.restoreCallingIdentity(ident);
11612                }
11613            }
11614        }
11615    }
11616
11617    @Override
11618    public void startConfirmDeviceCredentialIntent(Intent intent) {
11619        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11620        synchronized (this) {
11621            final long ident = Binder.clearCallingIdentity();
11622            try {
11623                mActivityStarter.startConfirmCredentialIntent(intent);
11624            } finally {
11625                Binder.restoreCallingIdentity(ident);
11626            }
11627        }
11628    }
11629
11630    @Override
11631    public void stopAppSwitches() {
11632        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11633                != PackageManager.PERMISSION_GRANTED) {
11634            throw new SecurityException("viewquires permission "
11635                    + android.Manifest.permission.STOP_APP_SWITCHES);
11636        }
11637
11638        synchronized(this) {
11639            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11640                    + APP_SWITCH_DELAY_TIME;
11641            mDidAppSwitch = false;
11642            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11643            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11644            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11645        }
11646    }
11647
11648    public void resumeAppSwitches() {
11649        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11650                != PackageManager.PERMISSION_GRANTED) {
11651            throw new SecurityException("Requires permission "
11652                    + android.Manifest.permission.STOP_APP_SWITCHES);
11653        }
11654
11655        synchronized(this) {
11656            // Note that we don't execute any pending app switches... we will
11657            // let those wait until either the timeout, or the next start
11658            // activity request.
11659            mAppSwitchesAllowedTime = 0;
11660        }
11661    }
11662
11663    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11664            int callingPid, int callingUid, String name) {
11665        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11666            return true;
11667        }
11668
11669        int perm = checkComponentPermission(
11670                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11671                sourceUid, -1, true);
11672        if (perm == PackageManager.PERMISSION_GRANTED) {
11673            return true;
11674        }
11675
11676        // If the actual IPC caller is different from the logical source, then
11677        // also see if they are allowed to control app switches.
11678        if (callingUid != -1 && callingUid != sourceUid) {
11679            perm = checkComponentPermission(
11680                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11681                    callingUid, -1, true);
11682            if (perm == PackageManager.PERMISSION_GRANTED) {
11683                return true;
11684            }
11685        }
11686
11687        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11688        return false;
11689    }
11690
11691    public void setDebugApp(String packageName, boolean waitForDebugger,
11692            boolean persistent) {
11693        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11694                "setDebugApp()");
11695
11696        long ident = Binder.clearCallingIdentity();
11697        try {
11698            // Note that this is not really thread safe if there are multiple
11699            // callers into it at the same time, but that's not a situation we
11700            // care about.
11701            if (persistent) {
11702                final ContentResolver resolver = mContext.getContentResolver();
11703                Settings.Global.putString(
11704                    resolver, Settings.Global.DEBUG_APP,
11705                    packageName);
11706                Settings.Global.putInt(
11707                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11708                    waitForDebugger ? 1 : 0);
11709            }
11710
11711            synchronized (this) {
11712                if (!persistent) {
11713                    mOrigDebugApp = mDebugApp;
11714                    mOrigWaitForDebugger = mWaitForDebugger;
11715                }
11716                mDebugApp = packageName;
11717                mWaitForDebugger = waitForDebugger;
11718                mDebugTransient = !persistent;
11719                if (packageName != null) {
11720                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11721                            false, UserHandle.USER_ALL, "set debug app");
11722                }
11723            }
11724        } finally {
11725            Binder.restoreCallingIdentity(ident);
11726        }
11727    }
11728
11729    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11730        synchronized (this) {
11731            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11732            if (!isDebuggable) {
11733                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11734                    throw new SecurityException("Process not debuggable: " + app.packageName);
11735                }
11736            }
11737
11738            mTrackAllocationApp = processName;
11739        }
11740    }
11741
11742    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11743        synchronized (this) {
11744            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11745            if (!isDebuggable) {
11746                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11747                    throw new SecurityException("Process not debuggable: " + app.packageName);
11748                }
11749            }
11750            mProfileApp = processName;
11751            mProfileFile = profilerInfo.profileFile;
11752            if (mProfileFd != null) {
11753                try {
11754                    mProfileFd.close();
11755                } catch (IOException e) {
11756                }
11757                mProfileFd = null;
11758            }
11759            mProfileFd = profilerInfo.profileFd;
11760            mSamplingInterval = profilerInfo.samplingInterval;
11761            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11762            mProfileType = 0;
11763        }
11764    }
11765
11766    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11767        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11768        if (!isDebuggable) {
11769            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11770                throw new SecurityException("Process not debuggable: " + app.packageName);
11771            }
11772        }
11773        mNativeDebuggingApp = processName;
11774    }
11775
11776    @Override
11777    public void setAlwaysFinish(boolean enabled) {
11778        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11779                "setAlwaysFinish()");
11780
11781        long ident = Binder.clearCallingIdentity();
11782        try {
11783            Settings.Global.putInt(
11784                    mContext.getContentResolver(),
11785                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11786
11787            synchronized (this) {
11788                mAlwaysFinishActivities = enabled;
11789            }
11790        } finally {
11791            Binder.restoreCallingIdentity(ident);
11792        }
11793    }
11794
11795    @Override
11796    public void setLenientBackgroundCheck(boolean enabled) {
11797        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11798                "setLenientBackgroundCheck()");
11799
11800        long ident = Binder.clearCallingIdentity();
11801        try {
11802            Settings.Global.putInt(
11803                    mContext.getContentResolver(),
11804                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11805
11806            synchronized (this) {
11807                mLenientBackgroundCheck = enabled;
11808            }
11809        } finally {
11810            Binder.restoreCallingIdentity(ident);
11811        }
11812    }
11813
11814    @Override
11815    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11816        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11817                "setActivityController()");
11818        synchronized (this) {
11819            mController = controller;
11820            mControllerIsAMonkey = imAMonkey;
11821            Watchdog.getInstance().setActivityController(controller);
11822        }
11823    }
11824
11825    @Override
11826    public void setUserIsMonkey(boolean userIsMonkey) {
11827        synchronized (this) {
11828            synchronized (mPidsSelfLocked) {
11829                final int callingPid = Binder.getCallingPid();
11830                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11831                if (precessRecord == null) {
11832                    throw new SecurityException("Unknown process: " + callingPid);
11833                }
11834                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11835                    throw new SecurityException("Only an instrumentation process "
11836                            + "with a UiAutomation can call setUserIsMonkey");
11837                }
11838            }
11839            mUserIsMonkey = userIsMonkey;
11840        }
11841    }
11842
11843    @Override
11844    public boolean isUserAMonkey() {
11845        synchronized (this) {
11846            // If there is a controller also implies the user is a monkey.
11847            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11848        }
11849    }
11850
11851    public void requestBugReport(int bugreportType) {
11852        String service = null;
11853        switch (bugreportType) {
11854            case ActivityManager.BUGREPORT_OPTION_FULL:
11855                service = "bugreport";
11856                break;
11857            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11858                service = "bugreportplus";
11859                break;
11860            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11861                service = "bugreportremote";
11862                break;
11863        }
11864        if (service == null) {
11865            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11866                    + bugreportType);
11867        }
11868        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11869        SystemProperties.set("ctl.start", service);
11870    }
11871
11872    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11873        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11874    }
11875
11876    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11877        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11878            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11879        }
11880        return KEY_DISPATCHING_TIMEOUT;
11881    }
11882
11883    @Override
11884    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11885        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11886                != PackageManager.PERMISSION_GRANTED) {
11887            throw new SecurityException("Requires permission "
11888                    + android.Manifest.permission.FILTER_EVENTS);
11889        }
11890        ProcessRecord proc;
11891        long timeout;
11892        synchronized (this) {
11893            synchronized (mPidsSelfLocked) {
11894                proc = mPidsSelfLocked.get(pid);
11895            }
11896            timeout = getInputDispatchingTimeoutLocked(proc);
11897        }
11898
11899        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11900            return -1;
11901        }
11902
11903        return timeout;
11904    }
11905
11906    /**
11907     * Handle input dispatching timeouts.
11908     * Returns whether input dispatching should be aborted or not.
11909     */
11910    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11911            final ActivityRecord activity, final ActivityRecord parent,
11912            final boolean aboveSystem, String reason) {
11913        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11914                != PackageManager.PERMISSION_GRANTED) {
11915            throw new SecurityException("Requires permission "
11916                    + android.Manifest.permission.FILTER_EVENTS);
11917        }
11918
11919        final String annotation;
11920        if (reason == null) {
11921            annotation = "Input dispatching timed out";
11922        } else {
11923            annotation = "Input dispatching timed out (" + reason + ")";
11924        }
11925
11926        if (proc != null) {
11927            synchronized (this) {
11928                if (proc.debugging) {
11929                    return false;
11930                }
11931
11932                if (mDidDexOpt) {
11933                    // Give more time since we were dexopting.
11934                    mDidDexOpt = false;
11935                    return false;
11936                }
11937
11938                if (proc.instrumentationClass != null) {
11939                    Bundle info = new Bundle();
11940                    info.putString("shortMsg", "keyDispatchingTimedOut");
11941                    info.putString("longMsg", annotation);
11942                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11943                    return true;
11944                }
11945            }
11946            mHandler.post(new Runnable() {
11947                @Override
11948                public void run() {
11949                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11950                }
11951            });
11952        }
11953
11954        return true;
11955    }
11956
11957    @Override
11958    public Bundle getAssistContextExtras(int requestType) {
11959        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11960                null, null, true /* focused */, true /* newSessionId */,
11961                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11962        if (pae == null) {
11963            return null;
11964        }
11965        synchronized (pae) {
11966            while (!pae.haveResult) {
11967                try {
11968                    pae.wait();
11969                } catch (InterruptedException e) {
11970                }
11971            }
11972        }
11973        synchronized (this) {
11974            buildAssistBundleLocked(pae, pae.result);
11975            mPendingAssistExtras.remove(pae);
11976            mUiHandler.removeCallbacks(pae);
11977        }
11978        return pae.extras;
11979    }
11980
11981    @Override
11982    public boolean isAssistDataAllowedOnCurrentActivity() {
11983        int userId;
11984        synchronized (this) {
11985            userId = mUserController.getCurrentUserIdLocked();
11986            ActivityRecord activity = getFocusedStack().topActivity();
11987            if (activity == null) {
11988                return false;
11989            }
11990            userId = activity.userId;
11991        }
11992        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11993                Context.DEVICE_POLICY_SERVICE);
11994        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11995    }
11996
11997    @Override
11998    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11999        long ident = Binder.clearCallingIdentity();
12000        try {
12001            synchronized (this) {
12002                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12003                ActivityRecord top = getFocusedStack().topActivity();
12004                if (top != caller) {
12005                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12006                            + " is not current top " + top);
12007                    return false;
12008                }
12009                if (!top.nowVisible) {
12010                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12011                            + " is not visible");
12012                    return false;
12013                }
12014            }
12015            AssistUtils utils = new AssistUtils(mContext);
12016            return utils.showSessionForActiveService(args,
12017                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12018        } finally {
12019            Binder.restoreCallingIdentity(ident);
12020        }
12021    }
12022
12023    @Override
12024    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12025            Bundle receiverExtras,
12026            IBinder activityToken, boolean focused, boolean newSessionId) {
12027        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12028                activityToken, focused, newSessionId,
12029                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12030                != null;
12031    }
12032
12033    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12034            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12035            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12036        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12037                "enqueueAssistContext()");
12038        synchronized (this) {
12039            ActivityRecord activity = getFocusedStack().topActivity();
12040            if (activity == null) {
12041                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12042                return null;
12043            }
12044            if (activity.app == null || activity.app.thread == null) {
12045                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12046                return null;
12047            }
12048            if (focused) {
12049                if (activityToken != null) {
12050                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12051                    if (activity != caller) {
12052                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12053                                + " is not current top " + activity);
12054                        return null;
12055                    }
12056                }
12057            } else {
12058                activity = ActivityRecord.forTokenLocked(activityToken);
12059                if (activity == null) {
12060                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12061                            + " couldn't be found");
12062                    return null;
12063                }
12064            }
12065
12066            PendingAssistExtras pae;
12067            Bundle extras = new Bundle();
12068            if (args != null) {
12069                extras.putAll(args);
12070            }
12071            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12072            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12073            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12074                    userHandle);
12075            // Increment the sessionId if necessary
12076            if (newSessionId) {
12077                mViSessionId++;
12078            }
12079            try {
12080                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12081                        requestType, mViSessionId);
12082                mPendingAssistExtras.add(pae);
12083                mUiHandler.postDelayed(pae, timeout);
12084            } catch (RemoteException e) {
12085                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12086                return null;
12087            }
12088            return pae;
12089        }
12090    }
12091
12092    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12093        IResultReceiver receiver;
12094        synchronized (this) {
12095            mPendingAssistExtras.remove(pae);
12096            receiver = pae.receiver;
12097        }
12098        if (receiver != null) {
12099            // Caller wants result sent back to them.
12100            Bundle sendBundle = new Bundle();
12101            // At least return the receiver extras
12102            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12103                    pae.receiverExtras);
12104            try {
12105                pae.receiver.send(0, sendBundle);
12106            } catch (RemoteException e) {
12107            }
12108        }
12109    }
12110
12111    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12112        if (result != null) {
12113            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12114        }
12115        if (pae.hint != null) {
12116            pae.extras.putBoolean(pae.hint, true);
12117        }
12118    }
12119
12120    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12121            AssistContent content, Uri referrer) {
12122        PendingAssistExtras pae = (PendingAssistExtras)token;
12123        synchronized (pae) {
12124            pae.result = extras;
12125            pae.structure = structure;
12126            pae.content = content;
12127            if (referrer != null) {
12128                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12129            }
12130            pae.haveResult = true;
12131            pae.notifyAll();
12132            if (pae.intent == null && pae.receiver == null) {
12133                // Caller is just waiting for the result.
12134                return;
12135            }
12136        }
12137
12138        // We are now ready to launch the assist activity.
12139        IResultReceiver sendReceiver = null;
12140        Bundle sendBundle = null;
12141        synchronized (this) {
12142            buildAssistBundleLocked(pae, extras);
12143            boolean exists = mPendingAssistExtras.remove(pae);
12144            mUiHandler.removeCallbacks(pae);
12145            if (!exists) {
12146                // Timed out.
12147                return;
12148            }
12149            if ((sendReceiver=pae.receiver) != null) {
12150                // Caller wants result sent back to them.
12151                sendBundle = new Bundle();
12152                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12153                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12154                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12155                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12156                        pae.receiverExtras);
12157            }
12158        }
12159        if (sendReceiver != null) {
12160            try {
12161                sendReceiver.send(0, sendBundle);
12162            } catch (RemoteException e) {
12163            }
12164            return;
12165        }
12166
12167        long ident = Binder.clearCallingIdentity();
12168        try {
12169            pae.intent.replaceExtras(pae.extras);
12170            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12171                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12172                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12173            closeSystemDialogs("assist");
12174            try {
12175                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12176            } catch (ActivityNotFoundException e) {
12177                Slog.w(TAG, "No activity to handle assist action.", e);
12178            }
12179        } finally {
12180            Binder.restoreCallingIdentity(ident);
12181        }
12182    }
12183
12184    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12185            Bundle args) {
12186        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12187                true /* focused */, true /* newSessionId */,
12188                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12189    }
12190
12191    public void registerProcessObserver(IProcessObserver observer) {
12192        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12193                "registerProcessObserver()");
12194        synchronized (this) {
12195            mProcessObservers.register(observer);
12196        }
12197    }
12198
12199    @Override
12200    public void unregisterProcessObserver(IProcessObserver observer) {
12201        synchronized (this) {
12202            mProcessObservers.unregister(observer);
12203        }
12204    }
12205
12206    @Override
12207    public void registerUidObserver(IUidObserver observer, int which) {
12208        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12209                "registerUidObserver()");
12210        synchronized (this) {
12211            mUidObservers.register(observer, which);
12212        }
12213    }
12214
12215    @Override
12216    public void unregisterUidObserver(IUidObserver observer) {
12217        synchronized (this) {
12218            mUidObservers.unregister(observer);
12219        }
12220    }
12221
12222    @Override
12223    public boolean convertFromTranslucent(IBinder token) {
12224        final long origId = Binder.clearCallingIdentity();
12225        try {
12226            synchronized (this) {
12227                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12228                if (r == null) {
12229                    return false;
12230                }
12231                final boolean translucentChanged = r.changeWindowTranslucency(true);
12232                if (translucentChanged) {
12233                    r.task.stack.releaseBackgroundResources(r);
12234                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12235                }
12236                mWindowManager.setAppFullscreen(token, true);
12237                return translucentChanged;
12238            }
12239        } finally {
12240            Binder.restoreCallingIdentity(origId);
12241        }
12242    }
12243
12244    @Override
12245    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12246        final long origId = Binder.clearCallingIdentity();
12247        try {
12248            synchronized (this) {
12249                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12250                if (r == null) {
12251                    return false;
12252                }
12253                int index = r.task.mActivities.lastIndexOf(r);
12254                if (index > 0) {
12255                    ActivityRecord under = r.task.mActivities.get(index - 1);
12256                    under.returningOptions = options;
12257                }
12258                final boolean translucentChanged = r.changeWindowTranslucency(false);
12259                if (translucentChanged) {
12260                    r.task.stack.convertActivityToTranslucent(r);
12261                }
12262                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12263                mWindowManager.setAppFullscreen(token, false);
12264                return translucentChanged;
12265            }
12266        } finally {
12267            Binder.restoreCallingIdentity(origId);
12268        }
12269    }
12270
12271    @Override
12272    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12273        final long origId = Binder.clearCallingIdentity();
12274        try {
12275            synchronized (this) {
12276                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12277                if (r != null) {
12278                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12279                }
12280            }
12281            return false;
12282        } finally {
12283            Binder.restoreCallingIdentity(origId);
12284        }
12285    }
12286
12287    @Override
12288    public boolean isBackgroundVisibleBehind(IBinder token) {
12289        final long origId = Binder.clearCallingIdentity();
12290        try {
12291            synchronized (this) {
12292                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12293                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12294                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12295                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12296                return visible;
12297            }
12298        } finally {
12299            Binder.restoreCallingIdentity(origId);
12300        }
12301    }
12302
12303    @Override
12304    public ActivityOptions getActivityOptions(IBinder token) {
12305        final long origId = Binder.clearCallingIdentity();
12306        try {
12307            synchronized (this) {
12308                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12309                if (r != null) {
12310                    final ActivityOptions activityOptions = r.pendingOptions;
12311                    r.pendingOptions = null;
12312                    return activityOptions;
12313                }
12314                return null;
12315            }
12316        } finally {
12317            Binder.restoreCallingIdentity(origId);
12318        }
12319    }
12320
12321    @Override
12322    public void setImmersive(IBinder token, boolean immersive) {
12323        synchronized(this) {
12324            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12325            if (r == null) {
12326                throw new IllegalArgumentException();
12327            }
12328            r.immersive = immersive;
12329
12330            // update associated state if we're frontmost
12331            if (r == mFocusedActivity) {
12332                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12333                applyUpdateLockStateLocked(r);
12334            }
12335        }
12336    }
12337
12338    @Override
12339    public boolean isImmersive(IBinder token) {
12340        synchronized (this) {
12341            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12342            if (r == null) {
12343                throw new IllegalArgumentException();
12344            }
12345            return r.immersive;
12346        }
12347    }
12348
12349    @Override
12350    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12351        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12352            throw new UnsupportedOperationException("VR mode not supported on this device!");
12353        }
12354
12355        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12356
12357        ActivityRecord r;
12358        synchronized (this) {
12359            r = ActivityRecord.isInStackLocked(token);
12360        }
12361
12362        if (r == null) {
12363            throw new IllegalArgumentException();
12364        }
12365
12366        int err;
12367        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12368                VrManagerInternal.NO_ERROR) {
12369            return err;
12370        }
12371
12372        synchronized(this) {
12373            r.requestedVrComponent = (enabled) ? packageName : null;
12374
12375            // Update associated state if this activity is currently focused
12376            if (r == mFocusedActivity) {
12377                applyUpdateVrModeLocked(r);
12378            }
12379            return 0;
12380        }
12381    }
12382
12383    @Override
12384    public boolean isVrModePackageEnabled(ComponentName packageName) {
12385        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12386            throw new UnsupportedOperationException("VR mode not supported on this device!");
12387        }
12388
12389        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12390
12391        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12392                VrManagerInternal.NO_ERROR;
12393    }
12394
12395    public boolean isTopActivityImmersive() {
12396        enforceNotIsolatedCaller("startActivity");
12397        synchronized (this) {
12398            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12399            return (r != null) ? r.immersive : false;
12400        }
12401    }
12402
12403    @Override
12404    public boolean isTopOfTask(IBinder token) {
12405        synchronized (this) {
12406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12407            if (r == null) {
12408                throw new IllegalArgumentException();
12409            }
12410            return r.task.getTopActivity() == r;
12411        }
12412    }
12413
12414    public final void enterSafeMode() {
12415        synchronized(this) {
12416            // It only makes sense to do this before the system is ready
12417            // and started launching other packages.
12418            if (!mSystemReady) {
12419                try {
12420                    AppGlobals.getPackageManager().enterSafeMode();
12421                } catch (RemoteException e) {
12422                }
12423            }
12424
12425            mSafeMode = true;
12426        }
12427    }
12428
12429    public final void showSafeModeOverlay() {
12430        View v = LayoutInflater.from(mContext).inflate(
12431                com.android.internal.R.layout.safe_mode, null);
12432        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12433        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12434        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12435        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12436        lp.gravity = Gravity.BOTTOM | Gravity.START;
12437        lp.format = v.getBackground().getOpacity();
12438        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12439                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12440        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12441        ((WindowManager)mContext.getSystemService(
12442                Context.WINDOW_SERVICE)).addView(v, lp);
12443    }
12444
12445    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12446        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12447            return;
12448        }
12449        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12450        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12451        synchronized (stats) {
12452            if (mBatteryStatsService.isOnBattery()) {
12453                mBatteryStatsService.enforceCallingPermission();
12454                int MY_UID = Binder.getCallingUid();
12455                final int uid;
12456                if (sender == null) {
12457                    uid = sourceUid;
12458                } else {
12459                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12460                }
12461                BatteryStatsImpl.Uid.Pkg pkg =
12462                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12463                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12464                pkg.noteWakeupAlarmLocked(tag);
12465            }
12466        }
12467    }
12468
12469    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12470        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12471            return;
12472        }
12473        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12474        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12475        synchronized (stats) {
12476            mBatteryStatsService.enforceCallingPermission();
12477            int MY_UID = Binder.getCallingUid();
12478            final int uid;
12479            if (sender == null) {
12480                uid = sourceUid;
12481            } else {
12482                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12483            }
12484            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12485        }
12486    }
12487
12488    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12489        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12490            return;
12491        }
12492        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12493        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12494        synchronized (stats) {
12495            mBatteryStatsService.enforceCallingPermission();
12496            int MY_UID = Binder.getCallingUid();
12497            final int uid;
12498            if (sender == null) {
12499                uid = sourceUid;
12500            } else {
12501                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12502            }
12503            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12504        }
12505    }
12506
12507    public boolean killPids(int[] pids, String pReason, boolean secure) {
12508        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12509            throw new SecurityException("killPids only available to the system");
12510        }
12511        String reason = (pReason == null) ? "Unknown" : pReason;
12512        // XXX Note: don't acquire main activity lock here, because the window
12513        // manager calls in with its locks held.
12514
12515        boolean killed = false;
12516        synchronized (mPidsSelfLocked) {
12517            int worstType = 0;
12518            for (int i=0; i<pids.length; i++) {
12519                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12520                if (proc != null) {
12521                    int type = proc.setAdj;
12522                    if (type > worstType) {
12523                        worstType = type;
12524                    }
12525                }
12526            }
12527
12528            // If the worst oom_adj is somewhere in the cached proc LRU range,
12529            // then constrain it so we will kill all cached procs.
12530            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12531                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12532                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12533            }
12534
12535            // If this is not a secure call, don't let it kill processes that
12536            // are important.
12537            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12538                worstType = ProcessList.SERVICE_ADJ;
12539            }
12540
12541            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12542            for (int i=0; i<pids.length; i++) {
12543                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12544                if (proc == null) {
12545                    continue;
12546                }
12547                int adj = proc.setAdj;
12548                if (adj >= worstType && !proc.killedByAm) {
12549                    proc.kill(reason, true);
12550                    killed = true;
12551                }
12552            }
12553        }
12554        return killed;
12555    }
12556
12557    @Override
12558    public void killUid(int appId, int userId, String reason) {
12559        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12560        synchronized (this) {
12561            final long identity = Binder.clearCallingIdentity();
12562            try {
12563                killPackageProcessesLocked(null, appId, userId,
12564                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12565                        reason != null ? reason : "kill uid");
12566            } finally {
12567                Binder.restoreCallingIdentity(identity);
12568            }
12569        }
12570    }
12571
12572    @Override
12573    public boolean killProcessesBelowForeground(String reason) {
12574        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12575            throw new SecurityException("killProcessesBelowForeground() only available to system");
12576        }
12577
12578        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12579    }
12580
12581    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12582        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12583            throw new SecurityException("killProcessesBelowAdj() only available to system");
12584        }
12585
12586        boolean killed = false;
12587        synchronized (mPidsSelfLocked) {
12588            final int size = mPidsSelfLocked.size();
12589            for (int i = 0; i < size; i++) {
12590                final int pid = mPidsSelfLocked.keyAt(i);
12591                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12592                if (proc == null) continue;
12593
12594                final int adj = proc.setAdj;
12595                if (adj > belowAdj && !proc.killedByAm) {
12596                    proc.kill(reason, true);
12597                    killed = true;
12598                }
12599            }
12600        }
12601        return killed;
12602    }
12603
12604    @Override
12605    public void hang(final IBinder who, boolean allowRestart) {
12606        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12607                != PackageManager.PERMISSION_GRANTED) {
12608            throw new SecurityException("Requires permission "
12609                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12610        }
12611
12612        final IBinder.DeathRecipient death = new DeathRecipient() {
12613            @Override
12614            public void binderDied() {
12615                synchronized (this) {
12616                    notifyAll();
12617                }
12618            }
12619        };
12620
12621        try {
12622            who.linkToDeath(death, 0);
12623        } catch (RemoteException e) {
12624            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12625            return;
12626        }
12627
12628        synchronized (this) {
12629            Watchdog.getInstance().setAllowRestart(allowRestart);
12630            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12631            synchronized (death) {
12632                while (who.isBinderAlive()) {
12633                    try {
12634                        death.wait();
12635                    } catch (InterruptedException e) {
12636                    }
12637                }
12638            }
12639            Watchdog.getInstance().setAllowRestart(true);
12640        }
12641    }
12642
12643    @Override
12644    public void restart() {
12645        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12646                != PackageManager.PERMISSION_GRANTED) {
12647            throw new SecurityException("Requires permission "
12648                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12649        }
12650
12651        Log.i(TAG, "Sending shutdown broadcast...");
12652
12653        BroadcastReceiver br = new BroadcastReceiver() {
12654            @Override public void onReceive(Context context, Intent intent) {
12655                // Now the broadcast is done, finish up the low-level shutdown.
12656                Log.i(TAG, "Shutting down activity manager...");
12657                shutdown(10000);
12658                Log.i(TAG, "Shutdown complete, restarting!");
12659                Process.killProcess(Process.myPid());
12660                System.exit(10);
12661            }
12662        };
12663
12664        // First send the high-level shut down broadcast.
12665        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12666        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12667        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12668        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12669        mContext.sendOrderedBroadcastAsUser(intent,
12670                UserHandle.ALL, null, br, mHandler, 0, null, null);
12671        */
12672        br.onReceive(mContext, intent);
12673    }
12674
12675    private long getLowRamTimeSinceIdle(long now) {
12676        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12677    }
12678
12679    @Override
12680    public void performIdleMaintenance() {
12681        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12682                != PackageManager.PERMISSION_GRANTED) {
12683            throw new SecurityException("Requires permission "
12684                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12685        }
12686
12687        synchronized (this) {
12688            final long now = SystemClock.uptimeMillis();
12689            final long timeSinceLastIdle = now - mLastIdleTime;
12690            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12691            mLastIdleTime = now;
12692            mLowRamTimeSinceLastIdle = 0;
12693            if (mLowRamStartTime != 0) {
12694                mLowRamStartTime = now;
12695            }
12696
12697            StringBuilder sb = new StringBuilder(128);
12698            sb.append("Idle maintenance over ");
12699            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12700            sb.append(" low RAM for ");
12701            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12702            Slog.i(TAG, sb.toString());
12703
12704            // If at least 1/3 of our time since the last idle period has been spent
12705            // with RAM low, then we want to kill processes.
12706            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12707
12708            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12709                ProcessRecord proc = mLruProcesses.get(i);
12710                if (proc.notCachedSinceIdle) {
12711                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12712                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12713                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12714                        if (doKilling && proc.initialIdlePss != 0
12715                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12716                            sb = new StringBuilder(128);
12717                            sb.append("Kill");
12718                            sb.append(proc.processName);
12719                            sb.append(" in idle maint: pss=");
12720                            sb.append(proc.lastPss);
12721                            sb.append(", swapPss=");
12722                            sb.append(proc.lastSwapPss);
12723                            sb.append(", initialPss=");
12724                            sb.append(proc.initialIdlePss);
12725                            sb.append(", period=");
12726                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12727                            sb.append(", lowRamPeriod=");
12728                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12729                            Slog.wtfQuiet(TAG, sb.toString());
12730                            proc.kill("idle maint (pss " + proc.lastPss
12731                                    + " from " + proc.initialIdlePss + ")", true);
12732                        }
12733                    }
12734                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12735                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12736                    proc.notCachedSinceIdle = true;
12737                    proc.initialIdlePss = 0;
12738                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12739                            mTestPssMode, isSleeping(), now);
12740                }
12741            }
12742
12743            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12744            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12745        }
12746    }
12747
12748    @Override
12749    public void sendIdleJobTrigger() {
12750        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12751                != PackageManager.PERMISSION_GRANTED) {
12752            throw new SecurityException("Requires permission "
12753                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12754        }
12755
12756        final long ident = Binder.clearCallingIdentity();
12757        try {
12758            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12759                    .setPackage("android")
12760                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12761            broadcastIntent(null, intent, null, null, 0, null, null, null,
12762                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12763        } finally {
12764            Binder.restoreCallingIdentity(ident);
12765        }
12766    }
12767
12768    private void retrieveSettings() {
12769        final ContentResolver resolver = mContext.getContentResolver();
12770        final boolean freeformWindowManagement =
12771                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12772                        || Settings.Global.getInt(
12773                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12774        final boolean supportsPictureInPicture =
12775                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12776
12777        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12778        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12779        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12780        final boolean alwaysFinishActivities =
12781                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12782        final boolean lenientBackgroundCheck =
12783                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12784        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12785        final boolean forceResizable = Settings.Global.getInt(
12786                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12787        // Transfer any global setting for forcing RTL layout, into a System Property
12788        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12789
12790        final Configuration configuration = new Configuration();
12791        Settings.System.getConfiguration(resolver, configuration);
12792        if (forceRtl) {
12793            // This will take care of setting the correct layout direction flags
12794            configuration.setLayoutDirection(configuration.locale);
12795        }
12796
12797        synchronized (this) {
12798            mDebugApp = mOrigDebugApp = debugApp;
12799            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12800            mAlwaysFinishActivities = alwaysFinishActivities;
12801            mLenientBackgroundCheck = lenientBackgroundCheck;
12802            mForceResizableActivities = forceResizable;
12803            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12804            if (supportsMultiWindow || forceResizable) {
12805                mSupportsMultiWindow = true;
12806                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12807                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12808            } else {
12809                mSupportsMultiWindow = false;
12810                mSupportsFreeformWindowManagement = false;
12811                mSupportsPictureInPicture = false;
12812            }
12813            // This happens before any activities are started, so we can
12814            // change mConfiguration in-place.
12815            updateConfigurationLocked(configuration, null, true);
12816            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12817                    "Initial config: " + mConfiguration);
12818
12819            // Load resources only after the current configuration has been set.
12820            final Resources res = mContext.getResources();
12821            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12822            mThumbnailWidth = res.getDimensionPixelSize(
12823                    com.android.internal.R.dimen.thumbnail_width);
12824            mThumbnailHeight = res.getDimensionPixelSize(
12825                    com.android.internal.R.dimen.thumbnail_height);
12826            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12827                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12828            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12829                    com.android.internal.R.string.config_appsNotReportingCrashes));
12830            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12831                mFullscreenThumbnailScale = (float) res
12832                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12833                    (float) mConfiguration.screenWidthDp;
12834            } else {
12835                mFullscreenThumbnailScale = res.getFraction(
12836                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12837            }
12838        }
12839    }
12840
12841    public boolean testIsSystemReady() {
12842        // no need to synchronize(this) just to read & return the value
12843        return mSystemReady;
12844    }
12845
12846    public void systemReady(final Runnable goingCallback) {
12847        synchronized(this) {
12848            if (mSystemReady) {
12849                // If we're done calling all the receivers, run the next "boot phase" passed in
12850                // by the SystemServer
12851                if (goingCallback != null) {
12852                    goingCallback.run();
12853                }
12854                return;
12855            }
12856
12857            mLocalDeviceIdleController
12858                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12859
12860            // Make sure we have the current profile info, since it is needed for security checks.
12861            mUserController.onSystemReady();
12862            mRecentTasks.onSystemReadyLocked();
12863            mAppOpsService.systemReady();
12864            mSystemReady = true;
12865        }
12866
12867        ArrayList<ProcessRecord> procsToKill = null;
12868        synchronized(mPidsSelfLocked) {
12869            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12870                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12871                if (!isAllowedWhileBooting(proc.info)){
12872                    if (procsToKill == null) {
12873                        procsToKill = new ArrayList<ProcessRecord>();
12874                    }
12875                    procsToKill.add(proc);
12876                }
12877            }
12878        }
12879
12880        synchronized(this) {
12881            if (procsToKill != null) {
12882                for (int i=procsToKill.size()-1; i>=0; i--) {
12883                    ProcessRecord proc = procsToKill.get(i);
12884                    Slog.i(TAG, "Removing system update proc: " + proc);
12885                    removeProcessLocked(proc, true, false, "system update done");
12886                }
12887            }
12888
12889            // Now that we have cleaned up any update processes, we
12890            // are ready to start launching real processes and know that
12891            // we won't trample on them any more.
12892            mProcessesReady = true;
12893        }
12894
12895        Slog.i(TAG, "System now ready");
12896        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12897            SystemClock.uptimeMillis());
12898
12899        synchronized(this) {
12900            // Make sure we have no pre-ready processes sitting around.
12901
12902            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12903                ResolveInfo ri = mContext.getPackageManager()
12904                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12905                                STOCK_PM_FLAGS);
12906                CharSequence errorMsg = null;
12907                if (ri != null) {
12908                    ActivityInfo ai = ri.activityInfo;
12909                    ApplicationInfo app = ai.applicationInfo;
12910                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12911                        mTopAction = Intent.ACTION_FACTORY_TEST;
12912                        mTopData = null;
12913                        mTopComponent = new ComponentName(app.packageName,
12914                                ai.name);
12915                    } else {
12916                        errorMsg = mContext.getResources().getText(
12917                                com.android.internal.R.string.factorytest_not_system);
12918                    }
12919                } else {
12920                    errorMsg = mContext.getResources().getText(
12921                            com.android.internal.R.string.factorytest_no_action);
12922                }
12923                if (errorMsg != null) {
12924                    mTopAction = null;
12925                    mTopData = null;
12926                    mTopComponent = null;
12927                    Message msg = Message.obtain();
12928                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12929                    msg.getData().putCharSequence("msg", errorMsg);
12930                    mUiHandler.sendMessage(msg);
12931                }
12932            }
12933        }
12934
12935        retrieveSettings();
12936        final int currentUserId;
12937        synchronized (this) {
12938            currentUserId = mUserController.getCurrentUserIdLocked();
12939            readGrantedUriPermissionsLocked();
12940        }
12941
12942        if (goingCallback != null) goingCallback.run();
12943
12944        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12945                Integer.toString(currentUserId), currentUserId);
12946        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12947                Integer.toString(currentUserId), currentUserId);
12948        mSystemServiceManager.startUser(currentUserId);
12949
12950        synchronized (this) {
12951            // Only start up encryption-aware persistent apps; once user is
12952            // unlocked we'll come back around and start unaware apps
12953            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12954
12955            // Start up initial activity.
12956            mBooting = true;
12957            // Enable home activity for system user, so that the system can always boot
12958            if (UserManager.isSplitSystemUser()) {
12959                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12960                try {
12961                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12962                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12963                            UserHandle.USER_SYSTEM);
12964                } catch (RemoteException e) {
12965                    throw e.rethrowAsRuntimeException();
12966                }
12967            }
12968            startHomeActivityLocked(currentUserId, "systemReady");
12969
12970            try {
12971                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12972                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12973                            + " data partition or your device will be unstable.");
12974                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12975                }
12976            } catch (RemoteException e) {
12977            }
12978
12979            if (!Build.isBuildConsistent()) {
12980                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12981                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12982            }
12983
12984            long ident = Binder.clearCallingIdentity();
12985            try {
12986                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12987                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12988                        | Intent.FLAG_RECEIVER_FOREGROUND);
12989                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12990                broadcastIntentLocked(null, null, intent,
12991                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12992                        null, false, false, MY_PID, Process.SYSTEM_UID,
12993                        currentUserId);
12994                intent = new Intent(Intent.ACTION_USER_STARTING);
12995                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12996                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12997                broadcastIntentLocked(null, null, intent,
12998                        null, new IIntentReceiver.Stub() {
12999                            @Override
13000                            public void performReceive(Intent intent, int resultCode, String data,
13001                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13002                                    throws RemoteException {
13003                            }
13004                        }, 0, null, null,
13005                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13006                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13007            } catch (Throwable t) {
13008                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13009            } finally {
13010                Binder.restoreCallingIdentity(ident);
13011            }
13012            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13013            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13014        }
13015    }
13016
13017    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13018        synchronized (this) {
13019            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13020        }
13021    }
13022
13023    void skipCurrentReceiverLocked(ProcessRecord app) {
13024        for (BroadcastQueue queue : mBroadcastQueues) {
13025            queue.skipCurrentReceiverLocked(app);
13026        }
13027    }
13028
13029    /**
13030     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13031     * The application process will exit immediately after this call returns.
13032     * @param app object of the crashing app, null for the system server
13033     * @param crashInfo describing the exception
13034     */
13035    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13036        ProcessRecord r = findAppProcess(app, "Crash");
13037        final String processName = app == null ? "system_server"
13038                : (r == null ? "unknown" : r.processName);
13039
13040        handleApplicationCrashInner("crash", r, processName, crashInfo);
13041    }
13042
13043    /* Native crash reporting uses this inner version because it needs to be somewhat
13044     * decoupled from the AM-managed cleanup lifecycle
13045     */
13046    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13047            ApplicationErrorReport.CrashInfo crashInfo) {
13048        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13049                UserHandle.getUserId(Binder.getCallingUid()), processName,
13050                r == null ? -1 : r.info.flags,
13051                crashInfo.exceptionClassName,
13052                crashInfo.exceptionMessage,
13053                crashInfo.throwFileName,
13054                crashInfo.throwLineNumber);
13055
13056        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13057
13058        mAppErrors.crashApplication(r, crashInfo);
13059    }
13060
13061    public void handleApplicationStrictModeViolation(
13062            IBinder app,
13063            int violationMask,
13064            StrictMode.ViolationInfo info) {
13065        ProcessRecord r = findAppProcess(app, "StrictMode");
13066        if (r == null) {
13067            return;
13068        }
13069
13070        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13071            Integer stackFingerprint = info.hashCode();
13072            boolean logIt = true;
13073            synchronized (mAlreadyLoggedViolatedStacks) {
13074                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13075                    logIt = false;
13076                    // TODO: sub-sample into EventLog for these, with
13077                    // the info.durationMillis?  Then we'd get
13078                    // the relative pain numbers, without logging all
13079                    // the stack traces repeatedly.  We'd want to do
13080                    // likewise in the client code, which also does
13081                    // dup suppression, before the Binder call.
13082                } else {
13083                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13084                        mAlreadyLoggedViolatedStacks.clear();
13085                    }
13086                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13087                }
13088            }
13089            if (logIt) {
13090                logStrictModeViolationToDropBox(r, info);
13091            }
13092        }
13093
13094        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13095            AppErrorResult result = new AppErrorResult();
13096            synchronized (this) {
13097                final long origId = Binder.clearCallingIdentity();
13098
13099                Message msg = Message.obtain();
13100                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13101                HashMap<String, Object> data = new HashMap<String, Object>();
13102                data.put("result", result);
13103                data.put("app", r);
13104                data.put("violationMask", violationMask);
13105                data.put("info", info);
13106                msg.obj = data;
13107                mUiHandler.sendMessage(msg);
13108
13109                Binder.restoreCallingIdentity(origId);
13110            }
13111            int res = result.get();
13112            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13113        }
13114    }
13115
13116    // Depending on the policy in effect, there could be a bunch of
13117    // these in quick succession so we try to batch these together to
13118    // minimize disk writes, number of dropbox entries, and maximize
13119    // compression, by having more fewer, larger records.
13120    private void logStrictModeViolationToDropBox(
13121            ProcessRecord process,
13122            StrictMode.ViolationInfo info) {
13123        if (info == null) {
13124            return;
13125        }
13126        final boolean isSystemApp = process == null ||
13127                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13128                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13129        final String processName = process == null ? "unknown" : process.processName;
13130        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13131        final DropBoxManager dbox = (DropBoxManager)
13132                mContext.getSystemService(Context.DROPBOX_SERVICE);
13133
13134        // Exit early if the dropbox isn't configured to accept this report type.
13135        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13136
13137        boolean bufferWasEmpty;
13138        boolean needsFlush;
13139        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13140        synchronized (sb) {
13141            bufferWasEmpty = sb.length() == 0;
13142            appendDropBoxProcessHeaders(process, processName, sb);
13143            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13144            sb.append("System-App: ").append(isSystemApp).append("\n");
13145            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13146            if (info.violationNumThisLoop != 0) {
13147                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13148            }
13149            if (info.numAnimationsRunning != 0) {
13150                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13151            }
13152            if (info.broadcastIntentAction != null) {
13153                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13154            }
13155            if (info.durationMillis != -1) {
13156                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13157            }
13158            if (info.numInstances != -1) {
13159                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13160            }
13161            if (info.tags != null) {
13162                for (String tag : info.tags) {
13163                    sb.append("Span-Tag: ").append(tag).append("\n");
13164                }
13165            }
13166            sb.append("\n");
13167            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13168                sb.append(info.crashInfo.stackTrace);
13169                sb.append("\n");
13170            }
13171            if (info.message != null) {
13172                sb.append(info.message);
13173                sb.append("\n");
13174            }
13175
13176            // Only buffer up to ~64k.  Various logging bits truncate
13177            // things at 128k.
13178            needsFlush = (sb.length() > 64 * 1024);
13179        }
13180
13181        // Flush immediately if the buffer's grown too large, or this
13182        // is a non-system app.  Non-system apps are isolated with a
13183        // different tag & policy and not batched.
13184        //
13185        // Batching is useful during internal testing with
13186        // StrictMode settings turned up high.  Without batching,
13187        // thousands of separate files could be created on boot.
13188        if (!isSystemApp || needsFlush) {
13189            new Thread("Error dump: " + dropboxTag) {
13190                @Override
13191                public void run() {
13192                    String report;
13193                    synchronized (sb) {
13194                        report = sb.toString();
13195                        sb.delete(0, sb.length());
13196                        sb.trimToSize();
13197                    }
13198                    if (report.length() != 0) {
13199                        dbox.addText(dropboxTag, report);
13200                    }
13201                }
13202            }.start();
13203            return;
13204        }
13205
13206        // System app batching:
13207        if (!bufferWasEmpty) {
13208            // An existing dropbox-writing thread is outstanding, so
13209            // we don't need to start it up.  The existing thread will
13210            // catch the buffer appends we just did.
13211            return;
13212        }
13213
13214        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13215        // (After this point, we shouldn't access AMS internal data structures.)
13216        new Thread("Error dump: " + dropboxTag) {
13217            @Override
13218            public void run() {
13219                // 5 second sleep to let stacks arrive and be batched together
13220                try {
13221                    Thread.sleep(5000);  // 5 seconds
13222                } catch (InterruptedException e) {}
13223
13224                String errorReport;
13225                synchronized (mStrictModeBuffer) {
13226                    errorReport = mStrictModeBuffer.toString();
13227                    if (errorReport.length() == 0) {
13228                        return;
13229                    }
13230                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13231                    mStrictModeBuffer.trimToSize();
13232                }
13233                dbox.addText(dropboxTag, errorReport);
13234            }
13235        }.start();
13236    }
13237
13238    /**
13239     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13240     * @param app object of the crashing app, null for the system server
13241     * @param tag reported by the caller
13242     * @param system whether this wtf is coming from the system
13243     * @param crashInfo describing the context of the error
13244     * @return true if the process should exit immediately (WTF is fatal)
13245     */
13246    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13247            final ApplicationErrorReport.CrashInfo crashInfo) {
13248        final int callingUid = Binder.getCallingUid();
13249        final int callingPid = Binder.getCallingPid();
13250
13251        if (system) {
13252            // If this is coming from the system, we could very well have low-level
13253            // system locks held, so we want to do this all asynchronously.  And we
13254            // never want this to become fatal, so there is that too.
13255            mHandler.post(new Runnable() {
13256                @Override public void run() {
13257                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13258                }
13259            });
13260            return false;
13261        }
13262
13263        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13264                crashInfo);
13265
13266        if (r != null && r.pid != Process.myPid() &&
13267                Settings.Global.getInt(mContext.getContentResolver(),
13268                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13269            mAppErrors.crashApplication(r, crashInfo);
13270            return true;
13271        } else {
13272            return false;
13273        }
13274    }
13275
13276    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13277            final ApplicationErrorReport.CrashInfo crashInfo) {
13278        final ProcessRecord r = findAppProcess(app, "WTF");
13279        final String processName = app == null ? "system_server"
13280                : (r == null ? "unknown" : r.processName);
13281
13282        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13283                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13284
13285        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13286
13287        return r;
13288    }
13289
13290    /**
13291     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13292     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13293     */
13294    private ProcessRecord findAppProcess(IBinder app, String reason) {
13295        if (app == null) {
13296            return null;
13297        }
13298
13299        synchronized (this) {
13300            final int NP = mProcessNames.getMap().size();
13301            for (int ip=0; ip<NP; ip++) {
13302                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13303                final int NA = apps.size();
13304                for (int ia=0; ia<NA; ia++) {
13305                    ProcessRecord p = apps.valueAt(ia);
13306                    if (p.thread != null && p.thread.asBinder() == app) {
13307                        return p;
13308                    }
13309                }
13310            }
13311
13312            Slog.w(TAG, "Can't find mystery application for " + reason
13313                    + " from pid=" + Binder.getCallingPid()
13314                    + " uid=" + Binder.getCallingUid() + ": " + app);
13315            return null;
13316        }
13317    }
13318
13319    /**
13320     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13321     * to append various headers to the dropbox log text.
13322     */
13323    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13324            StringBuilder sb) {
13325        // Watchdog thread ends up invoking this function (with
13326        // a null ProcessRecord) to add the stack file to dropbox.
13327        // Do not acquire a lock on this (am) in such cases, as it
13328        // could cause a potential deadlock, if and when watchdog
13329        // is invoked due to unavailability of lock on am and it
13330        // would prevent watchdog from killing system_server.
13331        if (process == null) {
13332            sb.append("Process: ").append(processName).append("\n");
13333            return;
13334        }
13335        // Note: ProcessRecord 'process' is guarded by the service
13336        // instance.  (notably process.pkgList, which could otherwise change
13337        // concurrently during execution of this method)
13338        synchronized (this) {
13339            sb.append("Process: ").append(processName).append("\n");
13340            int flags = process.info.flags;
13341            IPackageManager pm = AppGlobals.getPackageManager();
13342            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13343            for (int ip=0; ip<process.pkgList.size(); ip++) {
13344                String pkg = process.pkgList.keyAt(ip);
13345                sb.append("Package: ").append(pkg);
13346                try {
13347                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13348                    if (pi != null) {
13349                        sb.append(" v").append(pi.versionCode);
13350                        if (pi.versionName != null) {
13351                            sb.append(" (").append(pi.versionName).append(")");
13352                        }
13353                    }
13354                } catch (RemoteException e) {
13355                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13356                }
13357                sb.append("\n");
13358            }
13359        }
13360    }
13361
13362    private static String processClass(ProcessRecord process) {
13363        if (process == null || process.pid == MY_PID) {
13364            return "system_server";
13365        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13366            return "system_app";
13367        } else {
13368            return "data_app";
13369        }
13370    }
13371
13372    private volatile long mWtfClusterStart;
13373    private volatile int mWtfClusterCount;
13374
13375    /**
13376     * Write a description of an error (crash, WTF, ANR) to the drop box.
13377     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13378     * @param process which caused the error, null means the system server
13379     * @param activity which triggered the error, null if unknown
13380     * @param parent activity related to the error, null if unknown
13381     * @param subject line related to the error, null if absent
13382     * @param report in long form describing the error, null if absent
13383     * @param logFile to include in the report, null if none
13384     * @param crashInfo giving an application stack trace, null if absent
13385     */
13386    public void addErrorToDropBox(String eventType,
13387            ProcessRecord process, String processName, ActivityRecord activity,
13388            ActivityRecord parent, String subject,
13389            final String report, final File logFile,
13390            final ApplicationErrorReport.CrashInfo crashInfo) {
13391        // NOTE -- this must never acquire the ActivityManagerService lock,
13392        // otherwise the watchdog may be prevented from resetting the system.
13393
13394        final String dropboxTag = processClass(process) + "_" + eventType;
13395        final DropBoxManager dbox = (DropBoxManager)
13396                mContext.getSystemService(Context.DROPBOX_SERVICE);
13397
13398        // Exit early if the dropbox isn't configured to accept this report type.
13399        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13400
13401        // Rate-limit how often we're willing to do the heavy lifting below to
13402        // collect and record logs; currently 5 logs per 10 second period.
13403        final long now = SystemClock.elapsedRealtime();
13404        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13405            mWtfClusterStart = now;
13406            mWtfClusterCount = 1;
13407        } else {
13408            if (mWtfClusterCount++ >= 5) return;
13409        }
13410
13411        final StringBuilder sb = new StringBuilder(1024);
13412        appendDropBoxProcessHeaders(process, processName, sb);
13413        if (process != null) {
13414            sb.append("Foreground: ")
13415                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13416                    .append("\n");
13417        }
13418        if (activity != null) {
13419            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13420        }
13421        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13422            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13423        }
13424        if (parent != null && parent != activity) {
13425            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13426        }
13427        if (subject != null) {
13428            sb.append("Subject: ").append(subject).append("\n");
13429        }
13430        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13431        if (Debug.isDebuggerConnected()) {
13432            sb.append("Debugger: Connected\n");
13433        }
13434        sb.append("\n");
13435
13436        // Do the rest in a worker thread to avoid blocking the caller on I/O
13437        // (After this point, we shouldn't access AMS internal data structures.)
13438        Thread worker = new Thread("Error dump: " + dropboxTag) {
13439            @Override
13440            public void run() {
13441                if (report != null) {
13442                    sb.append(report);
13443                }
13444                if (logFile != null) {
13445                    try {
13446                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13447                                    "\n\n[[TRUNCATED]]"));
13448                    } catch (IOException e) {
13449                        Slog.e(TAG, "Error reading " + logFile, e);
13450                    }
13451                }
13452                if (crashInfo != null && crashInfo.stackTrace != null) {
13453                    sb.append(crashInfo.stackTrace);
13454                }
13455
13456                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13457                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13458                if (lines > 0) {
13459                    sb.append("\n");
13460
13461                    // Merge several logcat streams, and take the last N lines
13462                    InputStreamReader input = null;
13463                    try {
13464                        java.lang.Process logcat = new ProcessBuilder(
13465                                "/system/bin/timeout", "-k", "15s", "10s",
13466                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13467                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13468                                        .redirectErrorStream(true).start();
13469
13470                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13471                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13472                        input = new InputStreamReader(logcat.getInputStream());
13473
13474                        int num;
13475                        char[] buf = new char[8192];
13476                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13477                    } catch (IOException e) {
13478                        Slog.e(TAG, "Error running logcat", e);
13479                    } finally {
13480                        if (input != null) try { input.close(); } catch (IOException e) {}
13481                    }
13482                }
13483
13484                dbox.addText(dropboxTag, sb.toString());
13485            }
13486        };
13487
13488        if (process == null) {
13489            // If process is null, we are being called from some internal code
13490            // and may be about to die -- run this synchronously.
13491            worker.run();
13492        } else {
13493            worker.start();
13494        }
13495    }
13496
13497    @Override
13498    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13499        enforceNotIsolatedCaller("getProcessesInErrorState");
13500        // assume our apps are happy - lazy create the list
13501        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13502
13503        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13504                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13505        int userId = UserHandle.getUserId(Binder.getCallingUid());
13506
13507        synchronized (this) {
13508
13509            // iterate across all processes
13510            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13511                ProcessRecord app = mLruProcesses.get(i);
13512                if (!allUsers && app.userId != userId) {
13513                    continue;
13514                }
13515                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13516                    // This one's in trouble, so we'll generate a report for it
13517                    // crashes are higher priority (in case there's a crash *and* an anr)
13518                    ActivityManager.ProcessErrorStateInfo report = null;
13519                    if (app.crashing) {
13520                        report = app.crashingReport;
13521                    } else if (app.notResponding) {
13522                        report = app.notRespondingReport;
13523                    }
13524
13525                    if (report != null) {
13526                        if (errList == null) {
13527                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13528                        }
13529                        errList.add(report);
13530                    } else {
13531                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13532                                " crashing = " + app.crashing +
13533                                " notResponding = " + app.notResponding);
13534                    }
13535                }
13536            }
13537        }
13538
13539        return errList;
13540    }
13541
13542    static int procStateToImportance(int procState, int memAdj,
13543            ActivityManager.RunningAppProcessInfo currApp) {
13544        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13545        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13546            currApp.lru = memAdj;
13547        } else {
13548            currApp.lru = 0;
13549        }
13550        return imp;
13551    }
13552
13553    private void fillInProcMemInfo(ProcessRecord app,
13554            ActivityManager.RunningAppProcessInfo outInfo) {
13555        outInfo.pid = app.pid;
13556        outInfo.uid = app.info.uid;
13557        if (mHeavyWeightProcess == app) {
13558            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13559        }
13560        if (app.persistent) {
13561            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13562        }
13563        if (app.activities.size() > 0) {
13564            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13565        }
13566        outInfo.lastTrimLevel = app.trimMemoryLevel;
13567        int adj = app.curAdj;
13568        int procState = app.curProcState;
13569        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13570        outInfo.importanceReasonCode = app.adjTypeCode;
13571        outInfo.processState = app.curProcState;
13572    }
13573
13574    @Override
13575    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13576        enforceNotIsolatedCaller("getRunningAppProcesses");
13577
13578        final int callingUid = Binder.getCallingUid();
13579
13580        // Lazy instantiation of list
13581        List<ActivityManager.RunningAppProcessInfo> runList = null;
13582        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13583                callingUid) == PackageManager.PERMISSION_GRANTED;
13584        final int userId = UserHandle.getUserId(callingUid);
13585        final boolean allUids = isGetTasksAllowed(
13586                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13587
13588        synchronized (this) {
13589            // Iterate across all processes
13590            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13591                ProcessRecord app = mLruProcesses.get(i);
13592                if ((!allUsers && app.userId != userId)
13593                        || (!allUids && app.uid != callingUid)) {
13594                    continue;
13595                }
13596                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13597                    // Generate process state info for running application
13598                    ActivityManager.RunningAppProcessInfo currApp =
13599                        new ActivityManager.RunningAppProcessInfo(app.processName,
13600                                app.pid, app.getPackageList());
13601                    fillInProcMemInfo(app, currApp);
13602                    if (app.adjSource instanceof ProcessRecord) {
13603                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13604                        currApp.importanceReasonImportance =
13605                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13606                                        app.adjSourceProcState);
13607                    } else if (app.adjSource instanceof ActivityRecord) {
13608                        ActivityRecord r = (ActivityRecord)app.adjSource;
13609                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13610                    }
13611                    if (app.adjTarget instanceof ComponentName) {
13612                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13613                    }
13614                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13615                    //        + " lru=" + currApp.lru);
13616                    if (runList == null) {
13617                        runList = new ArrayList<>();
13618                    }
13619                    runList.add(currApp);
13620                }
13621            }
13622        }
13623        return runList;
13624    }
13625
13626    @Override
13627    public List<ApplicationInfo> getRunningExternalApplications() {
13628        enforceNotIsolatedCaller("getRunningExternalApplications");
13629        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13630        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13631        if (runningApps != null && runningApps.size() > 0) {
13632            Set<String> extList = new HashSet<String>();
13633            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13634                if (app.pkgList != null) {
13635                    for (String pkg : app.pkgList) {
13636                        extList.add(pkg);
13637                    }
13638                }
13639            }
13640            IPackageManager pm = AppGlobals.getPackageManager();
13641            for (String pkg : extList) {
13642                try {
13643                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13644                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13645                        retList.add(info);
13646                    }
13647                } catch (RemoteException e) {
13648                }
13649            }
13650        }
13651        return retList;
13652    }
13653
13654    @Override
13655    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13656        enforceNotIsolatedCaller("getMyMemoryState");
13657        synchronized (this) {
13658            ProcessRecord proc;
13659            synchronized (mPidsSelfLocked) {
13660                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13661            }
13662            fillInProcMemInfo(proc, outInfo);
13663        }
13664    }
13665
13666    @Override
13667    public int getMemoryTrimLevel() {
13668        enforceNotIsolatedCaller("getMyMemoryState");
13669        synchronized (this) {
13670            return mLastMemoryLevel;
13671        }
13672    }
13673
13674    @Override
13675    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13676            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13677        (new ActivityManagerShellCommand(this, false)).exec(
13678                this, in, out, err, args, resultReceiver);
13679    }
13680
13681    @Override
13682    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13683        if (checkCallingPermission(android.Manifest.permission.DUMP)
13684                != PackageManager.PERMISSION_GRANTED) {
13685            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13686                    + Binder.getCallingPid()
13687                    + ", uid=" + Binder.getCallingUid()
13688                    + " without permission "
13689                    + android.Manifest.permission.DUMP);
13690            return;
13691        }
13692
13693        boolean dumpAll = false;
13694        boolean dumpClient = false;
13695        String dumpPackage = null;
13696
13697        int opti = 0;
13698        while (opti < args.length) {
13699            String opt = args[opti];
13700            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13701                break;
13702            }
13703            opti++;
13704            if ("-a".equals(opt)) {
13705                dumpAll = true;
13706            } else if ("-c".equals(opt)) {
13707                dumpClient = true;
13708            } else if ("-p".equals(opt)) {
13709                if (opti < args.length) {
13710                    dumpPackage = args[opti];
13711                    opti++;
13712                } else {
13713                    pw.println("Error: -p option requires package argument");
13714                    return;
13715                }
13716                dumpClient = true;
13717            } else if ("-h".equals(opt)) {
13718                ActivityManagerShellCommand.dumpHelp(pw, true);
13719                return;
13720            } else {
13721                pw.println("Unknown argument: " + opt + "; use -h for help");
13722            }
13723        }
13724
13725        long origId = Binder.clearCallingIdentity();
13726        boolean more = false;
13727        // Is the caller requesting to dump a particular piece of data?
13728        if (opti < args.length) {
13729            String cmd = args[opti];
13730            opti++;
13731            if ("activities".equals(cmd) || "a".equals(cmd)) {
13732                synchronized (this) {
13733                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13734                }
13735            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13736                synchronized (this) {
13737                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13738                }
13739            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13740                String[] newArgs;
13741                String name;
13742                if (opti >= args.length) {
13743                    name = null;
13744                    newArgs = EMPTY_STRING_ARRAY;
13745                } else {
13746                    dumpPackage = args[opti];
13747                    opti++;
13748                    newArgs = new String[args.length - opti];
13749                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13750                            args.length - opti);
13751                }
13752                synchronized (this) {
13753                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13754                }
13755            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13756                String[] newArgs;
13757                String name;
13758                if (opti >= args.length) {
13759                    name = null;
13760                    newArgs = EMPTY_STRING_ARRAY;
13761                } else {
13762                    dumpPackage = args[opti];
13763                    opti++;
13764                    newArgs = new String[args.length - opti];
13765                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13766                            args.length - opti);
13767                }
13768                synchronized (this) {
13769                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13770                }
13771            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13772                String[] newArgs;
13773                String name;
13774                if (opti >= args.length) {
13775                    name = null;
13776                    newArgs = EMPTY_STRING_ARRAY;
13777                } else {
13778                    dumpPackage = args[opti];
13779                    opti++;
13780                    newArgs = new String[args.length - opti];
13781                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13782                            args.length - opti);
13783                }
13784                synchronized (this) {
13785                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13786                }
13787            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13788                synchronized (this) {
13789                    dumpOomLocked(fd, pw, args, opti, true);
13790                }
13791            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13792                synchronized (this) {
13793                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13794                }
13795            } else if ("provider".equals(cmd)) {
13796                String[] newArgs;
13797                String name;
13798                if (opti >= args.length) {
13799                    name = null;
13800                    newArgs = EMPTY_STRING_ARRAY;
13801                } else {
13802                    name = args[opti];
13803                    opti++;
13804                    newArgs = new String[args.length - opti];
13805                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13806                }
13807                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13808                    pw.println("No providers match: " + name);
13809                    pw.println("Use -h for help.");
13810                }
13811            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13812                synchronized (this) {
13813                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13814                }
13815            } else if ("service".equals(cmd)) {
13816                String[] newArgs;
13817                String name;
13818                if (opti >= args.length) {
13819                    name = null;
13820                    newArgs = EMPTY_STRING_ARRAY;
13821                } else {
13822                    name = args[opti];
13823                    opti++;
13824                    newArgs = new String[args.length - opti];
13825                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13826                            args.length - opti);
13827                }
13828                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13829                    pw.println("No services match: " + name);
13830                    pw.println("Use -h for help.");
13831                }
13832            } else if ("package".equals(cmd)) {
13833                String[] newArgs;
13834                if (opti >= args.length) {
13835                    pw.println("package: no package name specified");
13836                    pw.println("Use -h for help.");
13837                } else {
13838                    dumpPackage = args[opti];
13839                    opti++;
13840                    newArgs = new String[args.length - opti];
13841                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13842                            args.length - opti);
13843                    args = newArgs;
13844                    opti = 0;
13845                    more = true;
13846                }
13847            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13848                synchronized (this) {
13849                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13850                }
13851            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13852                if (dumpClient) {
13853                    ActiveServices.ServiceDumper dumper;
13854                    synchronized (this) {
13855                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13856                                dumpPackage);
13857                    }
13858                    dumper.dumpWithClient();
13859                } else {
13860                    synchronized (this) {
13861                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13862                                dumpPackage).dumpLocked();
13863                    }
13864                }
13865            } else if ("locks".equals(cmd)) {
13866                LockGuard.dump(fd, pw, args);
13867            } else {
13868                // Dumping a single activity?
13869                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13870                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13871                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13872                    if (res < 0) {
13873                        pw.println("Bad activity command, or no activities match: " + cmd);
13874                        pw.println("Use -h for help.");
13875                    }
13876                }
13877            }
13878            if (!more) {
13879                Binder.restoreCallingIdentity(origId);
13880                return;
13881            }
13882        }
13883
13884        // No piece of data specified, dump everything.
13885        if (dumpClient) {
13886            ActiveServices.ServiceDumper sdumper;
13887            synchronized (this) {
13888                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13889                pw.println();
13890                if (dumpAll) {
13891                    pw.println("-------------------------------------------------------------------------------");
13892                }
13893                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13894                pw.println();
13895                if (dumpAll) {
13896                    pw.println("-------------------------------------------------------------------------------");
13897                }
13898                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13899                pw.println();
13900                if (dumpAll) {
13901                    pw.println("-------------------------------------------------------------------------------");
13902                }
13903                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13904                pw.println();
13905                if (dumpAll) {
13906                    pw.println("-------------------------------------------------------------------------------");
13907                }
13908                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13909                        dumpPackage);
13910            }
13911            sdumper.dumpWithClient();
13912            pw.println();
13913            synchronized (this) {
13914                if (dumpAll) {
13915                    pw.println("-------------------------------------------------------------------------------");
13916                }
13917                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13918                pw.println();
13919                if (dumpAll) {
13920                    pw.println("-------------------------------------------------------------------------------");
13921                }
13922                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13923                if (mAssociations.size() > 0) {
13924                    pw.println();
13925                    if (dumpAll) {
13926                        pw.println("-------------------------------------------------------------------------------");
13927                    }
13928                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13929                }
13930                pw.println();
13931                if (dumpAll) {
13932                    pw.println("-------------------------------------------------------------------------------");
13933                }
13934                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13935            }
13936
13937        } else {
13938            synchronized (this) {
13939                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13940                pw.println();
13941                if (dumpAll) {
13942                    pw.println("-------------------------------------------------------------------------------");
13943                }
13944                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13945                pw.println();
13946                if (dumpAll) {
13947                    pw.println("-------------------------------------------------------------------------------");
13948                }
13949                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13950                pw.println();
13951                if (dumpAll) {
13952                    pw.println("-------------------------------------------------------------------------------");
13953                }
13954                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13955                pw.println();
13956                if (dumpAll) {
13957                    pw.println("-------------------------------------------------------------------------------");
13958                }
13959                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13960                        .dumpLocked();
13961                pw.println();
13962                if (dumpAll) {
13963                    pw.println("-------------------------------------------------------------------------------");
13964                }
13965                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13966                pw.println();
13967                if (dumpAll) {
13968                    pw.println("-------------------------------------------------------------------------------");
13969                }
13970                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13971                if (mAssociations.size() > 0) {
13972                    pw.println();
13973                    if (dumpAll) {
13974                        pw.println("-------------------------------------------------------------------------------");
13975                    }
13976                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13977                }
13978                pw.println();
13979                if (dumpAll) {
13980                    pw.println("-------------------------------------------------------------------------------");
13981                }
13982                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13983            }
13984        }
13985        Binder.restoreCallingIdentity(origId);
13986    }
13987
13988    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13989            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13990        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13991
13992        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13993                dumpPackage);
13994        boolean needSep = printedAnything;
13995
13996        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13997                dumpPackage, needSep, "  mFocusedActivity: ");
13998        if (printed) {
13999            printedAnything = true;
14000            needSep = false;
14001        }
14002
14003        if (dumpPackage == null) {
14004            if (needSep) {
14005                pw.println();
14006            }
14007            needSep = true;
14008            printedAnything = true;
14009            mStackSupervisor.dump(pw, "  ");
14010        }
14011
14012        if (!printedAnything) {
14013            pw.println("  (nothing)");
14014        }
14015    }
14016
14017    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14018            int opti, boolean dumpAll, String dumpPackage) {
14019        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14020
14021        boolean printedAnything = false;
14022
14023        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14024            boolean printedHeader = false;
14025
14026            final int N = mRecentTasks.size();
14027            for (int i=0; i<N; i++) {
14028                TaskRecord tr = mRecentTasks.get(i);
14029                if (dumpPackage != null) {
14030                    if (tr.realActivity == null ||
14031                            !dumpPackage.equals(tr.realActivity)) {
14032                        continue;
14033                    }
14034                }
14035                if (!printedHeader) {
14036                    pw.println("  Recent tasks:");
14037                    printedHeader = true;
14038                    printedAnything = true;
14039                }
14040                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14041                        pw.println(tr);
14042                if (dumpAll) {
14043                    mRecentTasks.get(i).dump(pw, "    ");
14044                }
14045            }
14046        }
14047
14048        if (!printedAnything) {
14049            pw.println("  (nothing)");
14050        }
14051    }
14052
14053    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14054            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14055        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14056
14057        int dumpUid = 0;
14058        if (dumpPackage != null) {
14059            IPackageManager pm = AppGlobals.getPackageManager();
14060            try {
14061                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14062            } catch (RemoteException e) {
14063            }
14064        }
14065
14066        boolean printedAnything = false;
14067
14068        final long now = SystemClock.uptimeMillis();
14069
14070        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14071            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14072                    = mAssociations.valueAt(i1);
14073            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14074                SparseArray<ArrayMap<String, Association>> sourceUids
14075                        = targetComponents.valueAt(i2);
14076                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14077                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14078                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14079                        Association ass = sourceProcesses.valueAt(i4);
14080                        if (dumpPackage != null) {
14081                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14082                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14083                                continue;
14084                            }
14085                        }
14086                        printedAnything = true;
14087                        pw.print("  ");
14088                        pw.print(ass.mTargetProcess);
14089                        pw.print("/");
14090                        UserHandle.formatUid(pw, ass.mTargetUid);
14091                        pw.print(" <- ");
14092                        pw.print(ass.mSourceProcess);
14093                        pw.print("/");
14094                        UserHandle.formatUid(pw, ass.mSourceUid);
14095                        pw.println();
14096                        pw.print("    via ");
14097                        pw.print(ass.mTargetComponent.flattenToShortString());
14098                        pw.println();
14099                        pw.print("    ");
14100                        long dur = ass.mTime;
14101                        if (ass.mNesting > 0) {
14102                            dur += now - ass.mStartTime;
14103                        }
14104                        TimeUtils.formatDuration(dur, pw);
14105                        pw.print(" (");
14106                        pw.print(ass.mCount);
14107                        pw.print(" times)");
14108                        pw.print("  ");
14109                        for (int i=0; i<ass.mStateTimes.length; i++) {
14110                            long amt = ass.mStateTimes[i];
14111                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14112                                amt += now - ass.mLastStateUptime;
14113                            }
14114                            if (amt != 0) {
14115                                pw.print(" ");
14116                                pw.print(ProcessList.makeProcStateString(
14117                                            i + ActivityManager.MIN_PROCESS_STATE));
14118                                pw.print("=");
14119                                TimeUtils.formatDuration(amt, pw);
14120                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14121                                    pw.print("*");
14122                                }
14123                            }
14124                        }
14125                        pw.println();
14126                        if (ass.mNesting > 0) {
14127                            pw.print("    Currently active: ");
14128                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14129                            pw.println();
14130                        }
14131                    }
14132                }
14133            }
14134
14135        }
14136
14137        if (!printedAnything) {
14138            pw.println("  (nothing)");
14139        }
14140    }
14141
14142    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14143            String header, boolean needSep) {
14144        boolean printed = false;
14145        int whichAppId = -1;
14146        if (dumpPackage != null) {
14147            try {
14148                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14149                        dumpPackage, 0);
14150                whichAppId = UserHandle.getAppId(info.uid);
14151            } catch (NameNotFoundException e) {
14152                e.printStackTrace();
14153            }
14154        }
14155        for (int i=0; i<uids.size(); i++) {
14156            UidRecord uidRec = uids.valueAt(i);
14157            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14158                continue;
14159            }
14160            if (!printed) {
14161                printed = true;
14162                if (needSep) {
14163                    pw.println();
14164                }
14165                pw.print("  ");
14166                pw.println(header);
14167                needSep = true;
14168            }
14169            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14170            pw.print(": "); pw.println(uidRec);
14171        }
14172        return printed;
14173    }
14174
14175    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14176            int opti, boolean dumpAll, String dumpPackage) {
14177        boolean needSep = false;
14178        boolean printedAnything = false;
14179        int numPers = 0;
14180
14181        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14182
14183        if (dumpAll) {
14184            final int NP = mProcessNames.getMap().size();
14185            for (int ip=0; ip<NP; ip++) {
14186                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14187                final int NA = procs.size();
14188                for (int ia=0; ia<NA; ia++) {
14189                    ProcessRecord r = procs.valueAt(ia);
14190                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14191                        continue;
14192                    }
14193                    if (!needSep) {
14194                        pw.println("  All known processes:");
14195                        needSep = true;
14196                        printedAnything = true;
14197                    }
14198                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14199                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14200                        pw.print(" "); pw.println(r);
14201                    r.dump(pw, "    ");
14202                    if (r.persistent) {
14203                        numPers++;
14204                    }
14205                }
14206            }
14207        }
14208
14209        if (mIsolatedProcesses.size() > 0) {
14210            boolean printed = false;
14211            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14212                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14213                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14214                    continue;
14215                }
14216                if (!printed) {
14217                    if (needSep) {
14218                        pw.println();
14219                    }
14220                    pw.println("  Isolated process list (sorted by uid):");
14221                    printedAnything = true;
14222                    printed = true;
14223                    needSep = true;
14224                }
14225                pw.println(String.format("%sIsolated #%2d: %s",
14226                        "    ", i, r.toString()));
14227            }
14228        }
14229
14230        if (mActiveUids.size() > 0) {
14231            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14232                printedAnything = needSep = true;
14233            }
14234        }
14235        if (mValidateUids.size() > 0) {
14236            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14237                printedAnything = needSep = true;
14238            }
14239        }
14240
14241        if (mLruProcesses.size() > 0) {
14242            if (needSep) {
14243                pw.println();
14244            }
14245            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14246                    pw.print(" total, non-act at ");
14247                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14248                    pw.print(", non-svc at ");
14249                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14250                    pw.println("):");
14251            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14252            needSep = true;
14253            printedAnything = true;
14254        }
14255
14256        if (dumpAll || dumpPackage != null) {
14257            synchronized (mPidsSelfLocked) {
14258                boolean printed = false;
14259                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14260                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14261                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14262                        continue;
14263                    }
14264                    if (!printed) {
14265                        if (needSep) pw.println();
14266                        needSep = true;
14267                        pw.println("  PID mappings:");
14268                        printed = true;
14269                        printedAnything = true;
14270                    }
14271                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14272                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14273                }
14274            }
14275        }
14276
14277        if (mForegroundProcesses.size() > 0) {
14278            synchronized (mPidsSelfLocked) {
14279                boolean printed = false;
14280                for (int i=0; i<mForegroundProcesses.size(); i++) {
14281                    ProcessRecord r = mPidsSelfLocked.get(
14282                            mForegroundProcesses.valueAt(i).pid);
14283                    if (dumpPackage != null && (r == null
14284                            || !r.pkgList.containsKey(dumpPackage))) {
14285                        continue;
14286                    }
14287                    if (!printed) {
14288                        if (needSep) pw.println();
14289                        needSep = true;
14290                        pw.println("  Foreground Processes:");
14291                        printed = true;
14292                        printedAnything = true;
14293                    }
14294                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14295                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14296                }
14297            }
14298        }
14299
14300        if (mPersistentStartingProcesses.size() > 0) {
14301            if (needSep) pw.println();
14302            needSep = true;
14303            printedAnything = true;
14304            pw.println("  Persisent processes that are starting:");
14305            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14306                    "Starting Norm", "Restarting PERS", dumpPackage);
14307        }
14308
14309        if (mRemovedProcesses.size() > 0) {
14310            if (needSep) pw.println();
14311            needSep = true;
14312            printedAnything = true;
14313            pw.println("  Processes that are being removed:");
14314            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14315                    "Removed Norm", "Removed PERS", dumpPackage);
14316        }
14317
14318        if (mProcessesOnHold.size() > 0) {
14319            if (needSep) pw.println();
14320            needSep = true;
14321            printedAnything = true;
14322            pw.println("  Processes that are on old until the system is ready:");
14323            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14324                    "OnHold Norm", "OnHold PERS", dumpPackage);
14325        }
14326
14327        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14328
14329        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14330        if (needSep) {
14331            printedAnything = true;
14332        }
14333
14334        if (dumpPackage == null) {
14335            pw.println();
14336            needSep = false;
14337            mUserController.dump(pw, dumpAll);
14338        }
14339        if (mHomeProcess != null && (dumpPackage == null
14340                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14341            if (needSep) {
14342                pw.println();
14343                needSep = false;
14344            }
14345            pw.println("  mHomeProcess: " + mHomeProcess);
14346        }
14347        if (mPreviousProcess != null && (dumpPackage == null
14348                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14349            if (needSep) {
14350                pw.println();
14351                needSep = false;
14352            }
14353            pw.println("  mPreviousProcess: " + mPreviousProcess);
14354        }
14355        if (dumpAll) {
14356            StringBuilder sb = new StringBuilder(128);
14357            sb.append("  mPreviousProcessVisibleTime: ");
14358            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14359            pw.println(sb);
14360        }
14361        if (mHeavyWeightProcess != null && (dumpPackage == null
14362                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14363            if (needSep) {
14364                pw.println();
14365                needSep = false;
14366            }
14367            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14368        }
14369        if (dumpPackage == null) {
14370            pw.println("  mConfiguration: " + mConfiguration);
14371        }
14372        if (dumpAll) {
14373            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14374            if (mCompatModePackages.getPackages().size() > 0) {
14375                boolean printed = false;
14376                for (Map.Entry<String, Integer> entry
14377                        : mCompatModePackages.getPackages().entrySet()) {
14378                    String pkg = entry.getKey();
14379                    int mode = entry.getValue();
14380                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14381                        continue;
14382                    }
14383                    if (!printed) {
14384                        pw.println("  mScreenCompatPackages:");
14385                        printed = true;
14386                    }
14387                    pw.print("    "); pw.print(pkg); pw.print(": ");
14388                            pw.print(mode); pw.println();
14389                }
14390            }
14391        }
14392        if (dumpPackage == null) {
14393            pw.println("  mWakefulness="
14394                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14395            pw.println("  mSleepTokens=" + mSleepTokens);
14396            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14397                    + lockScreenShownToString());
14398            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14399            if (mRunningVoice != null) {
14400                pw.println("  mRunningVoice=" + mRunningVoice);
14401                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14402            }
14403        }
14404        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14405                || mOrigWaitForDebugger) {
14406            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14407                    || dumpPackage.equals(mOrigDebugApp)) {
14408                if (needSep) {
14409                    pw.println();
14410                    needSep = false;
14411                }
14412                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14413                        + " mDebugTransient=" + mDebugTransient
14414                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14415            }
14416        }
14417        if (mCurAppTimeTracker != null) {
14418            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14419        }
14420        if (mMemWatchProcesses.getMap().size() > 0) {
14421            pw.println("  Mem watch processes:");
14422            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14423                    = mMemWatchProcesses.getMap();
14424            for (int i=0; i<procs.size(); i++) {
14425                final String proc = procs.keyAt(i);
14426                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14427                for (int j=0; j<uids.size(); j++) {
14428                    if (needSep) {
14429                        pw.println();
14430                        needSep = false;
14431                    }
14432                    StringBuilder sb = new StringBuilder();
14433                    sb.append("    ").append(proc).append('/');
14434                    UserHandle.formatUid(sb, uids.keyAt(j));
14435                    Pair<Long, String> val = uids.valueAt(j);
14436                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14437                    if (val.second != null) {
14438                        sb.append(", report to ").append(val.second);
14439                    }
14440                    pw.println(sb.toString());
14441                }
14442            }
14443            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14444            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14445            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14446                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14447        }
14448        if (mTrackAllocationApp != null) {
14449            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14450                if (needSep) {
14451                    pw.println();
14452                    needSep = false;
14453                }
14454                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14455            }
14456        }
14457        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14458                || mProfileFd != null) {
14459            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14460                if (needSep) {
14461                    pw.println();
14462                    needSep = false;
14463                }
14464                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14465                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14466                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14467                        + mAutoStopProfiler);
14468                pw.println("  mProfileType=" + mProfileType);
14469            }
14470        }
14471        if (mNativeDebuggingApp != null) {
14472            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14473                if (needSep) {
14474                    pw.println();
14475                    needSep = false;
14476                }
14477                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14478            }
14479        }
14480        if (dumpPackage == null) {
14481            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14482                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14483                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14484            }
14485            if (mController != null) {
14486                pw.println("  mController=" + mController
14487                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14488            }
14489            if (dumpAll) {
14490                pw.println("  Total persistent processes: " + numPers);
14491                pw.println("  mProcessesReady=" + mProcessesReady
14492                        + " mSystemReady=" + mSystemReady
14493                        + " mBooted=" + mBooted
14494                        + " mFactoryTest=" + mFactoryTest);
14495                pw.println("  mBooting=" + mBooting
14496                        + " mCallFinishBooting=" + mCallFinishBooting
14497                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14498                pw.print("  mLastPowerCheckRealtime=");
14499                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14500                        pw.println("");
14501                pw.print("  mLastPowerCheckUptime=");
14502                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14503                        pw.println("");
14504                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14505                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14506                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14507                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14508                        + " (" + mLruProcesses.size() + " total)"
14509                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14510                        + " mNumServiceProcs=" + mNumServiceProcs
14511                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14512                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14513                        + " mLastMemoryLevel=" + mLastMemoryLevel
14514                        + " mLastNumProcesses=" + mLastNumProcesses);
14515                long now = SystemClock.uptimeMillis();
14516                pw.print("  mLastIdleTime=");
14517                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14518                        pw.print(" mLowRamSinceLastIdle=");
14519                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14520                        pw.println();
14521            }
14522        }
14523
14524        if (!printedAnything) {
14525            pw.println("  (nothing)");
14526        }
14527    }
14528
14529    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14530            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14531        if (mProcessesToGc.size() > 0) {
14532            boolean printed = false;
14533            long now = SystemClock.uptimeMillis();
14534            for (int i=0; i<mProcessesToGc.size(); i++) {
14535                ProcessRecord proc = mProcessesToGc.get(i);
14536                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14537                    continue;
14538                }
14539                if (!printed) {
14540                    if (needSep) pw.println();
14541                    needSep = true;
14542                    pw.println("  Processes that are waiting to GC:");
14543                    printed = true;
14544                }
14545                pw.print("    Process "); pw.println(proc);
14546                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14547                        pw.print(", last gced=");
14548                        pw.print(now-proc.lastRequestedGc);
14549                        pw.print(" ms ago, last lowMem=");
14550                        pw.print(now-proc.lastLowMemory);
14551                        pw.println(" ms ago");
14552
14553            }
14554        }
14555        return needSep;
14556    }
14557
14558    void printOomLevel(PrintWriter pw, String name, int adj) {
14559        pw.print("    ");
14560        if (adj >= 0) {
14561            pw.print(' ');
14562            if (adj < 10) pw.print(' ');
14563        } else {
14564            if (adj > -10) pw.print(' ');
14565        }
14566        pw.print(adj);
14567        pw.print(": ");
14568        pw.print(name);
14569        pw.print(" (");
14570        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14571        pw.println(")");
14572    }
14573
14574    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14575            int opti, boolean dumpAll) {
14576        boolean needSep = false;
14577
14578        if (mLruProcesses.size() > 0) {
14579            if (needSep) pw.println();
14580            needSep = true;
14581            pw.println("  OOM levels:");
14582            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14583            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14584            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14585            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14586            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14587            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14588            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14589            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14590            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14591            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14592            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14593            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14594            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14595            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14596
14597            if (needSep) pw.println();
14598            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14599                    pw.print(" total, non-act at ");
14600                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14601                    pw.print(", non-svc at ");
14602                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14603                    pw.println("):");
14604            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14605            needSep = true;
14606        }
14607
14608        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14609
14610        pw.println();
14611        pw.println("  mHomeProcess: " + mHomeProcess);
14612        pw.println("  mPreviousProcess: " + mPreviousProcess);
14613        if (mHeavyWeightProcess != null) {
14614            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14615        }
14616
14617        return true;
14618    }
14619
14620    /**
14621     * There are three ways to call this:
14622     *  - no provider specified: dump all the providers
14623     *  - a flattened component name that matched an existing provider was specified as the
14624     *    first arg: dump that one provider
14625     *  - the first arg isn't the flattened component name of an existing provider:
14626     *    dump all providers whose component contains the first arg as a substring
14627     */
14628    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14629            int opti, boolean dumpAll) {
14630        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14631    }
14632
14633    static class ItemMatcher {
14634        ArrayList<ComponentName> components;
14635        ArrayList<String> strings;
14636        ArrayList<Integer> objects;
14637        boolean all;
14638
14639        ItemMatcher() {
14640            all = true;
14641        }
14642
14643        void build(String name) {
14644            ComponentName componentName = ComponentName.unflattenFromString(name);
14645            if (componentName != null) {
14646                if (components == null) {
14647                    components = new ArrayList<ComponentName>();
14648                }
14649                components.add(componentName);
14650                all = false;
14651            } else {
14652                int objectId = 0;
14653                // Not a '/' separated full component name; maybe an object ID?
14654                try {
14655                    objectId = Integer.parseInt(name, 16);
14656                    if (objects == null) {
14657                        objects = new ArrayList<Integer>();
14658                    }
14659                    objects.add(objectId);
14660                    all = false;
14661                } catch (RuntimeException e) {
14662                    // Not an integer; just do string match.
14663                    if (strings == null) {
14664                        strings = new ArrayList<String>();
14665                    }
14666                    strings.add(name);
14667                    all = false;
14668                }
14669            }
14670        }
14671
14672        int build(String[] args, int opti) {
14673            for (; opti<args.length; opti++) {
14674                String name = args[opti];
14675                if ("--".equals(name)) {
14676                    return opti+1;
14677                }
14678                build(name);
14679            }
14680            return opti;
14681        }
14682
14683        boolean match(Object object, ComponentName comp) {
14684            if (all) {
14685                return true;
14686            }
14687            if (components != null) {
14688                for (int i=0; i<components.size(); i++) {
14689                    if (components.get(i).equals(comp)) {
14690                        return true;
14691                    }
14692                }
14693            }
14694            if (objects != null) {
14695                for (int i=0; i<objects.size(); i++) {
14696                    if (System.identityHashCode(object) == objects.get(i)) {
14697                        return true;
14698                    }
14699                }
14700            }
14701            if (strings != null) {
14702                String flat = comp.flattenToString();
14703                for (int i=0; i<strings.size(); i++) {
14704                    if (flat.contains(strings.get(i))) {
14705                        return true;
14706                    }
14707                }
14708            }
14709            return false;
14710        }
14711    }
14712
14713    /**
14714     * There are three things that cmd can be:
14715     *  - a flattened component name that matches an existing activity
14716     *  - the cmd arg isn't the flattened component name of an existing activity:
14717     *    dump all activity whose component contains the cmd as a substring
14718     *  - A hex number of the ActivityRecord object instance.
14719     */
14720    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14721            int opti, boolean dumpAll) {
14722        ArrayList<ActivityRecord> activities;
14723
14724        synchronized (this) {
14725            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14726        }
14727
14728        if (activities.size() <= 0) {
14729            return false;
14730        }
14731
14732        String[] newArgs = new String[args.length - opti];
14733        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14734
14735        TaskRecord lastTask = null;
14736        boolean needSep = false;
14737        for (int i=activities.size()-1; i>=0; i--) {
14738            ActivityRecord r = activities.get(i);
14739            if (needSep) {
14740                pw.println();
14741            }
14742            needSep = true;
14743            synchronized (this) {
14744                if (lastTask != r.task) {
14745                    lastTask = r.task;
14746                    pw.print("TASK "); pw.print(lastTask.affinity);
14747                            pw.print(" id="); pw.println(lastTask.taskId);
14748                    if (dumpAll) {
14749                        lastTask.dump(pw, "  ");
14750                    }
14751                }
14752            }
14753            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14754        }
14755        return true;
14756    }
14757
14758    /**
14759     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14760     * there is a thread associated with the activity.
14761     */
14762    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14763            final ActivityRecord r, String[] args, boolean dumpAll) {
14764        String innerPrefix = prefix + "  ";
14765        synchronized (this) {
14766            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14767                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14768                    pw.print(" pid=");
14769                    if (r.app != null) pw.println(r.app.pid);
14770                    else pw.println("(not running)");
14771            if (dumpAll) {
14772                r.dump(pw, innerPrefix);
14773            }
14774        }
14775        if (r.app != null && r.app.thread != null) {
14776            // flush anything that is already in the PrintWriter since the thread is going
14777            // to write to the file descriptor directly
14778            pw.flush();
14779            try {
14780                TransferPipe tp = new TransferPipe();
14781                try {
14782                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14783                            r.appToken, innerPrefix, args);
14784                    tp.go(fd);
14785                } finally {
14786                    tp.kill();
14787                }
14788            } catch (IOException e) {
14789                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14790            } catch (RemoteException e) {
14791                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14792            }
14793        }
14794    }
14795
14796    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14797            int opti, boolean dumpAll, String dumpPackage) {
14798        boolean needSep = false;
14799        boolean onlyHistory = false;
14800        boolean printedAnything = false;
14801
14802        if ("history".equals(dumpPackage)) {
14803            if (opti < args.length && "-s".equals(args[opti])) {
14804                dumpAll = false;
14805            }
14806            onlyHistory = true;
14807            dumpPackage = null;
14808        }
14809
14810        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14811        if (!onlyHistory && dumpAll) {
14812            if (mRegisteredReceivers.size() > 0) {
14813                boolean printed = false;
14814                Iterator it = mRegisteredReceivers.values().iterator();
14815                while (it.hasNext()) {
14816                    ReceiverList r = (ReceiverList)it.next();
14817                    if (dumpPackage != null && (r.app == null ||
14818                            !dumpPackage.equals(r.app.info.packageName))) {
14819                        continue;
14820                    }
14821                    if (!printed) {
14822                        pw.println("  Registered Receivers:");
14823                        needSep = true;
14824                        printed = true;
14825                        printedAnything = true;
14826                    }
14827                    pw.print("  * "); pw.println(r);
14828                    r.dump(pw, "    ");
14829                }
14830            }
14831
14832            if (mReceiverResolver.dump(pw, needSep ?
14833                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14834                    "    ", dumpPackage, false, false)) {
14835                needSep = true;
14836                printedAnything = true;
14837            }
14838        }
14839
14840        for (BroadcastQueue q : mBroadcastQueues) {
14841            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14842            printedAnything |= needSep;
14843        }
14844
14845        needSep = true;
14846
14847        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14848            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14849                if (needSep) {
14850                    pw.println();
14851                }
14852                needSep = true;
14853                printedAnything = true;
14854                pw.print("  Sticky broadcasts for user ");
14855                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14856                StringBuilder sb = new StringBuilder(128);
14857                for (Map.Entry<String, ArrayList<Intent>> ent
14858                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14859                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14860                    if (dumpAll) {
14861                        pw.println(":");
14862                        ArrayList<Intent> intents = ent.getValue();
14863                        final int N = intents.size();
14864                        for (int i=0; i<N; i++) {
14865                            sb.setLength(0);
14866                            sb.append("    Intent: ");
14867                            intents.get(i).toShortString(sb, false, true, false, false);
14868                            pw.println(sb.toString());
14869                            Bundle bundle = intents.get(i).getExtras();
14870                            if (bundle != null) {
14871                                pw.print("      ");
14872                                pw.println(bundle.toString());
14873                            }
14874                        }
14875                    } else {
14876                        pw.println("");
14877                    }
14878                }
14879            }
14880        }
14881
14882        if (!onlyHistory && dumpAll) {
14883            pw.println();
14884            for (BroadcastQueue queue : mBroadcastQueues) {
14885                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14886                        + queue.mBroadcastsScheduled);
14887            }
14888            pw.println("  mHandler:");
14889            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14890            needSep = true;
14891            printedAnything = true;
14892        }
14893
14894        if (!printedAnything) {
14895            pw.println("  (nothing)");
14896        }
14897    }
14898
14899    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14900            int opti, boolean dumpAll, String dumpPackage) {
14901        boolean needSep;
14902        boolean printedAnything = false;
14903
14904        ItemMatcher matcher = new ItemMatcher();
14905        matcher.build(args, opti);
14906
14907        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14908
14909        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14910        printedAnything |= needSep;
14911
14912        if (mLaunchingProviders.size() > 0) {
14913            boolean printed = false;
14914            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14915                ContentProviderRecord r = mLaunchingProviders.get(i);
14916                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14917                    continue;
14918                }
14919                if (!printed) {
14920                    if (needSep) pw.println();
14921                    needSep = true;
14922                    pw.println("  Launching content providers:");
14923                    printed = true;
14924                    printedAnything = true;
14925                }
14926                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14927                        pw.println(r);
14928            }
14929        }
14930
14931        if (!printedAnything) {
14932            pw.println("  (nothing)");
14933        }
14934    }
14935
14936    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14937            int opti, boolean dumpAll, String dumpPackage) {
14938        boolean needSep = false;
14939        boolean printedAnything = false;
14940
14941        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14942
14943        if (mGrantedUriPermissions.size() > 0) {
14944            boolean printed = false;
14945            int dumpUid = -2;
14946            if (dumpPackage != null) {
14947                try {
14948                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14949                            MATCH_UNINSTALLED_PACKAGES, 0);
14950                } catch (NameNotFoundException e) {
14951                    dumpUid = -1;
14952                }
14953            }
14954            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14955                int uid = mGrantedUriPermissions.keyAt(i);
14956                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14957                    continue;
14958                }
14959                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14960                if (!printed) {
14961                    if (needSep) pw.println();
14962                    needSep = true;
14963                    pw.println("  Granted Uri Permissions:");
14964                    printed = true;
14965                    printedAnything = true;
14966                }
14967                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14968                for (UriPermission perm : perms.values()) {
14969                    pw.print("    "); pw.println(perm);
14970                    if (dumpAll) {
14971                        perm.dump(pw, "      ");
14972                    }
14973                }
14974            }
14975        }
14976
14977        if (!printedAnything) {
14978            pw.println("  (nothing)");
14979        }
14980    }
14981
14982    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14983            int opti, boolean dumpAll, String dumpPackage) {
14984        boolean printed = false;
14985
14986        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14987
14988        if (mIntentSenderRecords.size() > 0) {
14989            Iterator<WeakReference<PendingIntentRecord>> it
14990                    = mIntentSenderRecords.values().iterator();
14991            while (it.hasNext()) {
14992                WeakReference<PendingIntentRecord> ref = it.next();
14993                PendingIntentRecord rec = ref != null ? ref.get(): null;
14994                if (dumpPackage != null && (rec == null
14995                        || !dumpPackage.equals(rec.key.packageName))) {
14996                    continue;
14997                }
14998                printed = true;
14999                if (rec != null) {
15000                    pw.print("  * "); pw.println(rec);
15001                    if (dumpAll) {
15002                        rec.dump(pw, "    ");
15003                    }
15004                } else {
15005                    pw.print("  * "); pw.println(ref);
15006                }
15007            }
15008        }
15009
15010        if (!printed) {
15011            pw.println("  (nothing)");
15012        }
15013    }
15014
15015    private static final int dumpProcessList(PrintWriter pw,
15016            ActivityManagerService service, List list,
15017            String prefix, String normalLabel, String persistentLabel,
15018            String dumpPackage) {
15019        int numPers = 0;
15020        final int N = list.size()-1;
15021        for (int i=N; i>=0; i--) {
15022            ProcessRecord r = (ProcessRecord)list.get(i);
15023            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15024                continue;
15025            }
15026            pw.println(String.format("%s%s #%2d: %s",
15027                    prefix, (r.persistent ? persistentLabel : normalLabel),
15028                    i, r.toString()));
15029            if (r.persistent) {
15030                numPers++;
15031            }
15032        }
15033        return numPers;
15034    }
15035
15036    private static final boolean dumpProcessOomList(PrintWriter pw,
15037            ActivityManagerService service, List<ProcessRecord> origList,
15038            String prefix, String normalLabel, String persistentLabel,
15039            boolean inclDetails, String dumpPackage) {
15040
15041        ArrayList<Pair<ProcessRecord, Integer>> list
15042                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15043        for (int i=0; i<origList.size(); i++) {
15044            ProcessRecord r = origList.get(i);
15045            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15046                continue;
15047            }
15048            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15049        }
15050
15051        if (list.size() <= 0) {
15052            return false;
15053        }
15054
15055        Comparator<Pair<ProcessRecord, Integer>> comparator
15056                = new Comparator<Pair<ProcessRecord, Integer>>() {
15057            @Override
15058            public int compare(Pair<ProcessRecord, Integer> object1,
15059                    Pair<ProcessRecord, Integer> object2) {
15060                if (object1.first.setAdj != object2.first.setAdj) {
15061                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15062                }
15063                if (object1.first.setProcState != object2.first.setProcState) {
15064                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15065                }
15066                if (object1.second.intValue() != object2.second.intValue()) {
15067                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15068                }
15069                return 0;
15070            }
15071        };
15072
15073        Collections.sort(list, comparator);
15074
15075        final long curRealtime = SystemClock.elapsedRealtime();
15076        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15077        final long curUptime = SystemClock.uptimeMillis();
15078        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15079
15080        for (int i=list.size()-1; i>=0; i--) {
15081            ProcessRecord r = list.get(i).first;
15082            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15083            char schedGroup;
15084            switch (r.setSchedGroup) {
15085                case ProcessList.SCHED_GROUP_BACKGROUND:
15086                    schedGroup = 'B';
15087                    break;
15088                case ProcessList.SCHED_GROUP_DEFAULT:
15089                    schedGroup = 'F';
15090                    break;
15091                case ProcessList.SCHED_GROUP_TOP_APP:
15092                    schedGroup = 'T';
15093                    break;
15094                default:
15095                    schedGroup = '?';
15096                    break;
15097            }
15098            char foreground;
15099            if (r.foregroundActivities) {
15100                foreground = 'A';
15101            } else if (r.foregroundServices) {
15102                foreground = 'S';
15103            } else {
15104                foreground = ' ';
15105            }
15106            String procState = ProcessList.makeProcStateString(r.curProcState);
15107            pw.print(prefix);
15108            pw.print(r.persistent ? persistentLabel : normalLabel);
15109            pw.print(" #");
15110            int num = (origList.size()-1)-list.get(i).second;
15111            if (num < 10) pw.print(' ');
15112            pw.print(num);
15113            pw.print(": ");
15114            pw.print(oomAdj);
15115            pw.print(' ');
15116            pw.print(schedGroup);
15117            pw.print('/');
15118            pw.print(foreground);
15119            pw.print('/');
15120            pw.print(procState);
15121            pw.print(" trm:");
15122            if (r.trimMemoryLevel < 10) pw.print(' ');
15123            pw.print(r.trimMemoryLevel);
15124            pw.print(' ');
15125            pw.print(r.toShortString());
15126            pw.print(" (");
15127            pw.print(r.adjType);
15128            pw.println(')');
15129            if (r.adjSource != null || r.adjTarget != null) {
15130                pw.print(prefix);
15131                pw.print("    ");
15132                if (r.adjTarget instanceof ComponentName) {
15133                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15134                } else if (r.adjTarget != null) {
15135                    pw.print(r.adjTarget.toString());
15136                } else {
15137                    pw.print("{null}");
15138                }
15139                pw.print("<=");
15140                if (r.adjSource instanceof ProcessRecord) {
15141                    pw.print("Proc{");
15142                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15143                    pw.println("}");
15144                } else if (r.adjSource != null) {
15145                    pw.println(r.adjSource.toString());
15146                } else {
15147                    pw.println("{null}");
15148                }
15149            }
15150            if (inclDetails) {
15151                pw.print(prefix);
15152                pw.print("    ");
15153                pw.print("oom: max="); pw.print(r.maxAdj);
15154                pw.print(" curRaw="); pw.print(r.curRawAdj);
15155                pw.print(" setRaw="); pw.print(r.setRawAdj);
15156                pw.print(" cur="); pw.print(r.curAdj);
15157                pw.print(" set="); pw.println(r.setAdj);
15158                pw.print(prefix);
15159                pw.print("    ");
15160                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15161                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15162                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15163                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15164                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15165                pw.println();
15166                pw.print(prefix);
15167                pw.print("    ");
15168                pw.print("cached="); pw.print(r.cached);
15169                pw.print(" empty="); pw.print(r.empty);
15170                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15171
15172                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15173                    if (r.lastWakeTime != 0) {
15174                        long wtime;
15175                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15176                        synchronized (stats) {
15177                            wtime = stats.getProcessWakeTime(r.info.uid,
15178                                    r.pid, curRealtime);
15179                        }
15180                        long timeUsed = wtime - r.lastWakeTime;
15181                        pw.print(prefix);
15182                        pw.print("    ");
15183                        pw.print("keep awake over ");
15184                        TimeUtils.formatDuration(realtimeSince, pw);
15185                        pw.print(" used ");
15186                        TimeUtils.formatDuration(timeUsed, pw);
15187                        pw.print(" (");
15188                        pw.print((timeUsed*100)/realtimeSince);
15189                        pw.println("%)");
15190                    }
15191                    if (r.lastCpuTime != 0) {
15192                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15193                        pw.print(prefix);
15194                        pw.print("    ");
15195                        pw.print("run cpu over ");
15196                        TimeUtils.formatDuration(uptimeSince, pw);
15197                        pw.print(" used ");
15198                        TimeUtils.formatDuration(timeUsed, pw);
15199                        pw.print(" (");
15200                        pw.print((timeUsed*100)/uptimeSince);
15201                        pw.println("%)");
15202                    }
15203                }
15204            }
15205        }
15206        return true;
15207    }
15208
15209    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15210            String[] args) {
15211        ArrayList<ProcessRecord> procs;
15212        synchronized (this) {
15213            if (args != null && args.length > start
15214                    && args[start].charAt(0) != '-') {
15215                procs = new ArrayList<ProcessRecord>();
15216                int pid = -1;
15217                try {
15218                    pid = Integer.parseInt(args[start]);
15219                } catch (NumberFormatException e) {
15220                }
15221                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15222                    ProcessRecord proc = mLruProcesses.get(i);
15223                    if (proc.pid == pid) {
15224                        procs.add(proc);
15225                    } else if (allPkgs && proc.pkgList != null
15226                            && proc.pkgList.containsKey(args[start])) {
15227                        procs.add(proc);
15228                    } else if (proc.processName.equals(args[start])) {
15229                        procs.add(proc);
15230                    }
15231                }
15232                if (procs.size() <= 0) {
15233                    return null;
15234                }
15235            } else {
15236                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15237            }
15238        }
15239        return procs;
15240    }
15241
15242    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15243            PrintWriter pw, String[] args) {
15244        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15245        if (procs == null) {
15246            pw.println("No process found for: " + args[0]);
15247            return;
15248        }
15249
15250        long uptime = SystemClock.uptimeMillis();
15251        long realtime = SystemClock.elapsedRealtime();
15252        pw.println("Applications Graphics Acceleration Info:");
15253        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15254
15255        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15256            ProcessRecord r = procs.get(i);
15257            if (r.thread != null) {
15258                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15259                pw.flush();
15260                try {
15261                    TransferPipe tp = new TransferPipe();
15262                    try {
15263                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15264                        tp.go(fd);
15265                    } finally {
15266                        tp.kill();
15267                    }
15268                } catch (IOException e) {
15269                    pw.println("Failure while dumping the app: " + r);
15270                    pw.flush();
15271                } catch (RemoteException e) {
15272                    pw.println("Got a RemoteException while dumping the app " + r);
15273                    pw.flush();
15274                }
15275            }
15276        }
15277    }
15278
15279    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15280        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15281        if (procs == null) {
15282            pw.println("No process found for: " + args[0]);
15283            return;
15284        }
15285
15286        pw.println("Applications Database Info:");
15287
15288        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15289            ProcessRecord r = procs.get(i);
15290            if (r.thread != null) {
15291                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15292                pw.flush();
15293                try {
15294                    TransferPipe tp = new TransferPipe();
15295                    try {
15296                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15297                        tp.go(fd);
15298                    } finally {
15299                        tp.kill();
15300                    }
15301                } catch (IOException e) {
15302                    pw.println("Failure while dumping the app: " + r);
15303                    pw.flush();
15304                } catch (RemoteException e) {
15305                    pw.println("Got a RemoteException while dumping the app " + r);
15306                    pw.flush();
15307                }
15308            }
15309        }
15310    }
15311
15312    final static class MemItem {
15313        final boolean isProc;
15314        final String label;
15315        final String shortLabel;
15316        final long pss;
15317        final long swapPss;
15318        final int id;
15319        final boolean hasActivities;
15320        ArrayList<MemItem> subitems;
15321
15322        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15323                boolean _hasActivities) {
15324            isProc = true;
15325            label = _label;
15326            shortLabel = _shortLabel;
15327            pss = _pss;
15328            swapPss = _swapPss;
15329            id = _id;
15330            hasActivities = _hasActivities;
15331        }
15332
15333        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15334            isProc = false;
15335            label = _label;
15336            shortLabel = _shortLabel;
15337            pss = _pss;
15338            swapPss = _swapPss;
15339            id = _id;
15340            hasActivities = false;
15341        }
15342    }
15343
15344    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15345            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15346        if (sort && !isCompact) {
15347            Collections.sort(items, new Comparator<MemItem>() {
15348                @Override
15349                public int compare(MemItem lhs, MemItem rhs) {
15350                    if (lhs.pss < rhs.pss) {
15351                        return 1;
15352                    } else if (lhs.pss > rhs.pss) {
15353                        return -1;
15354                    }
15355                    return 0;
15356                }
15357            });
15358        }
15359
15360        for (int i=0; i<items.size(); i++) {
15361            MemItem mi = items.get(i);
15362            if (!isCompact) {
15363                if (dumpSwapPss) {
15364                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15365                            mi.label, stringifyKBSize(mi.swapPss));
15366                } else {
15367                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15368                }
15369            } else if (mi.isProc) {
15370                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15371                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15372                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15373                pw.println(mi.hasActivities ? ",a" : ",e");
15374            } else {
15375                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15376                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15377            }
15378            if (mi.subitems != null) {
15379                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15380                        true, isCompact, dumpSwapPss);
15381            }
15382        }
15383    }
15384
15385    // These are in KB.
15386    static final long[] DUMP_MEM_BUCKETS = new long[] {
15387        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15388        120*1024, 160*1024, 200*1024,
15389        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15390        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15391    };
15392
15393    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15394            boolean stackLike) {
15395        int start = label.lastIndexOf('.');
15396        if (start >= 0) start++;
15397        else start = 0;
15398        int end = label.length();
15399        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15400            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15401                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15402                out.append(bucket);
15403                out.append(stackLike ? "MB." : "MB ");
15404                out.append(label, start, end);
15405                return;
15406            }
15407        }
15408        out.append(memKB/1024);
15409        out.append(stackLike ? "MB." : "MB ");
15410        out.append(label, start, end);
15411    }
15412
15413    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15414            ProcessList.NATIVE_ADJ,
15415            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15416            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15417            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15418            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15419            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15420            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15421    };
15422    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15423            "Native",
15424            "System", "Persistent", "Persistent Service", "Foreground",
15425            "Visible", "Perceptible",
15426            "Heavy Weight", "Backup",
15427            "A Services", "Home",
15428            "Previous", "B Services", "Cached"
15429    };
15430    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15431            "native",
15432            "sys", "pers", "persvc", "fore",
15433            "vis", "percept",
15434            "heavy", "backup",
15435            "servicea", "home",
15436            "prev", "serviceb", "cached"
15437    };
15438
15439    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15440            long realtime, boolean isCheckinRequest, boolean isCompact) {
15441        if (isCompact) {
15442            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15443        }
15444        if (isCheckinRequest || isCompact) {
15445            // short checkin version
15446            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15447        } else {
15448            pw.println("Applications Memory Usage (in Kilobytes):");
15449            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15450        }
15451    }
15452
15453    private static final int KSM_SHARED = 0;
15454    private static final int KSM_SHARING = 1;
15455    private static final int KSM_UNSHARED = 2;
15456    private static final int KSM_VOLATILE = 3;
15457
15458    private final long[] getKsmInfo() {
15459        long[] longOut = new long[4];
15460        final int[] SINGLE_LONG_FORMAT = new int[] {
15461            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15462        };
15463        long[] longTmp = new long[1];
15464        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15465                SINGLE_LONG_FORMAT, null, longTmp, null);
15466        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15467        longTmp[0] = 0;
15468        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15469                SINGLE_LONG_FORMAT, null, longTmp, null);
15470        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15471        longTmp[0] = 0;
15472        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15473                SINGLE_LONG_FORMAT, null, longTmp, null);
15474        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15475        longTmp[0] = 0;
15476        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15477                SINGLE_LONG_FORMAT, null, longTmp, null);
15478        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15479        return longOut;
15480    }
15481
15482    private static String stringifySize(long size, int order) {
15483        Locale locale = Locale.US;
15484        switch (order) {
15485            case 1:
15486                return String.format(locale, "%,13d", size);
15487            case 1024:
15488                return String.format(locale, "%,9dK", size / 1024);
15489            case 1024 * 1024:
15490                return String.format(locale, "%,5dM", size / 1024 / 1024);
15491            case 1024 * 1024 * 1024:
15492                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15493            default:
15494                throw new IllegalArgumentException("Invalid size order");
15495        }
15496    }
15497
15498    private static String stringifyKBSize(long size) {
15499        return stringifySize(size * 1024, 1024);
15500    }
15501
15502    // Update this version number in case you change the 'compact' format
15503    private static final int MEMINFO_COMPACT_VERSION = 1;
15504
15505    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15506            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15507        boolean dumpDetails = false;
15508        boolean dumpFullDetails = false;
15509        boolean dumpDalvik = false;
15510        boolean dumpSummaryOnly = false;
15511        boolean dumpUnreachable = false;
15512        boolean oomOnly = false;
15513        boolean isCompact = false;
15514        boolean localOnly = false;
15515        boolean packages = false;
15516        boolean isCheckinRequest = false;
15517        boolean dumpSwapPss = false;
15518
15519        int opti = 0;
15520        while (opti < args.length) {
15521            String opt = args[opti];
15522            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15523                break;
15524            }
15525            opti++;
15526            if ("-a".equals(opt)) {
15527                dumpDetails = true;
15528                dumpFullDetails = true;
15529                dumpDalvik = true;
15530                dumpSwapPss = true;
15531            } else if ("-d".equals(opt)) {
15532                dumpDalvik = true;
15533            } else if ("-c".equals(opt)) {
15534                isCompact = true;
15535            } else if ("-s".equals(opt)) {
15536                dumpDetails = true;
15537                dumpSummaryOnly = true;
15538            } else if ("-S".equals(opt)) {
15539                dumpSwapPss = true;
15540            } else if ("--unreachable".equals(opt)) {
15541                dumpUnreachable = true;
15542            } else if ("--oom".equals(opt)) {
15543                oomOnly = true;
15544            } else if ("--local".equals(opt)) {
15545                localOnly = true;
15546            } else if ("--package".equals(opt)) {
15547                packages = true;
15548            } else if ("--checkin".equals(opt)) {
15549                isCheckinRequest = true;
15550
15551            } else if ("-h".equals(opt)) {
15552                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15553                pw.println("  -a: include all available information for each process.");
15554                pw.println("  -d: include dalvik details.");
15555                pw.println("  -c: dump in a compact machine-parseable representation.");
15556                pw.println("  -s: dump only summary of application memory usage.");
15557                pw.println("  -S: dump also SwapPss.");
15558                pw.println("  --oom: only show processes organized by oom adj.");
15559                pw.println("  --local: only collect details locally, don't call process.");
15560                pw.println("  --package: interpret process arg as package, dumping all");
15561                pw.println("             processes that have loaded that package.");
15562                pw.println("  --checkin: dump data for a checkin");
15563                pw.println("If [process] is specified it can be the name or ");
15564                pw.println("pid of a specific process to dump.");
15565                return;
15566            } else {
15567                pw.println("Unknown argument: " + opt + "; use -h for help");
15568            }
15569        }
15570
15571        long uptime = SystemClock.uptimeMillis();
15572        long realtime = SystemClock.elapsedRealtime();
15573        final long[] tmpLong = new long[1];
15574
15575        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15576        if (procs == null) {
15577            // No Java processes.  Maybe they want to print a native process.
15578            if (args != null && args.length > opti
15579                    && args[opti].charAt(0) != '-') {
15580                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15581                        = new ArrayList<ProcessCpuTracker.Stats>();
15582                updateCpuStatsNow();
15583                int findPid = -1;
15584                try {
15585                    findPid = Integer.parseInt(args[opti]);
15586                } catch (NumberFormatException e) {
15587                }
15588                synchronized (mProcessCpuTracker) {
15589                    final int N = mProcessCpuTracker.countStats();
15590                    for (int i=0; i<N; i++) {
15591                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15592                        if (st.pid == findPid || (st.baseName != null
15593                                && st.baseName.equals(args[opti]))) {
15594                            nativeProcs.add(st);
15595                        }
15596                    }
15597                }
15598                if (nativeProcs.size() > 0) {
15599                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15600                            isCompact);
15601                    Debug.MemoryInfo mi = null;
15602                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15603                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15604                        final int pid = r.pid;
15605                        if (!isCheckinRequest && dumpDetails) {
15606                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15607                        }
15608                        if (mi == null) {
15609                            mi = new Debug.MemoryInfo();
15610                        }
15611                        if (dumpDetails || (!brief && !oomOnly)) {
15612                            Debug.getMemoryInfo(pid, mi);
15613                        } else {
15614                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15615                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15616                        }
15617                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15618                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15619                        if (isCheckinRequest) {
15620                            pw.println();
15621                        }
15622                    }
15623                    return;
15624                }
15625            }
15626            pw.println("No process found for: " + args[opti]);
15627            return;
15628        }
15629
15630        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15631            dumpDetails = true;
15632        }
15633
15634        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15635
15636        String[] innerArgs = new String[args.length-opti];
15637        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15638
15639        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15640        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15641        long nativePss = 0;
15642        long nativeSwapPss = 0;
15643        long dalvikPss = 0;
15644        long dalvikSwapPss = 0;
15645        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15646                EmptyArray.LONG;
15647        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15648                EmptyArray.LONG;
15649        long otherPss = 0;
15650        long otherSwapPss = 0;
15651        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15652        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15653
15654        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15655        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15656        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15657                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15658
15659        long totalPss = 0;
15660        long totalSwapPss = 0;
15661        long cachedPss = 0;
15662        long cachedSwapPss = 0;
15663        boolean hasSwapPss = false;
15664
15665        Debug.MemoryInfo mi = null;
15666        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15667            final ProcessRecord r = procs.get(i);
15668            final IApplicationThread thread;
15669            final int pid;
15670            final int oomAdj;
15671            final boolean hasActivities;
15672            synchronized (this) {
15673                thread = r.thread;
15674                pid = r.pid;
15675                oomAdj = r.getSetAdjWithServices();
15676                hasActivities = r.activities.size() > 0;
15677            }
15678            if (thread != null) {
15679                if (!isCheckinRequest && dumpDetails) {
15680                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15681                }
15682                if (mi == null) {
15683                    mi = new Debug.MemoryInfo();
15684                }
15685                if (dumpDetails || (!brief && !oomOnly)) {
15686                    Debug.getMemoryInfo(pid, mi);
15687                    hasSwapPss = mi.hasSwappedOutPss;
15688                } else {
15689                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15690                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15691                }
15692                if (dumpDetails) {
15693                    if (localOnly) {
15694                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15695                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15696                        if (isCheckinRequest) {
15697                            pw.println();
15698                        }
15699                    } else {
15700                        try {
15701                            pw.flush();
15702                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15703                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15704                        } catch (RemoteException e) {
15705                            if (!isCheckinRequest) {
15706                                pw.println("Got RemoteException!");
15707                                pw.flush();
15708                            }
15709                        }
15710                    }
15711                }
15712
15713                final long myTotalPss = mi.getTotalPss();
15714                final long myTotalUss = mi.getTotalUss();
15715                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15716
15717                synchronized (this) {
15718                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15719                        // Record this for posterity if the process has been stable.
15720                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15721                    }
15722                }
15723
15724                if (!isCheckinRequest && mi != null) {
15725                    totalPss += myTotalPss;
15726                    totalSwapPss += myTotalSwapPss;
15727                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15728                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15729                            myTotalSwapPss, pid, hasActivities);
15730                    procMems.add(pssItem);
15731                    procMemsMap.put(pid, pssItem);
15732
15733                    nativePss += mi.nativePss;
15734                    nativeSwapPss += mi.nativeSwappedOutPss;
15735                    dalvikPss += mi.dalvikPss;
15736                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15737                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15738                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15739                        dalvikSubitemSwapPss[j] +=
15740                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15741                    }
15742                    otherPss += mi.otherPss;
15743                    otherSwapPss += mi.otherSwappedOutPss;
15744                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15745                        long mem = mi.getOtherPss(j);
15746                        miscPss[j] += mem;
15747                        otherPss -= mem;
15748                        mem = mi.getOtherSwappedOutPss(j);
15749                        miscSwapPss[j] += mem;
15750                        otherSwapPss -= mem;
15751                    }
15752
15753                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15754                        cachedPss += myTotalPss;
15755                        cachedSwapPss += myTotalSwapPss;
15756                    }
15757
15758                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15759                        if (oomIndex == (oomPss.length - 1)
15760                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15761                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15762                            oomPss[oomIndex] += myTotalPss;
15763                            oomSwapPss[oomIndex] += myTotalSwapPss;
15764                            if (oomProcs[oomIndex] == null) {
15765                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15766                            }
15767                            oomProcs[oomIndex].add(pssItem);
15768                            break;
15769                        }
15770                    }
15771                }
15772            }
15773        }
15774
15775        long nativeProcTotalPss = 0;
15776
15777        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15778            // If we are showing aggregations, also look for native processes to
15779            // include so that our aggregations are more accurate.
15780            updateCpuStatsNow();
15781            mi = null;
15782            synchronized (mProcessCpuTracker) {
15783                final int N = mProcessCpuTracker.countStats();
15784                for (int i=0; i<N; i++) {
15785                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15786                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15787                        if (mi == null) {
15788                            mi = new Debug.MemoryInfo();
15789                        }
15790                        if (!brief && !oomOnly) {
15791                            Debug.getMemoryInfo(st.pid, mi);
15792                        } else {
15793                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15794                            mi.nativePrivateDirty = (int)tmpLong[0];
15795                        }
15796
15797                        final long myTotalPss = mi.getTotalPss();
15798                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15799                        totalPss += myTotalPss;
15800                        nativeProcTotalPss += myTotalPss;
15801
15802                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15803                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15804                        procMems.add(pssItem);
15805
15806                        nativePss += mi.nativePss;
15807                        nativeSwapPss += mi.nativeSwappedOutPss;
15808                        dalvikPss += mi.dalvikPss;
15809                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15810                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15811                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15812                            dalvikSubitemSwapPss[j] +=
15813                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15814                        }
15815                        otherPss += mi.otherPss;
15816                        otherSwapPss += mi.otherSwappedOutPss;
15817                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15818                            long mem = mi.getOtherPss(j);
15819                            miscPss[j] += mem;
15820                            otherPss -= mem;
15821                            mem = mi.getOtherSwappedOutPss(j);
15822                            miscSwapPss[j] += mem;
15823                            otherSwapPss -= mem;
15824                        }
15825                        oomPss[0] += myTotalPss;
15826                        oomSwapPss[0] += myTotalSwapPss;
15827                        if (oomProcs[0] == null) {
15828                            oomProcs[0] = new ArrayList<MemItem>();
15829                        }
15830                        oomProcs[0].add(pssItem);
15831                    }
15832                }
15833            }
15834
15835            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15836
15837            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15838            final MemItem dalvikItem =
15839                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15840            if (dalvikSubitemPss.length > 0) {
15841                dalvikItem.subitems = new ArrayList<MemItem>();
15842                for (int j=0; j<dalvikSubitemPss.length; j++) {
15843                    final String name = Debug.MemoryInfo.getOtherLabel(
15844                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15845                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15846                                    dalvikSubitemSwapPss[j], j));
15847                }
15848            }
15849            catMems.add(dalvikItem);
15850            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15851            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15852                String label = Debug.MemoryInfo.getOtherLabel(j);
15853                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15854            }
15855
15856            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15857            for (int j=0; j<oomPss.length; j++) {
15858                if (oomPss[j] != 0) {
15859                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15860                            : DUMP_MEM_OOM_LABEL[j];
15861                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15862                            DUMP_MEM_OOM_ADJ[j]);
15863                    item.subitems = oomProcs[j];
15864                    oomMems.add(item);
15865                }
15866            }
15867
15868            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15869            if (!brief && !oomOnly && !isCompact) {
15870                pw.println();
15871                pw.println("Total PSS by process:");
15872                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15873                pw.println();
15874            }
15875            if (!isCompact) {
15876                pw.println("Total PSS by OOM adjustment:");
15877            }
15878            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15879            if (!brief && !oomOnly) {
15880                PrintWriter out = categoryPw != null ? categoryPw : pw;
15881                if (!isCompact) {
15882                    out.println();
15883                    out.println("Total PSS by category:");
15884                }
15885                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15886            }
15887            if (!isCompact) {
15888                pw.println();
15889            }
15890            MemInfoReader memInfo = new MemInfoReader();
15891            memInfo.readMemInfo();
15892            if (nativeProcTotalPss > 0) {
15893                synchronized (this) {
15894                    final long cachedKb = memInfo.getCachedSizeKb();
15895                    final long freeKb = memInfo.getFreeSizeKb();
15896                    final long zramKb = memInfo.getZramTotalSizeKb();
15897                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15898                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15899                            kernelKb*1024, nativeProcTotalPss*1024);
15900                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15901                            nativeProcTotalPss);
15902                }
15903            }
15904            if (!brief) {
15905                if (!isCompact) {
15906                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15907                    pw.print(" (status ");
15908                    switch (mLastMemoryLevel) {
15909                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15910                            pw.println("normal)");
15911                            break;
15912                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15913                            pw.println("moderate)");
15914                            break;
15915                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15916                            pw.println("low)");
15917                            break;
15918                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15919                            pw.println("critical)");
15920                            break;
15921                        default:
15922                            pw.print(mLastMemoryLevel);
15923                            pw.println(")");
15924                            break;
15925                    }
15926                    pw.print(" Free RAM: ");
15927                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15928                            + memInfo.getFreeSizeKb()));
15929                    pw.print(" (");
15930                    pw.print(stringifyKBSize(cachedPss));
15931                    pw.print(" cached pss + ");
15932                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15933                    pw.print(" cached kernel + ");
15934                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15935                    pw.println(" free)");
15936                } else {
15937                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15938                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15939                            + memInfo.getFreeSizeKb()); pw.print(",");
15940                    pw.println(totalPss - cachedPss);
15941                }
15942            }
15943            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15944                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15945                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15946            if (!isCompact) {
15947                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15948                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15949                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15950                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15951                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15952            } else {
15953                pw.print("lostram,"); pw.println(lostRAM);
15954            }
15955            if (!brief) {
15956                if (memInfo.getZramTotalSizeKb() != 0) {
15957                    if (!isCompact) {
15958                        pw.print("     ZRAM: ");
15959                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15960                                pw.print(" physical used for ");
15961                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15962                                        - memInfo.getSwapFreeSizeKb()));
15963                                pw.print(" in swap (");
15964                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15965                                pw.println(" total swap)");
15966                    } else {
15967                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15968                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15969                                pw.println(memInfo.getSwapFreeSizeKb());
15970                    }
15971                }
15972                final long[] ksm = getKsmInfo();
15973                if (!isCompact) {
15974                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15975                            || ksm[KSM_VOLATILE] != 0) {
15976                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15977                                pw.print(" saved from shared ");
15978                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15979                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15980                                pw.print(" unshared; ");
15981                                pw.print(stringifyKBSize(
15982                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15983                    }
15984                    pw.print("   Tuning: ");
15985                    pw.print(ActivityManager.staticGetMemoryClass());
15986                    pw.print(" (large ");
15987                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15988                    pw.print("), oom ");
15989                    pw.print(stringifySize(
15990                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15991                    pw.print(", restore limit ");
15992                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15993                    if (ActivityManager.isLowRamDeviceStatic()) {
15994                        pw.print(" (low-ram)");
15995                    }
15996                    if (ActivityManager.isHighEndGfx()) {
15997                        pw.print(" (high-end-gfx)");
15998                    }
15999                    pw.println();
16000                } else {
16001                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16002                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16003                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16004                    pw.print("tuning,");
16005                    pw.print(ActivityManager.staticGetMemoryClass());
16006                    pw.print(',');
16007                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16008                    pw.print(',');
16009                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16010                    if (ActivityManager.isLowRamDeviceStatic()) {
16011                        pw.print(",low-ram");
16012                    }
16013                    if (ActivityManager.isHighEndGfx()) {
16014                        pw.print(",high-end-gfx");
16015                    }
16016                    pw.println();
16017                }
16018            }
16019        }
16020    }
16021
16022    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16023            long memtrack, String name) {
16024        sb.append("  ");
16025        sb.append(ProcessList.makeOomAdjString(oomAdj));
16026        sb.append(' ');
16027        sb.append(ProcessList.makeProcStateString(procState));
16028        sb.append(' ');
16029        ProcessList.appendRamKb(sb, pss);
16030        sb.append(": ");
16031        sb.append(name);
16032        if (memtrack > 0) {
16033            sb.append(" (");
16034            sb.append(stringifyKBSize(memtrack));
16035            sb.append(" memtrack)");
16036        }
16037    }
16038
16039    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16040        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16041        sb.append(" (pid ");
16042        sb.append(mi.pid);
16043        sb.append(") ");
16044        sb.append(mi.adjType);
16045        sb.append('\n');
16046        if (mi.adjReason != null) {
16047            sb.append("                      ");
16048            sb.append(mi.adjReason);
16049            sb.append('\n');
16050        }
16051    }
16052
16053    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16054        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16055        for (int i=0, N=memInfos.size(); i<N; i++) {
16056            ProcessMemInfo mi = memInfos.get(i);
16057            infoMap.put(mi.pid, mi);
16058        }
16059        updateCpuStatsNow();
16060        long[] memtrackTmp = new long[1];
16061        synchronized (mProcessCpuTracker) {
16062            final int N = mProcessCpuTracker.countStats();
16063            for (int i=0; i<N; i++) {
16064                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16065                if (st.vsize > 0) {
16066                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16067                    if (pss > 0) {
16068                        if (infoMap.indexOfKey(st.pid) < 0) {
16069                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16070                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16071                            mi.pss = pss;
16072                            mi.memtrack = memtrackTmp[0];
16073                            memInfos.add(mi);
16074                        }
16075                    }
16076                }
16077            }
16078        }
16079
16080        long totalPss = 0;
16081        long totalMemtrack = 0;
16082        for (int i=0, N=memInfos.size(); i<N; i++) {
16083            ProcessMemInfo mi = memInfos.get(i);
16084            if (mi.pss == 0) {
16085                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16086                mi.memtrack = memtrackTmp[0];
16087            }
16088            totalPss += mi.pss;
16089            totalMemtrack += mi.memtrack;
16090        }
16091        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16092            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16093                if (lhs.oomAdj != rhs.oomAdj) {
16094                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16095                }
16096                if (lhs.pss != rhs.pss) {
16097                    return lhs.pss < rhs.pss ? 1 : -1;
16098                }
16099                return 0;
16100            }
16101        });
16102
16103        StringBuilder tag = new StringBuilder(128);
16104        StringBuilder stack = new StringBuilder(128);
16105        tag.append("Low on memory -- ");
16106        appendMemBucket(tag, totalPss, "total", false);
16107        appendMemBucket(stack, totalPss, "total", true);
16108
16109        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16110        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16111        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16112
16113        boolean firstLine = true;
16114        int lastOomAdj = Integer.MIN_VALUE;
16115        long extraNativeRam = 0;
16116        long extraNativeMemtrack = 0;
16117        long cachedPss = 0;
16118        for (int i=0, N=memInfos.size(); i<N; i++) {
16119            ProcessMemInfo mi = memInfos.get(i);
16120
16121            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16122                cachedPss += mi.pss;
16123            }
16124
16125            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16126                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16127                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16128                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16129                if (lastOomAdj != mi.oomAdj) {
16130                    lastOomAdj = mi.oomAdj;
16131                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16132                        tag.append(" / ");
16133                    }
16134                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16135                        if (firstLine) {
16136                            stack.append(":");
16137                            firstLine = false;
16138                        }
16139                        stack.append("\n\t at ");
16140                    } else {
16141                        stack.append("$");
16142                    }
16143                } else {
16144                    tag.append(" ");
16145                    stack.append("$");
16146                }
16147                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16148                    appendMemBucket(tag, mi.pss, mi.name, false);
16149                }
16150                appendMemBucket(stack, mi.pss, mi.name, true);
16151                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16152                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16153                    stack.append("(");
16154                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16155                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16156                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16157                            stack.append(":");
16158                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16159                        }
16160                    }
16161                    stack.append(")");
16162                }
16163            }
16164
16165            appendMemInfo(fullNativeBuilder, mi);
16166            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16167                // The short form only has native processes that are >= 512K.
16168                if (mi.pss >= 512) {
16169                    appendMemInfo(shortNativeBuilder, mi);
16170                } else {
16171                    extraNativeRam += mi.pss;
16172                    extraNativeMemtrack += mi.memtrack;
16173                }
16174            } else {
16175                // Short form has all other details, but if we have collected RAM
16176                // from smaller native processes let's dump a summary of that.
16177                if (extraNativeRam > 0) {
16178                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16179                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16180                    shortNativeBuilder.append('\n');
16181                    extraNativeRam = 0;
16182                }
16183                appendMemInfo(fullJavaBuilder, mi);
16184            }
16185        }
16186
16187        fullJavaBuilder.append("           ");
16188        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16189        fullJavaBuilder.append(": TOTAL");
16190        if (totalMemtrack > 0) {
16191            fullJavaBuilder.append(" (");
16192            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16193            fullJavaBuilder.append(" memtrack)");
16194        } else {
16195        }
16196        fullJavaBuilder.append("\n");
16197
16198        MemInfoReader memInfo = new MemInfoReader();
16199        memInfo.readMemInfo();
16200        final long[] infos = memInfo.getRawInfo();
16201
16202        StringBuilder memInfoBuilder = new StringBuilder(1024);
16203        Debug.getMemInfo(infos);
16204        memInfoBuilder.append("  MemInfo: ");
16205        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16206        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16207        memInfoBuilder.append(stringifyKBSize(
16208                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16209        memInfoBuilder.append(stringifyKBSize(
16210                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16211        memInfoBuilder.append(stringifyKBSize(
16212                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16213        memInfoBuilder.append("           ");
16214        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16215        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16216        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16217        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16218        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16219            memInfoBuilder.append("  ZRAM: ");
16220            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16221            memInfoBuilder.append(" RAM, ");
16222            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16223            memInfoBuilder.append(" swap total, ");
16224            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16225            memInfoBuilder.append(" swap free\n");
16226        }
16227        final long[] ksm = getKsmInfo();
16228        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16229                || ksm[KSM_VOLATILE] != 0) {
16230            memInfoBuilder.append("  KSM: ");
16231            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16232            memInfoBuilder.append(" saved from shared ");
16233            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16234            memInfoBuilder.append("\n       ");
16235            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16236            memInfoBuilder.append(" unshared; ");
16237            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16238            memInfoBuilder.append(" volatile\n");
16239        }
16240        memInfoBuilder.append("  Free RAM: ");
16241        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16242                + memInfo.getFreeSizeKb()));
16243        memInfoBuilder.append("\n");
16244        memInfoBuilder.append("  Used RAM: ");
16245        memInfoBuilder.append(stringifyKBSize(
16246                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16247        memInfoBuilder.append("\n");
16248        memInfoBuilder.append("  Lost RAM: ");
16249        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16250                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16251                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16252        memInfoBuilder.append("\n");
16253        Slog.i(TAG, "Low on memory:");
16254        Slog.i(TAG, shortNativeBuilder.toString());
16255        Slog.i(TAG, fullJavaBuilder.toString());
16256        Slog.i(TAG, memInfoBuilder.toString());
16257
16258        StringBuilder dropBuilder = new StringBuilder(1024);
16259        /*
16260        StringWriter oomSw = new StringWriter();
16261        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16262        StringWriter catSw = new StringWriter();
16263        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16264        String[] emptyArgs = new String[] { };
16265        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16266        oomPw.flush();
16267        String oomString = oomSw.toString();
16268        */
16269        dropBuilder.append("Low on memory:");
16270        dropBuilder.append(stack);
16271        dropBuilder.append('\n');
16272        dropBuilder.append(fullNativeBuilder);
16273        dropBuilder.append(fullJavaBuilder);
16274        dropBuilder.append('\n');
16275        dropBuilder.append(memInfoBuilder);
16276        dropBuilder.append('\n');
16277        /*
16278        dropBuilder.append(oomString);
16279        dropBuilder.append('\n');
16280        */
16281        StringWriter catSw = new StringWriter();
16282        synchronized (ActivityManagerService.this) {
16283            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16284            String[] emptyArgs = new String[] { };
16285            catPw.println();
16286            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16287            catPw.println();
16288            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16289                    false, null).dumpLocked();
16290            catPw.println();
16291            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16292            catPw.flush();
16293        }
16294        dropBuilder.append(catSw.toString());
16295        addErrorToDropBox("lowmem", null, "system_server", null,
16296                null, tag.toString(), dropBuilder.toString(), null, null);
16297        //Slog.i(TAG, "Sent to dropbox:");
16298        //Slog.i(TAG, dropBuilder.toString());
16299        synchronized (ActivityManagerService.this) {
16300            long now = SystemClock.uptimeMillis();
16301            if (mLastMemUsageReportTime < now) {
16302                mLastMemUsageReportTime = now;
16303            }
16304        }
16305    }
16306
16307    /**
16308     * Searches array of arguments for the specified string
16309     * @param args array of argument strings
16310     * @param value value to search for
16311     * @return true if the value is contained in the array
16312     */
16313    private static boolean scanArgs(String[] args, String value) {
16314        if (args != null) {
16315            for (String arg : args) {
16316                if (value.equals(arg)) {
16317                    return true;
16318                }
16319            }
16320        }
16321        return false;
16322    }
16323
16324    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16325            ContentProviderRecord cpr, boolean always) {
16326        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16327
16328        if (!inLaunching || always) {
16329            synchronized (cpr) {
16330                cpr.launchingApp = null;
16331                cpr.notifyAll();
16332            }
16333            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16334            String names[] = cpr.info.authority.split(";");
16335            for (int j = 0; j < names.length; j++) {
16336                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16337            }
16338        }
16339
16340        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16341            ContentProviderConnection conn = cpr.connections.get(i);
16342            if (conn.waiting) {
16343                // If this connection is waiting for the provider, then we don't
16344                // need to mess with its process unless we are always removing
16345                // or for some reason the provider is not currently launching.
16346                if (inLaunching && !always) {
16347                    continue;
16348                }
16349            }
16350            ProcessRecord capp = conn.client;
16351            conn.dead = true;
16352            if (conn.stableCount > 0) {
16353                if (!capp.persistent && capp.thread != null
16354                        && capp.pid != 0
16355                        && capp.pid != MY_PID) {
16356                    capp.kill("depends on provider "
16357                            + cpr.name.flattenToShortString()
16358                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16359                }
16360            } else if (capp.thread != null && conn.provider.provider != null) {
16361                try {
16362                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16363                } catch (RemoteException e) {
16364                }
16365                // In the protocol here, we don't expect the client to correctly
16366                // clean up this connection, we'll just remove it.
16367                cpr.connections.remove(i);
16368                if (conn.client.conProviders.remove(conn)) {
16369                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16370                }
16371            }
16372        }
16373
16374        if (inLaunching && always) {
16375            mLaunchingProviders.remove(cpr);
16376        }
16377        return inLaunching;
16378    }
16379
16380    /**
16381     * Main code for cleaning up a process when it has gone away.  This is
16382     * called both as a result of the process dying, or directly when stopping
16383     * a process when running in single process mode.
16384     *
16385     * @return Returns true if the given process has been restarted, so the
16386     * app that was passed in must remain on the process lists.
16387     */
16388    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16389            boolean restarting, boolean allowRestart, int index) {
16390        if (index >= 0) {
16391            removeLruProcessLocked(app);
16392            ProcessList.remove(app.pid);
16393        }
16394
16395        mProcessesToGc.remove(app);
16396        mPendingPssProcesses.remove(app);
16397
16398        // Dismiss any open dialogs.
16399        if (app.crashDialog != null && !app.forceCrashReport) {
16400            app.crashDialog.dismiss();
16401            app.crashDialog = null;
16402        }
16403        if (app.anrDialog != null) {
16404            app.anrDialog.dismiss();
16405            app.anrDialog = null;
16406        }
16407        if (app.waitDialog != null) {
16408            app.waitDialog.dismiss();
16409            app.waitDialog = null;
16410        }
16411
16412        app.crashing = false;
16413        app.notResponding = false;
16414
16415        app.resetPackageList(mProcessStats);
16416        app.unlinkDeathRecipient();
16417        app.makeInactive(mProcessStats);
16418        app.waitingToKill = null;
16419        app.forcingToForeground = null;
16420        updateProcessForegroundLocked(app, false, false);
16421        app.foregroundActivities = false;
16422        app.hasShownUi = false;
16423        app.treatLikeActivity = false;
16424        app.hasAboveClient = false;
16425        app.hasClientActivities = false;
16426
16427        mServices.killServicesLocked(app, allowRestart);
16428
16429        boolean restart = false;
16430
16431        // Remove published content providers.
16432        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16433            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16434            final boolean always = app.bad || !allowRestart;
16435            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16436            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16437                // We left the provider in the launching list, need to
16438                // restart it.
16439                restart = true;
16440            }
16441
16442            cpr.provider = null;
16443            cpr.proc = null;
16444        }
16445        app.pubProviders.clear();
16446
16447        // Take care of any launching providers waiting for this process.
16448        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16449            restart = true;
16450        }
16451
16452        // Unregister from connected content providers.
16453        if (!app.conProviders.isEmpty()) {
16454            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16455                ContentProviderConnection conn = app.conProviders.get(i);
16456                conn.provider.connections.remove(conn);
16457                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16458                        conn.provider.name);
16459            }
16460            app.conProviders.clear();
16461        }
16462
16463        // At this point there may be remaining entries in mLaunchingProviders
16464        // where we were the only one waiting, so they are no longer of use.
16465        // Look for these and clean up if found.
16466        // XXX Commented out for now.  Trying to figure out a way to reproduce
16467        // the actual situation to identify what is actually going on.
16468        if (false) {
16469            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16470                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16471                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16472                    synchronized (cpr) {
16473                        cpr.launchingApp = null;
16474                        cpr.notifyAll();
16475                    }
16476                }
16477            }
16478        }
16479
16480        skipCurrentReceiverLocked(app);
16481
16482        // Unregister any receivers.
16483        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16484            removeReceiverLocked(app.receivers.valueAt(i));
16485        }
16486        app.receivers.clear();
16487
16488        // If the app is undergoing backup, tell the backup manager about it
16489        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16490            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16491                    + mBackupTarget.appInfo + " died during backup");
16492            try {
16493                IBackupManager bm = IBackupManager.Stub.asInterface(
16494                        ServiceManager.getService(Context.BACKUP_SERVICE));
16495                bm.agentDisconnected(app.info.packageName);
16496            } catch (RemoteException e) {
16497                // can't happen; backup manager is local
16498            }
16499        }
16500
16501        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16502            ProcessChangeItem item = mPendingProcessChanges.get(i);
16503            if (item.pid == app.pid) {
16504                mPendingProcessChanges.remove(i);
16505                mAvailProcessChanges.add(item);
16506            }
16507        }
16508        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16509                null).sendToTarget();
16510
16511        // If the caller is restarting this app, then leave it in its
16512        // current lists and let the caller take care of it.
16513        if (restarting) {
16514            return false;
16515        }
16516
16517        if (!app.persistent || app.isolated) {
16518            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16519                    "Removing non-persistent process during cleanup: " + app);
16520            removeProcessNameLocked(app.processName, app.uid);
16521            if (mHeavyWeightProcess == app) {
16522                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16523                        mHeavyWeightProcess.userId, 0));
16524                mHeavyWeightProcess = null;
16525            }
16526        } else if (!app.removed) {
16527            // This app is persistent, so we need to keep its record around.
16528            // If it is not already on the pending app list, add it there
16529            // and start a new process for it.
16530            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16531                mPersistentStartingProcesses.add(app);
16532                restart = true;
16533            }
16534        }
16535        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16536                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16537        mProcessesOnHold.remove(app);
16538
16539        if (app == mHomeProcess) {
16540            mHomeProcess = null;
16541        }
16542        if (app == mPreviousProcess) {
16543            mPreviousProcess = null;
16544        }
16545
16546        if (restart && !app.isolated) {
16547            // We have components that still need to be running in the
16548            // process, so re-launch it.
16549            if (index < 0) {
16550                ProcessList.remove(app.pid);
16551            }
16552            addProcessNameLocked(app);
16553            startProcessLocked(app, "restart", app.processName);
16554            return true;
16555        } else if (app.pid > 0 && app.pid != MY_PID) {
16556            // Goodbye!
16557            boolean removed;
16558            synchronized (mPidsSelfLocked) {
16559                mPidsSelfLocked.remove(app.pid);
16560                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16561            }
16562            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16563            if (app.isolated) {
16564                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16565            }
16566            app.setPid(0);
16567        }
16568        return false;
16569    }
16570
16571    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16572        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16573            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16574            if (cpr.launchingApp == app) {
16575                return true;
16576            }
16577        }
16578        return false;
16579    }
16580
16581    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16582        // Look through the content providers we are waiting to have launched,
16583        // and if any run in this process then either schedule a restart of
16584        // the process or kill the client waiting for it if this process has
16585        // gone bad.
16586        boolean restart = false;
16587        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16588            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16589            if (cpr.launchingApp == app) {
16590                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16591                    restart = true;
16592                } else {
16593                    removeDyingProviderLocked(app, cpr, true);
16594                }
16595            }
16596        }
16597        return restart;
16598    }
16599
16600    // =========================================================
16601    // SERVICES
16602    // =========================================================
16603
16604    @Override
16605    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16606            int flags) {
16607        enforceNotIsolatedCaller("getServices");
16608        synchronized (this) {
16609            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16610        }
16611    }
16612
16613    @Override
16614    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16615        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16616        synchronized (this) {
16617            return mServices.getRunningServiceControlPanelLocked(name);
16618        }
16619    }
16620
16621    @Override
16622    public ComponentName startService(IApplicationThread caller, Intent service,
16623            String resolvedType, String callingPackage, int userId)
16624            throws TransactionTooLargeException {
16625        enforceNotIsolatedCaller("startService");
16626        // Refuse possible leaked file descriptors
16627        if (service != null && service.hasFileDescriptors() == true) {
16628            throw new IllegalArgumentException("File descriptors passed in Intent");
16629        }
16630
16631        if (callingPackage == null) {
16632            throw new IllegalArgumentException("callingPackage cannot be null");
16633        }
16634
16635        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16636                "startService: " + service + " type=" + resolvedType);
16637        synchronized(this) {
16638            final int callingPid = Binder.getCallingPid();
16639            final int callingUid = Binder.getCallingUid();
16640            final long origId = Binder.clearCallingIdentity();
16641            ComponentName res = mServices.startServiceLocked(caller, service,
16642                    resolvedType, callingPid, callingUid, callingPackage, userId);
16643            Binder.restoreCallingIdentity(origId);
16644            return res;
16645        }
16646    }
16647
16648    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16649            String callingPackage, int userId)
16650            throws TransactionTooLargeException {
16651        synchronized(this) {
16652            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16653                    "startServiceInPackage: " + service + " type=" + resolvedType);
16654            final long origId = Binder.clearCallingIdentity();
16655            ComponentName res = mServices.startServiceLocked(null, service,
16656                    resolvedType, -1, uid, callingPackage, userId);
16657            Binder.restoreCallingIdentity(origId);
16658            return res;
16659        }
16660    }
16661
16662    @Override
16663    public int stopService(IApplicationThread caller, Intent service,
16664            String resolvedType, int userId) {
16665        enforceNotIsolatedCaller("stopService");
16666        // Refuse possible leaked file descriptors
16667        if (service != null && service.hasFileDescriptors() == true) {
16668            throw new IllegalArgumentException("File descriptors passed in Intent");
16669        }
16670
16671        synchronized(this) {
16672            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16673        }
16674    }
16675
16676    @Override
16677    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16678        enforceNotIsolatedCaller("peekService");
16679        // Refuse possible leaked file descriptors
16680        if (service != null && service.hasFileDescriptors() == true) {
16681            throw new IllegalArgumentException("File descriptors passed in Intent");
16682        }
16683
16684        if (callingPackage == null) {
16685            throw new IllegalArgumentException("callingPackage cannot be null");
16686        }
16687
16688        synchronized(this) {
16689            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16690        }
16691    }
16692
16693    @Override
16694    public boolean stopServiceToken(ComponentName className, IBinder token,
16695            int startId) {
16696        synchronized(this) {
16697            return mServices.stopServiceTokenLocked(className, token, startId);
16698        }
16699    }
16700
16701    @Override
16702    public void setServiceForeground(ComponentName className, IBinder token,
16703            int id, Notification notification, int flags) {
16704        synchronized(this) {
16705            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16706        }
16707    }
16708
16709    @Override
16710    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16711            boolean requireFull, String name, String callerPackage) {
16712        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16713                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16714    }
16715
16716    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16717            String className, int flags) {
16718        boolean result = false;
16719        // For apps that don't have pre-defined UIDs, check for permission
16720        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16721            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16722                if (ActivityManager.checkUidPermission(
16723                        INTERACT_ACROSS_USERS,
16724                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16725                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16726                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16727                            + " requests FLAG_SINGLE_USER, but app does not hold "
16728                            + INTERACT_ACROSS_USERS;
16729                    Slog.w(TAG, msg);
16730                    throw new SecurityException(msg);
16731                }
16732                // Permission passed
16733                result = true;
16734            }
16735        } else if ("system".equals(componentProcessName)) {
16736            result = true;
16737        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16738            // Phone app and persistent apps are allowed to export singleuser providers.
16739            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16740                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16741        }
16742        if (DEBUG_MU) Slog.v(TAG_MU,
16743                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16744                + Integer.toHexString(flags) + ") = " + result);
16745        return result;
16746    }
16747
16748    /**
16749     * Checks to see if the caller is in the same app as the singleton
16750     * component, or the component is in a special app. It allows special apps
16751     * to export singleton components but prevents exporting singleton
16752     * components for regular apps.
16753     */
16754    boolean isValidSingletonCall(int callingUid, int componentUid) {
16755        int componentAppId = UserHandle.getAppId(componentUid);
16756        return UserHandle.isSameApp(callingUid, componentUid)
16757                || componentAppId == Process.SYSTEM_UID
16758                || componentAppId == Process.PHONE_UID
16759                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16760                        == PackageManager.PERMISSION_GRANTED;
16761    }
16762
16763    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16764            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16765            int userId) throws TransactionTooLargeException {
16766        enforceNotIsolatedCaller("bindService");
16767
16768        // Refuse possible leaked file descriptors
16769        if (service != null && service.hasFileDescriptors() == true) {
16770            throw new IllegalArgumentException("File descriptors passed in Intent");
16771        }
16772
16773        if (callingPackage == null) {
16774            throw new IllegalArgumentException("callingPackage cannot be null");
16775        }
16776
16777        synchronized(this) {
16778            return mServices.bindServiceLocked(caller, token, service,
16779                    resolvedType, connection, flags, callingPackage, userId);
16780        }
16781    }
16782
16783    public boolean unbindService(IServiceConnection connection) {
16784        synchronized (this) {
16785            return mServices.unbindServiceLocked(connection);
16786        }
16787    }
16788
16789    public void publishService(IBinder token, Intent intent, IBinder service) {
16790        // Refuse possible leaked file descriptors
16791        if (intent != null && intent.hasFileDescriptors() == true) {
16792            throw new IllegalArgumentException("File descriptors passed in Intent");
16793        }
16794
16795        synchronized(this) {
16796            if (!(token instanceof ServiceRecord)) {
16797                throw new IllegalArgumentException("Invalid service token");
16798            }
16799            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16800        }
16801    }
16802
16803    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16804        // Refuse possible leaked file descriptors
16805        if (intent != null && intent.hasFileDescriptors() == true) {
16806            throw new IllegalArgumentException("File descriptors passed in Intent");
16807        }
16808
16809        synchronized(this) {
16810            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16811        }
16812    }
16813
16814    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16815        synchronized(this) {
16816            if (!(token instanceof ServiceRecord)) {
16817                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16818                throw new IllegalArgumentException("Invalid service token");
16819            }
16820            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16821        }
16822    }
16823
16824    // =========================================================
16825    // BACKUP AND RESTORE
16826    // =========================================================
16827
16828    // Cause the target app to be launched if necessary and its backup agent
16829    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16830    // activity manager to announce its creation.
16831    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16832        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16833                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16834        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16835
16836        synchronized(this) {
16837            // !!! TODO: currently no check here that we're already bound
16838            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16839            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16840            synchronized (stats) {
16841                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16842            }
16843
16844            // Backup agent is now in use, its package can't be stopped.
16845            try {
16846                AppGlobals.getPackageManager().setPackageStoppedState(
16847                        app.packageName, false, UserHandle.getUserId(app.uid));
16848            } catch (RemoteException e) {
16849            } catch (IllegalArgumentException e) {
16850                Slog.w(TAG, "Failed trying to unstop package "
16851                        + app.packageName + ": " + e);
16852            }
16853
16854            BackupRecord r = new BackupRecord(ss, app, backupMode);
16855            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16856                    ? new ComponentName(app.packageName, app.backupAgentName)
16857                    : new ComponentName("android", "FullBackupAgent");
16858            // startProcessLocked() returns existing proc's record if it's already running
16859            ProcessRecord proc = startProcessLocked(app.processName, app,
16860                    false, 0, "backup", hostingName, false, false, false);
16861            if (proc == null) {
16862                Slog.e(TAG, "Unable to start backup agent process " + r);
16863                return false;
16864            }
16865
16866            r.app = proc;
16867            mBackupTarget = r;
16868            mBackupAppName = app.packageName;
16869
16870            // Try not to kill the process during backup
16871            updateOomAdjLocked(proc);
16872
16873            // If the process is already attached, schedule the creation of the backup agent now.
16874            // If it is not yet live, this will be done when it attaches to the framework.
16875            if (proc.thread != null) {
16876                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16877                try {
16878                    proc.thread.scheduleCreateBackupAgent(app,
16879                            compatibilityInfoForPackageLocked(app), backupMode);
16880                } catch (RemoteException e) {
16881                    // Will time out on the backup manager side
16882                }
16883            } else {
16884                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16885            }
16886            // Invariants: at this point, the target app process exists and the application
16887            // is either already running or in the process of coming up.  mBackupTarget and
16888            // mBackupAppName describe the app, so that when it binds back to the AM we
16889            // know that it's scheduled for a backup-agent operation.
16890        }
16891
16892        return true;
16893    }
16894
16895    @Override
16896    public void clearPendingBackup() {
16897        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16898        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16899
16900        synchronized (this) {
16901            mBackupTarget = null;
16902            mBackupAppName = null;
16903        }
16904    }
16905
16906    // A backup agent has just come up
16907    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16908        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16909                + " = " + agent);
16910
16911        synchronized(this) {
16912            if (!agentPackageName.equals(mBackupAppName)) {
16913                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16914                return;
16915            }
16916        }
16917
16918        long oldIdent = Binder.clearCallingIdentity();
16919        try {
16920            IBackupManager bm = IBackupManager.Stub.asInterface(
16921                    ServiceManager.getService(Context.BACKUP_SERVICE));
16922            bm.agentConnected(agentPackageName, agent);
16923        } catch (RemoteException e) {
16924            // can't happen; the backup manager service is local
16925        } catch (Exception e) {
16926            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16927            e.printStackTrace();
16928        } finally {
16929            Binder.restoreCallingIdentity(oldIdent);
16930        }
16931    }
16932
16933    // done with this agent
16934    public void unbindBackupAgent(ApplicationInfo appInfo) {
16935        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16936        if (appInfo == null) {
16937            Slog.w(TAG, "unbind backup agent for null app");
16938            return;
16939        }
16940
16941        synchronized(this) {
16942            try {
16943                if (mBackupAppName == null) {
16944                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16945                    return;
16946                }
16947
16948                if (!mBackupAppName.equals(appInfo.packageName)) {
16949                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16950                    return;
16951                }
16952
16953                // Not backing this app up any more; reset its OOM adjustment
16954                final ProcessRecord proc = mBackupTarget.app;
16955                updateOomAdjLocked(proc);
16956
16957                // If the app crashed during backup, 'thread' will be null here
16958                if (proc.thread != null) {
16959                    try {
16960                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16961                                compatibilityInfoForPackageLocked(appInfo));
16962                    } catch (Exception e) {
16963                        Slog.e(TAG, "Exception when unbinding backup agent:");
16964                        e.printStackTrace();
16965                    }
16966                }
16967            } finally {
16968                mBackupTarget = null;
16969                mBackupAppName = null;
16970            }
16971        }
16972    }
16973    // =========================================================
16974    // BROADCASTS
16975    // =========================================================
16976
16977    boolean isPendingBroadcastProcessLocked(int pid) {
16978        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16979                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16980    }
16981
16982    void skipPendingBroadcastLocked(int pid) {
16983            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16984            for (BroadcastQueue queue : mBroadcastQueues) {
16985                queue.skipPendingBroadcastLocked(pid);
16986            }
16987    }
16988
16989    // The app just attached; send any pending broadcasts that it should receive
16990    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16991        boolean didSomething = false;
16992        for (BroadcastQueue queue : mBroadcastQueues) {
16993            didSomething |= queue.sendPendingBroadcastsLocked(app);
16994        }
16995        return didSomething;
16996    }
16997
16998    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16999            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17000        enforceNotIsolatedCaller("registerReceiver");
17001        ArrayList<Intent> stickyIntents = null;
17002        ProcessRecord callerApp = null;
17003        int callingUid;
17004        int callingPid;
17005        synchronized(this) {
17006            if (caller != null) {
17007                callerApp = getRecordForAppLocked(caller);
17008                if (callerApp == null) {
17009                    throw new SecurityException(
17010                            "Unable to find app for caller " + caller
17011                            + " (pid=" + Binder.getCallingPid()
17012                            + ") when registering receiver " + receiver);
17013                }
17014                if (callerApp.info.uid != Process.SYSTEM_UID &&
17015                        !callerApp.pkgList.containsKey(callerPackage) &&
17016                        !"android".equals(callerPackage)) {
17017                    throw new SecurityException("Given caller package " + callerPackage
17018                            + " is not running in process " + callerApp);
17019                }
17020                callingUid = callerApp.info.uid;
17021                callingPid = callerApp.pid;
17022            } else {
17023                callerPackage = null;
17024                callingUid = Binder.getCallingUid();
17025                callingPid = Binder.getCallingPid();
17026            }
17027
17028            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17029                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17030
17031            Iterator<String> actions = filter.actionsIterator();
17032            if (actions == null) {
17033                ArrayList<String> noAction = new ArrayList<String>(1);
17034                noAction.add(null);
17035                actions = noAction.iterator();
17036            }
17037
17038            // Collect stickies of users
17039            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17040            while (actions.hasNext()) {
17041                String action = actions.next();
17042                for (int id : userIds) {
17043                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17044                    if (stickies != null) {
17045                        ArrayList<Intent> intents = stickies.get(action);
17046                        if (intents != null) {
17047                            if (stickyIntents == null) {
17048                                stickyIntents = new ArrayList<Intent>();
17049                            }
17050                            stickyIntents.addAll(intents);
17051                        }
17052                    }
17053                }
17054            }
17055        }
17056
17057        ArrayList<Intent> allSticky = null;
17058        if (stickyIntents != null) {
17059            final ContentResolver resolver = mContext.getContentResolver();
17060            // Look for any matching sticky broadcasts...
17061            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17062                Intent intent = stickyIntents.get(i);
17063                // If intent has scheme "content", it will need to acccess
17064                // provider that needs to lock mProviderMap in ActivityThread
17065                // and also it may need to wait application response, so we
17066                // cannot lock ActivityManagerService here.
17067                if (filter.match(resolver, intent, true, TAG) >= 0) {
17068                    if (allSticky == null) {
17069                        allSticky = new ArrayList<Intent>();
17070                    }
17071                    allSticky.add(intent);
17072                }
17073            }
17074        }
17075
17076        // The first sticky in the list is returned directly back to the client.
17077        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17078        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17079        if (receiver == null) {
17080            return sticky;
17081        }
17082
17083        synchronized (this) {
17084            if (callerApp != null && (callerApp.thread == null
17085                    || callerApp.thread.asBinder() != caller.asBinder())) {
17086                // Original caller already died
17087                return null;
17088            }
17089            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17090            if (rl == null) {
17091                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17092                        userId, receiver);
17093                if (rl.app != null) {
17094                    rl.app.receivers.add(rl);
17095                } else {
17096                    try {
17097                        receiver.asBinder().linkToDeath(rl, 0);
17098                    } catch (RemoteException e) {
17099                        return sticky;
17100                    }
17101                    rl.linkedToDeath = true;
17102                }
17103                mRegisteredReceivers.put(receiver.asBinder(), rl);
17104            } else if (rl.uid != callingUid) {
17105                throw new IllegalArgumentException(
17106                        "Receiver requested to register for uid " + callingUid
17107                        + " was previously registered for uid " + rl.uid);
17108            } else if (rl.pid != callingPid) {
17109                throw new IllegalArgumentException(
17110                        "Receiver requested to register for pid " + callingPid
17111                        + " was previously registered for pid " + rl.pid);
17112            } else if (rl.userId != userId) {
17113                throw new IllegalArgumentException(
17114                        "Receiver requested to register for user " + userId
17115                        + " was previously registered for user " + rl.userId);
17116            }
17117            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17118                    permission, callingUid, userId);
17119            rl.add(bf);
17120            if (!bf.debugCheck()) {
17121                Slog.w(TAG, "==> For Dynamic broadcast");
17122            }
17123            mReceiverResolver.addFilter(bf);
17124
17125            // Enqueue broadcasts for all existing stickies that match
17126            // this filter.
17127            if (allSticky != null) {
17128                ArrayList receivers = new ArrayList();
17129                receivers.add(bf);
17130
17131                final int stickyCount = allSticky.size();
17132                for (int i = 0; i < stickyCount; i++) {
17133                    Intent intent = allSticky.get(i);
17134                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17135                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17136                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17137                            null, 0, null, null, false, true, true, -1);
17138                    queue.enqueueParallelBroadcastLocked(r);
17139                    queue.scheduleBroadcastsLocked();
17140                }
17141            }
17142
17143            return sticky;
17144        }
17145    }
17146
17147    public void unregisterReceiver(IIntentReceiver receiver) {
17148        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17149
17150        final long origId = Binder.clearCallingIdentity();
17151        try {
17152            boolean doTrim = false;
17153
17154            synchronized(this) {
17155                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17156                if (rl != null) {
17157                    final BroadcastRecord r = rl.curBroadcast;
17158                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17159                        final boolean doNext = r.queue.finishReceiverLocked(
17160                                r, r.resultCode, r.resultData, r.resultExtras,
17161                                r.resultAbort, false);
17162                        if (doNext) {
17163                            doTrim = true;
17164                            r.queue.processNextBroadcast(false);
17165                        }
17166                    }
17167
17168                    if (rl.app != null) {
17169                        rl.app.receivers.remove(rl);
17170                    }
17171                    removeReceiverLocked(rl);
17172                    if (rl.linkedToDeath) {
17173                        rl.linkedToDeath = false;
17174                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17175                    }
17176                }
17177            }
17178
17179            // If we actually concluded any broadcasts, we might now be able
17180            // to trim the recipients' apps from our working set
17181            if (doTrim) {
17182                trimApplications();
17183                return;
17184            }
17185
17186        } finally {
17187            Binder.restoreCallingIdentity(origId);
17188        }
17189    }
17190
17191    void removeReceiverLocked(ReceiverList rl) {
17192        mRegisteredReceivers.remove(rl.receiver.asBinder());
17193        for (int i = rl.size() - 1; i >= 0; i--) {
17194            mReceiverResolver.removeFilter(rl.get(i));
17195        }
17196    }
17197
17198    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17199        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17200            ProcessRecord r = mLruProcesses.get(i);
17201            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17202                try {
17203                    r.thread.dispatchPackageBroadcast(cmd, packages);
17204                } catch (RemoteException ex) {
17205                }
17206            }
17207        }
17208    }
17209
17210    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17211            int callingUid, int[] users) {
17212        // TODO: come back and remove this assumption to triage all broadcasts
17213        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17214
17215        List<ResolveInfo> receivers = null;
17216        try {
17217            HashSet<ComponentName> singleUserReceivers = null;
17218            boolean scannedFirstReceivers = false;
17219            for (int user : users) {
17220                // Skip users that have Shell restrictions, with exception of always permitted
17221                // Shell broadcasts
17222                if (callingUid == Process.SHELL_UID
17223                        && mUserController.hasUserRestriction(
17224                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17225                        && !isPermittedShellBroadcast(intent)) {
17226                    continue;
17227                }
17228                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17229                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17230                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17231                    // If this is not the system user, we need to check for
17232                    // any receivers that should be filtered out.
17233                    for (int i=0; i<newReceivers.size(); i++) {
17234                        ResolveInfo ri = newReceivers.get(i);
17235                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17236                            newReceivers.remove(i);
17237                            i--;
17238                        }
17239                    }
17240                }
17241                if (newReceivers != null && newReceivers.size() == 0) {
17242                    newReceivers = null;
17243                }
17244                if (receivers == null) {
17245                    receivers = newReceivers;
17246                } else if (newReceivers != null) {
17247                    // We need to concatenate the additional receivers
17248                    // found with what we have do far.  This would be easy,
17249                    // but we also need to de-dup any receivers that are
17250                    // singleUser.
17251                    if (!scannedFirstReceivers) {
17252                        // Collect any single user receivers we had already retrieved.
17253                        scannedFirstReceivers = true;
17254                        for (int i=0; i<receivers.size(); i++) {
17255                            ResolveInfo ri = receivers.get(i);
17256                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17257                                ComponentName cn = new ComponentName(
17258                                        ri.activityInfo.packageName, ri.activityInfo.name);
17259                                if (singleUserReceivers == null) {
17260                                    singleUserReceivers = new HashSet<ComponentName>();
17261                                }
17262                                singleUserReceivers.add(cn);
17263                            }
17264                        }
17265                    }
17266                    // Add the new results to the existing results, tracking
17267                    // and de-dupping single user receivers.
17268                    for (int i=0; i<newReceivers.size(); i++) {
17269                        ResolveInfo ri = newReceivers.get(i);
17270                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17271                            ComponentName cn = new ComponentName(
17272                                    ri.activityInfo.packageName, ri.activityInfo.name);
17273                            if (singleUserReceivers == null) {
17274                                singleUserReceivers = new HashSet<ComponentName>();
17275                            }
17276                            if (!singleUserReceivers.contains(cn)) {
17277                                singleUserReceivers.add(cn);
17278                                receivers.add(ri);
17279                            }
17280                        } else {
17281                            receivers.add(ri);
17282                        }
17283                    }
17284                }
17285            }
17286        } catch (RemoteException ex) {
17287            // pm is in same process, this will never happen.
17288        }
17289        return receivers;
17290    }
17291
17292    private boolean isPermittedShellBroadcast(Intent intent) {
17293        // remote bugreport should always be allowed to be taken
17294        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17295    }
17296
17297    final int broadcastIntentLocked(ProcessRecord callerApp,
17298            String callerPackage, Intent intent, String resolvedType,
17299            IIntentReceiver resultTo, int resultCode, String resultData,
17300            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17301            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17302        intent = new Intent(intent);
17303
17304        // By default broadcasts do not go to stopped apps.
17305        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17306
17307        // If we have not finished booting, don't allow this to launch new processes.
17308        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17309            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17310        }
17311
17312        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17313                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17314                + " ordered=" + ordered + " userid=" + userId);
17315        if ((resultTo != null) && !ordered) {
17316            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17317        }
17318
17319        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17320                ALLOW_NON_FULL, "broadcast", callerPackage);
17321
17322        // Make sure that the user who is receiving this broadcast is running.
17323        // If not, we will just skip it. Make an exception for shutdown broadcasts
17324        // and upgrade steps.
17325
17326        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17327            if ((callingUid != Process.SYSTEM_UID
17328                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17329                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17330                Slog.w(TAG, "Skipping broadcast of " + intent
17331                        + ": user " + userId + " is stopped");
17332                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17333            }
17334        }
17335
17336        BroadcastOptions brOptions = null;
17337        if (bOptions != null) {
17338            brOptions = new BroadcastOptions(bOptions);
17339            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17340                // See if the caller is allowed to do this.  Note we are checking against
17341                // the actual real caller (not whoever provided the operation as say a
17342                // PendingIntent), because that who is actually supplied the arguments.
17343                if (checkComponentPermission(
17344                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17345                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17346                        != PackageManager.PERMISSION_GRANTED) {
17347                    String msg = "Permission Denial: " + intent.getAction()
17348                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17349                            + ", uid=" + callingUid + ")"
17350                            + " requires "
17351                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17352                    Slog.w(TAG, msg);
17353                    throw new SecurityException(msg);
17354                }
17355            }
17356        }
17357
17358        // Verify that protected broadcasts are only being sent by system code,
17359        // and that system code is only sending protected broadcasts.
17360        final String action = intent.getAction();
17361        final boolean isProtectedBroadcast;
17362        try {
17363            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17364        } catch (RemoteException e) {
17365            Slog.w(TAG, "Remote exception", e);
17366            return ActivityManager.BROADCAST_SUCCESS;
17367        }
17368
17369        final boolean isCallerSystem;
17370        switch (UserHandle.getAppId(callingUid)) {
17371            case Process.ROOT_UID:
17372            case Process.SYSTEM_UID:
17373            case Process.PHONE_UID:
17374            case Process.BLUETOOTH_UID:
17375            case Process.NFC_UID:
17376                isCallerSystem = true;
17377                break;
17378            default:
17379                isCallerSystem = (callerApp != null) && callerApp.persistent;
17380                break;
17381        }
17382
17383        if (isCallerSystem) {
17384            if (isProtectedBroadcast
17385                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17386                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17387                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17388                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17389                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17390                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17391                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17392                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17393                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)) {
17394                // Broadcast is either protected, or it's a public action that
17395                // we've relaxed, so it's fine for system internals to send.
17396            } else {
17397                // The vast majority of broadcasts sent from system internals
17398                // should be protected to avoid security holes, so yell loudly
17399                // to ensure we examine these cases.
17400                Log.wtf(TAG, "Sending non-protected broadcast " + action
17401                        + " from system", new Throwable());
17402            }
17403
17404        } else {
17405            if (isProtectedBroadcast) {
17406                String msg = "Permission Denial: not allowed to send broadcast "
17407                        + action + " from pid="
17408                        + callingPid + ", uid=" + callingUid;
17409                Slog.w(TAG, msg);
17410                throw new SecurityException(msg);
17411
17412            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17413                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17414                // Special case for compatibility: we don't want apps to send this,
17415                // but historically it has not been protected and apps may be using it
17416                // to poke their own app widget.  So, instead of making it protected,
17417                // just limit it to the caller.
17418                if (callerPackage == null) {
17419                    String msg = "Permission Denial: not allowed to send broadcast "
17420                            + action + " from unknown caller.";
17421                    Slog.w(TAG, msg);
17422                    throw new SecurityException(msg);
17423                } else if (intent.getComponent() != null) {
17424                    // They are good enough to send to an explicit component...  verify
17425                    // it is being sent to the calling app.
17426                    if (!intent.getComponent().getPackageName().equals(
17427                            callerPackage)) {
17428                        String msg = "Permission Denial: not allowed to send broadcast "
17429                                + action + " to "
17430                                + intent.getComponent().getPackageName() + " from "
17431                                + callerPackage;
17432                        Slog.w(TAG, msg);
17433                        throw new SecurityException(msg);
17434                    }
17435                } else {
17436                    // Limit broadcast to their own package.
17437                    intent.setPackage(callerPackage);
17438                }
17439            }
17440        }
17441
17442        if (action != null) {
17443            switch (action) {
17444                case Intent.ACTION_UID_REMOVED:
17445                case Intent.ACTION_PACKAGE_REMOVED:
17446                case Intent.ACTION_PACKAGE_CHANGED:
17447                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17448                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17449                case Intent.ACTION_PACKAGES_SUSPENDED:
17450                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17451                    // Handle special intents: if this broadcast is from the package
17452                    // manager about a package being removed, we need to remove all of
17453                    // its activities from the history stack.
17454                    if (checkComponentPermission(
17455                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17456                            callingPid, callingUid, -1, true)
17457                            != PackageManager.PERMISSION_GRANTED) {
17458                        String msg = "Permission Denial: " + intent.getAction()
17459                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17460                                + ", uid=" + callingUid + ")"
17461                                + " requires "
17462                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17463                        Slog.w(TAG, msg);
17464                        throw new SecurityException(msg);
17465                    }
17466                    switch (action) {
17467                        case Intent.ACTION_UID_REMOVED:
17468                            final Bundle intentExtras = intent.getExtras();
17469                            final int uid = intentExtras != null
17470                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17471                            if (uid >= 0) {
17472                                mBatteryStatsService.removeUid(uid);
17473                                mAppOpsService.uidRemoved(uid);
17474                            }
17475                            break;
17476                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17477                            // If resources are unavailable just force stop all those packages
17478                            // and flush the attribute cache as well.
17479                            String list[] =
17480                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17481                            if (list != null && list.length > 0) {
17482                                for (int i = 0; i < list.length; i++) {
17483                                    forceStopPackageLocked(list[i], -1, false, true, true,
17484                                            false, false, userId, "storage unmount");
17485                                }
17486                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17487                                sendPackageBroadcastLocked(
17488                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17489                                        userId);
17490                            }
17491                            break;
17492                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17493                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17494                            break;
17495                        case Intent.ACTION_PACKAGE_REMOVED:
17496                        case Intent.ACTION_PACKAGE_CHANGED:
17497                            Uri data = intent.getData();
17498                            String ssp;
17499                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17500                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17501                                final boolean replacing =
17502                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17503                                final boolean killProcess =
17504                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17505                                final boolean fullUninstall = removed && !replacing;
17506                                if (killProcess) {
17507                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17508                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17509                                            false, true, true, false, fullUninstall, userId,
17510                                            removed ? "pkg removed" : "pkg changed");
17511                                }
17512                                if (removed) {
17513                                    final int cmd = killProcess
17514                                            ? IApplicationThread.PACKAGE_REMOVED
17515                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17516                                    sendPackageBroadcastLocked(cmd,
17517                                            new String[] {ssp}, userId);
17518                                    if (fullUninstall) {
17519                                        mAppOpsService.packageRemoved(
17520                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17521
17522                                        // Remove all permissions granted from/to this package
17523                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17524
17525                                        removeTasksByPackageNameLocked(ssp, userId);
17526                                        mBatteryStatsService.notePackageUninstalled(ssp);
17527                                    }
17528                                } else {
17529                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17530                                            intent.getStringArrayExtra(
17531                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17532                                }
17533                            }
17534                            break;
17535                        case Intent.ACTION_PACKAGES_SUSPENDED:
17536                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17537                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17538                                    intent.getAction());
17539                            final String[] packageNames = intent.getStringArrayExtra(
17540                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17541                            final int userHandle = intent.getIntExtra(
17542                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17543
17544                            synchronized(ActivityManagerService.this) {
17545                                mRecentTasks.onPackagesSuspendedChanged(
17546                                        packageNames, suspended, userHandle);
17547                            }
17548                            break;
17549                    }
17550                    break;
17551                case Intent.ACTION_PACKAGE_REPLACED:
17552                {
17553                    final Uri data = intent.getData();
17554                    final String ssp;
17555                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17556                        final ApplicationInfo aInfo =
17557                                getPackageManagerInternalLocked().getApplicationInfo(
17558                                        ssp,
17559                                        userId);
17560                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17561                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17562                                new String[] {ssp}, userId);
17563                    }
17564                    break;
17565                }
17566                case Intent.ACTION_PACKAGE_ADDED:
17567                {
17568                    // Special case for adding a package: by default turn on compatibility mode.
17569                    Uri data = intent.getData();
17570                    String ssp;
17571                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17572                        final boolean replacing =
17573                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17574                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17575
17576                        try {
17577                            ApplicationInfo ai = AppGlobals.getPackageManager().
17578                                    getApplicationInfo(ssp, 0, 0);
17579                            mBatteryStatsService.notePackageInstalled(ssp,
17580                                    ai != null ? ai.versionCode : 0);
17581                        } catch (RemoteException e) {
17582                        }
17583                    }
17584                    break;
17585                }
17586                case Intent.ACTION_TIMEZONE_CHANGED:
17587                    // If this is the time zone changed action, queue up a message that will reset
17588                    // the timezone of all currently running processes. This message will get
17589                    // queued up before the broadcast happens.
17590                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17591                    break;
17592                case Intent.ACTION_TIME_CHANGED:
17593                    // If the user set the time, let all running processes know.
17594                    final int is24Hour =
17595                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17596                                    : 0;
17597                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17598                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17599                    synchronized (stats) {
17600                        stats.noteCurrentTimeChangedLocked();
17601                    }
17602                    break;
17603                case Intent.ACTION_CLEAR_DNS_CACHE:
17604                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17605                    break;
17606                case Proxy.PROXY_CHANGE_ACTION:
17607                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17608                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17609                    break;
17610                case android.hardware.Camera.ACTION_NEW_PICTURE:
17611                case android.hardware.Camera.ACTION_NEW_VIDEO:
17612                    // These broadcasts are no longer allowed by the system, since they can
17613                    // cause significant thrashing at a crictical point (using the camera).
17614                    // Apps should use JobScehduler to monitor for media provider changes.
17615                    Slog.w(TAG, action + " no longer allowed; dropping from "
17616                            + UserHandle.formatUid(callingUid));
17617                    // Lie; we don't want to crash the app.
17618                    return ActivityManager.BROADCAST_SUCCESS;
17619            }
17620        }
17621
17622        // Add to the sticky list if requested.
17623        if (sticky) {
17624            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17625                    callingPid, callingUid)
17626                    != PackageManager.PERMISSION_GRANTED) {
17627                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17628                        + callingPid + ", uid=" + callingUid
17629                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17630                Slog.w(TAG, msg);
17631                throw new SecurityException(msg);
17632            }
17633            if (requiredPermissions != null && requiredPermissions.length > 0) {
17634                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17635                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17636                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17637            }
17638            if (intent.getComponent() != null) {
17639                throw new SecurityException(
17640                        "Sticky broadcasts can't target a specific component");
17641            }
17642            // We use userId directly here, since the "all" target is maintained
17643            // as a separate set of sticky broadcasts.
17644            if (userId != UserHandle.USER_ALL) {
17645                // But first, if this is not a broadcast to all users, then
17646                // make sure it doesn't conflict with an existing broadcast to
17647                // all users.
17648                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17649                        UserHandle.USER_ALL);
17650                if (stickies != null) {
17651                    ArrayList<Intent> list = stickies.get(intent.getAction());
17652                    if (list != null) {
17653                        int N = list.size();
17654                        int i;
17655                        for (i=0; i<N; i++) {
17656                            if (intent.filterEquals(list.get(i))) {
17657                                throw new IllegalArgumentException(
17658                                        "Sticky broadcast " + intent + " for user "
17659                                        + userId + " conflicts with existing global broadcast");
17660                            }
17661                        }
17662                    }
17663                }
17664            }
17665            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17666            if (stickies == null) {
17667                stickies = new ArrayMap<>();
17668                mStickyBroadcasts.put(userId, stickies);
17669            }
17670            ArrayList<Intent> list = stickies.get(intent.getAction());
17671            if (list == null) {
17672                list = new ArrayList<>();
17673                stickies.put(intent.getAction(), list);
17674            }
17675            final int stickiesCount = list.size();
17676            int i;
17677            for (i = 0; i < stickiesCount; i++) {
17678                if (intent.filterEquals(list.get(i))) {
17679                    // This sticky already exists, replace it.
17680                    list.set(i, new Intent(intent));
17681                    break;
17682                }
17683            }
17684            if (i >= stickiesCount) {
17685                list.add(new Intent(intent));
17686            }
17687        }
17688
17689        int[] users;
17690        if (userId == UserHandle.USER_ALL) {
17691            // Caller wants broadcast to go to all started users.
17692            users = mUserController.getStartedUserArrayLocked();
17693        } else {
17694            // Caller wants broadcast to go to one specific user.
17695            users = new int[] {userId};
17696        }
17697
17698        // Figure out who all will receive this broadcast.
17699        List receivers = null;
17700        List<BroadcastFilter> registeredReceivers = null;
17701        // Need to resolve the intent to interested receivers...
17702        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17703                 == 0) {
17704            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17705        }
17706        if (intent.getComponent() == null) {
17707            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17708                // Query one target user at a time, excluding shell-restricted users
17709                for (int i = 0; i < users.length; i++) {
17710                    if (mUserController.hasUserRestriction(
17711                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17712                        continue;
17713                    }
17714                    List<BroadcastFilter> registeredReceiversForUser =
17715                            mReceiverResolver.queryIntent(intent,
17716                                    resolvedType, false, users[i]);
17717                    if (registeredReceivers == null) {
17718                        registeredReceivers = registeredReceiversForUser;
17719                    } else if (registeredReceiversForUser != null) {
17720                        registeredReceivers.addAll(registeredReceiversForUser);
17721                    }
17722                }
17723            } else {
17724                registeredReceivers = mReceiverResolver.queryIntent(intent,
17725                        resolvedType, false, userId);
17726            }
17727        }
17728
17729        final boolean replacePending =
17730                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17731
17732        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17733                + " replacePending=" + replacePending);
17734
17735        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17736        if (!ordered && NR > 0) {
17737            // If we are not serializing this broadcast, then send the
17738            // registered receivers separately so they don't wait for the
17739            // components to be launched.
17740            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17741            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17742                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17743                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17744                    resultExtras, ordered, sticky, false, userId);
17745            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17746            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17747            if (!replaced) {
17748                queue.enqueueParallelBroadcastLocked(r);
17749                queue.scheduleBroadcastsLocked();
17750            }
17751            registeredReceivers = null;
17752            NR = 0;
17753        }
17754
17755        // Merge into one list.
17756        int ir = 0;
17757        if (receivers != null) {
17758            // A special case for PACKAGE_ADDED: do not allow the package
17759            // being added to see this broadcast.  This prevents them from
17760            // using this as a back door to get run as soon as they are
17761            // installed.  Maybe in the future we want to have a special install
17762            // broadcast or such for apps, but we'd like to deliberately make
17763            // this decision.
17764            String skipPackages[] = null;
17765            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17766                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17767                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17768                Uri data = intent.getData();
17769                if (data != null) {
17770                    String pkgName = data.getSchemeSpecificPart();
17771                    if (pkgName != null) {
17772                        skipPackages = new String[] { pkgName };
17773                    }
17774                }
17775            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17776                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17777            }
17778            if (skipPackages != null && (skipPackages.length > 0)) {
17779                for (String skipPackage : skipPackages) {
17780                    if (skipPackage != null) {
17781                        int NT = receivers.size();
17782                        for (int it=0; it<NT; it++) {
17783                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17784                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17785                                receivers.remove(it);
17786                                it--;
17787                                NT--;
17788                            }
17789                        }
17790                    }
17791                }
17792            }
17793
17794            int NT = receivers != null ? receivers.size() : 0;
17795            int it = 0;
17796            ResolveInfo curt = null;
17797            BroadcastFilter curr = null;
17798            while (it < NT && ir < NR) {
17799                if (curt == null) {
17800                    curt = (ResolveInfo)receivers.get(it);
17801                }
17802                if (curr == null) {
17803                    curr = registeredReceivers.get(ir);
17804                }
17805                if (curr.getPriority() >= curt.priority) {
17806                    // Insert this broadcast record into the final list.
17807                    receivers.add(it, curr);
17808                    ir++;
17809                    curr = null;
17810                    it++;
17811                    NT++;
17812                } else {
17813                    // Skip to the next ResolveInfo in the final list.
17814                    it++;
17815                    curt = null;
17816                }
17817            }
17818        }
17819        while (ir < NR) {
17820            if (receivers == null) {
17821                receivers = new ArrayList();
17822            }
17823            receivers.add(registeredReceivers.get(ir));
17824            ir++;
17825        }
17826
17827        if ((receivers != null && receivers.size() > 0)
17828                || resultTo != null) {
17829            BroadcastQueue queue = broadcastQueueForIntent(intent);
17830            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17831                    callerPackage, callingPid, callingUid, resolvedType,
17832                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17833                    resultData, resultExtras, ordered, sticky, false, userId);
17834
17835            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17836                    + ": prev had " + queue.mOrderedBroadcasts.size());
17837            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17838                    "Enqueueing broadcast " + r.intent.getAction());
17839
17840            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17841            if (!replaced) {
17842                queue.enqueueOrderedBroadcastLocked(r);
17843                queue.scheduleBroadcastsLocked();
17844            }
17845        }
17846
17847        return ActivityManager.BROADCAST_SUCCESS;
17848    }
17849
17850    final Intent verifyBroadcastLocked(Intent intent) {
17851        // Refuse possible leaked file descriptors
17852        if (intent != null && intent.hasFileDescriptors() == true) {
17853            throw new IllegalArgumentException("File descriptors passed in Intent");
17854        }
17855
17856        int flags = intent.getFlags();
17857
17858        if (!mProcessesReady) {
17859            // if the caller really truly claims to know what they're doing, go
17860            // ahead and allow the broadcast without launching any receivers
17861            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17862                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17863            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17864                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17865                        + " before boot completion");
17866                throw new IllegalStateException("Cannot broadcast before boot completed");
17867            }
17868        }
17869
17870        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17871            throw new IllegalArgumentException(
17872                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17873        }
17874
17875        return intent;
17876    }
17877
17878    public final int broadcastIntent(IApplicationThread caller,
17879            Intent intent, String resolvedType, IIntentReceiver resultTo,
17880            int resultCode, String resultData, Bundle resultExtras,
17881            String[] requiredPermissions, int appOp, Bundle bOptions,
17882            boolean serialized, boolean sticky, int userId) {
17883        enforceNotIsolatedCaller("broadcastIntent");
17884        synchronized(this) {
17885            intent = verifyBroadcastLocked(intent);
17886
17887            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17888            final int callingPid = Binder.getCallingPid();
17889            final int callingUid = Binder.getCallingUid();
17890            final long origId = Binder.clearCallingIdentity();
17891            int res = broadcastIntentLocked(callerApp,
17892                    callerApp != null ? callerApp.info.packageName : null,
17893                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17894                    requiredPermissions, appOp, bOptions, serialized, sticky,
17895                    callingPid, callingUid, userId);
17896            Binder.restoreCallingIdentity(origId);
17897            return res;
17898        }
17899    }
17900
17901
17902    int broadcastIntentInPackage(String packageName, int uid,
17903            Intent intent, String resolvedType, IIntentReceiver resultTo,
17904            int resultCode, String resultData, Bundle resultExtras,
17905            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17906            int userId) {
17907        synchronized(this) {
17908            intent = verifyBroadcastLocked(intent);
17909
17910            final long origId = Binder.clearCallingIdentity();
17911            String[] requiredPermissions = requiredPermission == null ? null
17912                    : new String[] {requiredPermission};
17913            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17914                    resultTo, resultCode, resultData, resultExtras,
17915                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17916                    sticky, -1, uid, userId);
17917            Binder.restoreCallingIdentity(origId);
17918            return res;
17919        }
17920    }
17921
17922    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17923        // Refuse possible leaked file descriptors
17924        if (intent != null && intent.hasFileDescriptors() == true) {
17925            throw new IllegalArgumentException("File descriptors passed in Intent");
17926        }
17927
17928        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17929                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17930
17931        synchronized(this) {
17932            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17933                    != PackageManager.PERMISSION_GRANTED) {
17934                String msg = "Permission Denial: unbroadcastIntent() from pid="
17935                        + Binder.getCallingPid()
17936                        + ", uid=" + Binder.getCallingUid()
17937                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17938                Slog.w(TAG, msg);
17939                throw new SecurityException(msg);
17940            }
17941            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17942            if (stickies != null) {
17943                ArrayList<Intent> list = stickies.get(intent.getAction());
17944                if (list != null) {
17945                    int N = list.size();
17946                    int i;
17947                    for (i=0; i<N; i++) {
17948                        if (intent.filterEquals(list.get(i))) {
17949                            list.remove(i);
17950                            break;
17951                        }
17952                    }
17953                    if (list.size() <= 0) {
17954                        stickies.remove(intent.getAction());
17955                    }
17956                }
17957                if (stickies.size() <= 0) {
17958                    mStickyBroadcasts.remove(userId);
17959                }
17960            }
17961        }
17962    }
17963
17964    void backgroundServicesFinishedLocked(int userId) {
17965        for (BroadcastQueue queue : mBroadcastQueues) {
17966            queue.backgroundServicesFinishedLocked(userId);
17967        }
17968    }
17969
17970    public void finishReceiver(IBinder who, int resultCode, String resultData,
17971            Bundle resultExtras, boolean resultAbort, int flags) {
17972        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17973
17974        // Refuse possible leaked file descriptors
17975        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17976            throw new IllegalArgumentException("File descriptors passed in Bundle");
17977        }
17978
17979        final long origId = Binder.clearCallingIdentity();
17980        try {
17981            boolean doNext = false;
17982            BroadcastRecord r;
17983
17984            synchronized(this) {
17985                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17986                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17987                r = queue.getMatchingOrderedReceiver(who);
17988                if (r != null) {
17989                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17990                        resultData, resultExtras, resultAbort, true);
17991                }
17992            }
17993
17994            if (doNext) {
17995                r.queue.processNextBroadcast(false);
17996            }
17997            trimApplications();
17998        } finally {
17999            Binder.restoreCallingIdentity(origId);
18000        }
18001    }
18002
18003    // =========================================================
18004    // INSTRUMENTATION
18005    // =========================================================
18006
18007    public boolean startInstrumentation(ComponentName className,
18008            String profileFile, int flags, Bundle arguments,
18009            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18010            int userId, String abiOverride) {
18011        enforceNotIsolatedCaller("startInstrumentation");
18012        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18013                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18014        // Refuse possible leaked file descriptors
18015        if (arguments != null && arguments.hasFileDescriptors()) {
18016            throw new IllegalArgumentException("File descriptors passed in Bundle");
18017        }
18018
18019        synchronized(this) {
18020            InstrumentationInfo ii = null;
18021            ApplicationInfo ai = null;
18022            try {
18023                ii = mContext.getPackageManager().getInstrumentationInfo(
18024                    className, STOCK_PM_FLAGS);
18025                ai = AppGlobals.getPackageManager().getApplicationInfo(
18026                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18027            } catch (PackageManager.NameNotFoundException e) {
18028            } catch (RemoteException e) {
18029            }
18030            if (ii == null) {
18031                reportStartInstrumentationFailureLocked(watcher, className,
18032                        "Unable to find instrumentation info for: " + className);
18033                return false;
18034            }
18035            if (ai == null) {
18036                reportStartInstrumentationFailureLocked(watcher, className,
18037                        "Unable to find instrumentation target package: " + ii.targetPackage);
18038                return false;
18039            }
18040            if (!ai.hasCode()) {
18041                reportStartInstrumentationFailureLocked(watcher, className,
18042                        "Instrumentation target has no code: " + ii.targetPackage);
18043                return false;
18044            }
18045
18046            int match = mContext.getPackageManager().checkSignatures(
18047                    ii.targetPackage, ii.packageName);
18048            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18049                String msg = "Permission Denial: starting instrumentation "
18050                        + className + " from pid="
18051                        + Binder.getCallingPid()
18052                        + ", uid=" + Binder.getCallingPid()
18053                        + " not allowed because package " + ii.packageName
18054                        + " does not have a signature matching the target "
18055                        + ii.targetPackage;
18056                reportStartInstrumentationFailureLocked(watcher, className, msg);
18057                throw new SecurityException(msg);
18058            }
18059
18060            final long origId = Binder.clearCallingIdentity();
18061            // Instrumentation can kill and relaunch even persistent processes
18062            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18063                    "start instr");
18064            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18065            app.instrumentationClass = className;
18066            app.instrumentationInfo = ai;
18067            app.instrumentationProfileFile = profileFile;
18068            app.instrumentationArguments = arguments;
18069            app.instrumentationWatcher = watcher;
18070            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18071            app.instrumentationResultClass = className;
18072            Binder.restoreCallingIdentity(origId);
18073        }
18074
18075        return true;
18076    }
18077
18078    /**
18079     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18080     * error to the logs, but if somebody is watching, send the report there too.  This enables
18081     * the "am" command to report errors with more information.
18082     *
18083     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18084     * @param cn The component name of the instrumentation.
18085     * @param report The error report.
18086     */
18087    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18088            ComponentName cn, String report) {
18089        Slog.w(TAG, report);
18090        if (watcher != null) {
18091            Bundle results = new Bundle();
18092            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18093            results.putString("Error", report);
18094            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18095        }
18096    }
18097
18098    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18099        if (app.instrumentationWatcher != null) {
18100            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18101                    app.instrumentationClass, resultCode, results);
18102        }
18103
18104        // Can't call out of the system process with a lock held, so post a message.
18105        if (app.instrumentationUiAutomationConnection != null) {
18106            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18107                    app.instrumentationUiAutomationConnection).sendToTarget();
18108        }
18109
18110        app.instrumentationWatcher = null;
18111        app.instrumentationUiAutomationConnection = null;
18112        app.instrumentationClass = null;
18113        app.instrumentationInfo = null;
18114        app.instrumentationProfileFile = null;
18115        app.instrumentationArguments = null;
18116
18117        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18118                "finished inst");
18119    }
18120
18121    public void finishInstrumentation(IApplicationThread target,
18122            int resultCode, Bundle results) {
18123        int userId = UserHandle.getCallingUserId();
18124        // Refuse possible leaked file descriptors
18125        if (results != null && results.hasFileDescriptors()) {
18126            throw new IllegalArgumentException("File descriptors passed in Intent");
18127        }
18128
18129        synchronized(this) {
18130            ProcessRecord app = getRecordForAppLocked(target);
18131            if (app == null) {
18132                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18133                return;
18134            }
18135            final long origId = Binder.clearCallingIdentity();
18136            finishInstrumentationLocked(app, resultCode, results);
18137            Binder.restoreCallingIdentity(origId);
18138        }
18139    }
18140
18141    // =========================================================
18142    // CONFIGURATION
18143    // =========================================================
18144
18145    public ConfigurationInfo getDeviceConfigurationInfo() {
18146        ConfigurationInfo config = new ConfigurationInfo();
18147        synchronized (this) {
18148            config.reqTouchScreen = mConfiguration.touchscreen;
18149            config.reqKeyboardType = mConfiguration.keyboard;
18150            config.reqNavigation = mConfiguration.navigation;
18151            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18152                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18153                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18154            }
18155            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18156                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18157                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18158            }
18159            config.reqGlEsVersion = GL_ES_VERSION;
18160        }
18161        return config;
18162    }
18163
18164    ActivityStack getFocusedStack() {
18165        return mStackSupervisor.getFocusedStack();
18166    }
18167
18168    @Override
18169    public int getFocusedStackId() throws RemoteException {
18170        ActivityStack focusedStack = getFocusedStack();
18171        if (focusedStack != null) {
18172            return focusedStack.getStackId();
18173        }
18174        return -1;
18175    }
18176
18177    public Configuration getConfiguration() {
18178        Configuration ci;
18179        synchronized(this) {
18180            ci = new Configuration(mConfiguration);
18181            ci.userSetLocale = false;
18182        }
18183        return ci;
18184    }
18185
18186    @Override
18187    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18188        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18189        synchronized (this) {
18190            mSuppressResizeConfigChanges = suppress;
18191        }
18192    }
18193
18194    @Override
18195    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18196        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18197        if (fromStackId == HOME_STACK_ID) {
18198            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18199        }
18200        synchronized (this) {
18201            final long origId = Binder.clearCallingIdentity();
18202            try {
18203                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18204            } finally {
18205                Binder.restoreCallingIdentity(origId);
18206            }
18207        }
18208    }
18209
18210    @Override
18211    public void updatePersistentConfiguration(Configuration values) {
18212        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18213                "updateConfiguration()");
18214        enforceWriteSettingsPermission("updateConfiguration()");
18215        if (values == null) {
18216            throw new NullPointerException("Configuration must not be null");
18217        }
18218
18219        int userId = UserHandle.getCallingUserId();
18220
18221        synchronized(this) {
18222            final long origId = Binder.clearCallingIdentity();
18223            updateConfigurationLocked(values, null, false, true, userId);
18224            Binder.restoreCallingIdentity(origId);
18225        }
18226    }
18227
18228    private void updateFontScaleIfNeeded() {
18229        final int currentUserId;
18230        synchronized(this) {
18231            currentUserId = mUserController.getCurrentUserIdLocked();
18232        }
18233        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18234                FONT_SCALE, 1.0f, currentUserId);
18235        if (mConfiguration.fontScale != scaleFactor) {
18236            final Configuration configuration = mWindowManager.computeNewConfiguration();
18237            configuration.fontScale = scaleFactor;
18238            updatePersistentConfiguration(configuration);
18239        }
18240    }
18241
18242    private void enforceWriteSettingsPermission(String func) {
18243        int uid = Binder.getCallingUid();
18244        if (uid == Process.ROOT_UID) {
18245            return;
18246        }
18247
18248        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18249                Settings.getPackageNameForUid(mContext, uid), false)) {
18250            return;
18251        }
18252
18253        String msg = "Permission Denial: " + func + " from pid="
18254                + Binder.getCallingPid()
18255                + ", uid=" + uid
18256                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18257        Slog.w(TAG, msg);
18258        throw new SecurityException(msg);
18259    }
18260
18261    public void updateConfiguration(Configuration values) {
18262        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18263                "updateConfiguration()");
18264
18265        synchronized(this) {
18266            if (values == null && mWindowManager != null) {
18267                // sentinel: fetch the current configuration from the window manager
18268                values = mWindowManager.computeNewConfiguration();
18269            }
18270
18271            if (mWindowManager != null) {
18272                mProcessList.applyDisplaySize(mWindowManager);
18273            }
18274
18275            final long origId = Binder.clearCallingIdentity();
18276            if (values != null) {
18277                Settings.System.clearConfiguration(values);
18278            }
18279            updateConfigurationLocked(values, null, false);
18280            Binder.restoreCallingIdentity(origId);
18281        }
18282    }
18283
18284    void updateUserConfigurationLocked() {
18285        Configuration configuration = new Configuration(mConfiguration);
18286        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18287                mUserController.getCurrentUserIdLocked());
18288        updateConfigurationLocked(configuration, null, false);
18289    }
18290
18291    boolean updateConfigurationLocked(Configuration values,
18292            ActivityRecord starting, boolean initLocale) {
18293        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18294        return updateConfigurationLocked(values, starting, initLocale, false,
18295                UserHandle.USER_NULL);
18296    }
18297
18298    // To cache the list of supported system locales
18299    private String[] mSupportedSystemLocales = null;
18300
18301    /**
18302     * Do either or both things: (1) change the current configuration, and (2)
18303     * make sure the given activity is running with the (now) current
18304     * configuration.  Returns true if the activity has been left running, or
18305     * false if <var>starting</var> is being destroyed to match the new
18306     * configuration.
18307     *
18308     * @param userId is only used when persistent parameter is set to true to persist configuration
18309     *               for that particular user
18310     */
18311    private boolean updateConfigurationLocked(Configuration values,
18312            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18313        int changes = 0;
18314
18315        if (mWindowManager != null) {
18316            mWindowManager.deferSurfaceLayout();
18317        }
18318        if (values != null) {
18319            Configuration newConfig = new Configuration(mConfiguration);
18320            changes = newConfig.updateFrom(values);
18321            if (changes != 0) {
18322                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18323                        "Updating configuration to: " + values);
18324
18325                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18326
18327                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18328                    final Locale locale;
18329                    if (values.getLocales().size() == 1) {
18330                        // This is an optimization to avoid the JNI call when the result of
18331                        // getFirstMatch() does not depend on the supported locales.
18332                        locale = values.getLocales().get(0);
18333                    } else {
18334                        if (mSupportedSystemLocales == null) {
18335                            mSupportedSystemLocales =
18336                                    Resources.getSystem().getAssets().getLocales();
18337                        }
18338                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18339                    }
18340                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18341                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18342                            locale));
18343                }
18344
18345                mConfigurationSeq++;
18346                if (mConfigurationSeq <= 0) {
18347                    mConfigurationSeq = 1;
18348                }
18349                newConfig.seq = mConfigurationSeq;
18350                mConfiguration = newConfig;
18351                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18352                mUsageStatsService.reportConfigurationChange(newConfig,
18353                        mUserController.getCurrentUserIdLocked());
18354                //mUsageStatsService.noteStartConfig(newConfig);
18355
18356                final Configuration configCopy = new Configuration(mConfiguration);
18357
18358                // TODO: If our config changes, should we auto dismiss any currently
18359                // showing dialogs?
18360                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18361
18362                AttributeCache ac = AttributeCache.instance();
18363                if (ac != null) {
18364                    ac.updateConfiguration(configCopy);
18365                }
18366
18367                // Make sure all resources in our process are updated
18368                // right now, so that anyone who is going to retrieve
18369                // resource values after we return will be sure to get
18370                // the new ones.  This is especially important during
18371                // boot, where the first config change needs to guarantee
18372                // all resources have that config before following boot
18373                // code is executed.
18374                mSystemThread.applyConfigurationToResources(configCopy);
18375
18376                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18377                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18378                    msg.obj = new Configuration(configCopy);
18379                    msg.arg1 = userId;
18380                    mHandler.sendMessage(msg);
18381                }
18382
18383                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18384                if (isDensityChange) {
18385                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18386                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18387                }
18388
18389                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18390                    ProcessRecord app = mLruProcesses.get(i);
18391                    try {
18392                        if (app.thread != null) {
18393                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18394                                    + app.processName + " new config " + mConfiguration);
18395                            app.thread.scheduleConfigurationChanged(configCopy);
18396                        }
18397                    } catch (Exception e) {
18398                    }
18399                }
18400                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18401                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18402                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18403                        | Intent.FLAG_RECEIVER_FOREGROUND);
18404                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18405                        null, AppOpsManager.OP_NONE, null, false, false,
18406                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18407                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18408                    // Tell the shortcut manager that the system locale changed.  It needs to know
18409                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18410                    // we "push" from here, rather than having the service listen to the broadcast.
18411                    final ShortcutServiceInternal shortcutService =
18412                            LocalServices.getService(ShortcutServiceInternal.class);
18413                    if (shortcutService != null) {
18414                        shortcutService.onSystemLocaleChangedNoLock();
18415                    }
18416
18417                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18418                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18419                    if (!mProcessesReady) {
18420                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18421                    }
18422                    broadcastIntentLocked(null, null, intent,
18423                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18424                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18425                }
18426            }
18427            // Update the configuration with WM first and check if any of the stacks need to be
18428            // resized due to the configuration change. If so, resize the stacks now and do any
18429            // relaunches if necessary. This way we don't need to relaunch again below in
18430            // ensureActivityConfigurationLocked().
18431            if (mWindowManager != null) {
18432                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18433                if (resizedStacks != null) {
18434                    for (int stackId : resizedStacks) {
18435                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18436                        mStackSupervisor.resizeStackLocked(
18437                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18438                    }
18439                }
18440            }
18441        }
18442
18443        boolean kept = true;
18444        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18445        // mainStack is null during startup.
18446        if (mainStack != null) {
18447            if (changes != 0 && starting == null) {
18448                // If the configuration changed, and the caller is not already
18449                // in the process of starting an activity, then find the top
18450                // activity to check if its configuration needs to change.
18451                starting = mainStack.topRunningActivityLocked();
18452            }
18453
18454            if (starting != null) {
18455                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18456                // And we need to make sure at this point that all other activities
18457                // are made visible with the correct configuration.
18458                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18459                        !PRESERVE_WINDOWS);
18460            }
18461        }
18462        if (mWindowManager != null) {
18463            mWindowManager.continueSurfaceLayout();
18464        }
18465        return kept;
18466    }
18467
18468    /**
18469     * Decide based on the configuration whether we should shouw the ANR,
18470     * crash, etc dialogs.  The idea is that if there is no affordnace to
18471     * press the on-screen buttons, we shouldn't show the dialog.
18472     *
18473     * A thought: SystemUI might also want to get told about this, the Power
18474     * dialog / global actions also might want different behaviors.
18475     */
18476    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18477        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18478                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18479                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18480        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18481                                    == Configuration.UI_MODE_TYPE_CAR);
18482        return inputMethodExists && uiIsNotCarType && !inVrMode;
18483    }
18484
18485    @Override
18486    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18487        synchronized (this) {
18488            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18489            if (srec != null) {
18490                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18491            }
18492        }
18493        return false;
18494    }
18495
18496    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18497            Intent resultData) {
18498
18499        synchronized (this) {
18500            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18501            if (r != null) {
18502                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18503            }
18504            return false;
18505        }
18506    }
18507
18508    public int getLaunchedFromUid(IBinder activityToken) {
18509        ActivityRecord srec;
18510        synchronized (this) {
18511            srec = ActivityRecord.forTokenLocked(activityToken);
18512        }
18513        if (srec == null) {
18514            return -1;
18515        }
18516        return srec.launchedFromUid;
18517    }
18518
18519    public String getLaunchedFromPackage(IBinder activityToken) {
18520        ActivityRecord srec;
18521        synchronized (this) {
18522            srec = ActivityRecord.forTokenLocked(activityToken);
18523        }
18524        if (srec == null) {
18525            return null;
18526        }
18527        return srec.launchedFromPackage;
18528    }
18529
18530    // =========================================================
18531    // LIFETIME MANAGEMENT
18532    // =========================================================
18533
18534    // Returns which broadcast queue the app is the current [or imminent] receiver
18535    // on, or 'null' if the app is not an active broadcast recipient.
18536    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18537        BroadcastRecord r = app.curReceiver;
18538        if (r != null) {
18539            return r.queue;
18540        }
18541
18542        // It's not the current receiver, but it might be starting up to become one
18543        synchronized (this) {
18544            for (BroadcastQueue queue : mBroadcastQueues) {
18545                r = queue.mPendingBroadcast;
18546                if (r != null && r.curApp == app) {
18547                    // found it; report which queue it's in
18548                    return queue;
18549                }
18550            }
18551        }
18552
18553        return null;
18554    }
18555
18556    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18557            int targetUid, ComponentName targetComponent, String targetProcess) {
18558        if (!mTrackingAssociations) {
18559            return null;
18560        }
18561        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18562                = mAssociations.get(targetUid);
18563        if (components == null) {
18564            components = new ArrayMap<>();
18565            mAssociations.put(targetUid, components);
18566        }
18567        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18568        if (sourceUids == null) {
18569            sourceUids = new SparseArray<>();
18570            components.put(targetComponent, sourceUids);
18571        }
18572        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18573        if (sourceProcesses == null) {
18574            sourceProcesses = new ArrayMap<>();
18575            sourceUids.put(sourceUid, sourceProcesses);
18576        }
18577        Association ass = sourceProcesses.get(sourceProcess);
18578        if (ass == null) {
18579            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18580                    targetProcess);
18581            sourceProcesses.put(sourceProcess, ass);
18582        }
18583        ass.mCount++;
18584        ass.mNesting++;
18585        if (ass.mNesting == 1) {
18586            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18587            ass.mLastState = sourceState;
18588        }
18589        return ass;
18590    }
18591
18592    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18593            ComponentName targetComponent) {
18594        if (!mTrackingAssociations) {
18595            return;
18596        }
18597        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18598                = mAssociations.get(targetUid);
18599        if (components == null) {
18600            return;
18601        }
18602        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18603        if (sourceUids == null) {
18604            return;
18605        }
18606        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18607        if (sourceProcesses == null) {
18608            return;
18609        }
18610        Association ass = sourceProcesses.get(sourceProcess);
18611        if (ass == null || ass.mNesting <= 0) {
18612            return;
18613        }
18614        ass.mNesting--;
18615        if (ass.mNesting == 0) {
18616            long uptime = SystemClock.uptimeMillis();
18617            ass.mTime += uptime - ass.mStartTime;
18618            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18619                    += uptime - ass.mLastStateUptime;
18620            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18621        }
18622    }
18623
18624    private void noteUidProcessState(final int uid, final int state) {
18625        mBatteryStatsService.noteUidProcessState(uid, state);
18626        if (mTrackingAssociations) {
18627            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18628                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18629                        = mAssociations.valueAt(i1);
18630                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18631                    SparseArray<ArrayMap<String, Association>> sourceUids
18632                            = targetComponents.valueAt(i2);
18633                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18634                    if (sourceProcesses != null) {
18635                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18636                            Association ass = sourceProcesses.valueAt(i4);
18637                            if (ass.mNesting >= 1) {
18638                                // currently associated
18639                                long uptime = SystemClock.uptimeMillis();
18640                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18641                                        += uptime - ass.mLastStateUptime;
18642                                ass.mLastState = state;
18643                                ass.mLastStateUptime = uptime;
18644                            }
18645                        }
18646                    }
18647                }
18648            }
18649        }
18650    }
18651
18652    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18653            boolean doingAll, long now) {
18654        if (mAdjSeq == app.adjSeq) {
18655            // This adjustment has already been computed.
18656            return app.curRawAdj;
18657        }
18658
18659        if (app.thread == null) {
18660            app.adjSeq = mAdjSeq;
18661            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18662            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18663            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18664        }
18665
18666        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18667        app.adjSource = null;
18668        app.adjTarget = null;
18669        app.empty = false;
18670        app.cached = false;
18671
18672        final int activitiesSize = app.activities.size();
18673
18674        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18675            // The max adjustment doesn't allow this app to be anything
18676            // below foreground, so it is not worth doing work for it.
18677            app.adjType = "fixed";
18678            app.adjSeq = mAdjSeq;
18679            app.curRawAdj = app.maxAdj;
18680            app.foregroundActivities = false;
18681            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18682            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18683            // System processes can do UI, and when they do we want to have
18684            // them trim their memory after the user leaves the UI.  To
18685            // facilitate this, here we need to determine whether or not it
18686            // is currently showing UI.
18687            app.systemNoUi = true;
18688            if (app == TOP_APP) {
18689                app.systemNoUi = false;
18690                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18691                app.adjType = "pers-top-activity";
18692            } else if (activitiesSize > 0) {
18693                for (int j = 0; j < activitiesSize; j++) {
18694                    final ActivityRecord r = app.activities.get(j);
18695                    if (r.visible) {
18696                        app.systemNoUi = false;
18697                    }
18698                }
18699            }
18700            if (!app.systemNoUi) {
18701                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18702            }
18703            return (app.curAdj=app.maxAdj);
18704        }
18705
18706        app.systemNoUi = false;
18707
18708        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18709
18710        // Determine the importance of the process, starting with most
18711        // important to least, and assign an appropriate OOM adjustment.
18712        int adj;
18713        int schedGroup;
18714        int procState;
18715        boolean foregroundActivities = false;
18716        BroadcastQueue queue;
18717        if (app == TOP_APP) {
18718            // The last app on the list is the foreground app.
18719            adj = ProcessList.FOREGROUND_APP_ADJ;
18720            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18721            app.adjType = "top-activity";
18722            foregroundActivities = true;
18723            procState = PROCESS_STATE_CUR_TOP;
18724        } else if (app.instrumentationClass != null) {
18725            // Don't want to kill running instrumentation.
18726            adj = ProcessList.FOREGROUND_APP_ADJ;
18727            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18728            app.adjType = "instrumentation";
18729            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18730        } else if ((queue = isReceivingBroadcast(app)) != null) {
18731            // An app that is currently receiving a broadcast also
18732            // counts as being in the foreground for OOM killer purposes.
18733            // It's placed in a sched group based on the nature of the
18734            // broadcast as reflected by which queue it's active in.
18735            adj = ProcessList.FOREGROUND_APP_ADJ;
18736            schedGroup = (queue == mFgBroadcastQueue)
18737                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18738            app.adjType = "broadcast";
18739            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18740        } else if (app.executingServices.size() > 0) {
18741            // An app that is currently executing a service callback also
18742            // counts as being in the foreground.
18743            adj = ProcessList.FOREGROUND_APP_ADJ;
18744            schedGroup = app.execServicesFg ?
18745                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18746            app.adjType = "exec-service";
18747            procState = ActivityManager.PROCESS_STATE_SERVICE;
18748            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18749        } else {
18750            // As far as we know the process is empty.  We may change our mind later.
18751            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18752            // At this point we don't actually know the adjustment.  Use the cached adj
18753            // value that the caller wants us to.
18754            adj = cachedAdj;
18755            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18756            app.cached = true;
18757            app.empty = true;
18758            app.adjType = "cch-empty";
18759        }
18760
18761        // Examine all activities if not already foreground.
18762        if (!foregroundActivities && activitiesSize > 0) {
18763            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18764            for (int j = 0; j < activitiesSize; j++) {
18765                final ActivityRecord r = app.activities.get(j);
18766                if (r.app != app) {
18767                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18768                            + " instead of expected " + app);
18769                    if (r.app == null || (r.app.uid == app.uid)) {
18770                        // Only fix things up when they look sane
18771                        r.app = app;
18772                    } else {
18773                        continue;
18774                    }
18775                }
18776                if (r.visible) {
18777                    // App has a visible activity; only upgrade adjustment.
18778                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18779                        adj = ProcessList.VISIBLE_APP_ADJ;
18780                        app.adjType = "visible";
18781                    }
18782                    if (procState > PROCESS_STATE_CUR_TOP) {
18783                        procState = PROCESS_STATE_CUR_TOP;
18784                    }
18785                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18786                    app.cached = false;
18787                    app.empty = false;
18788                    foregroundActivities = true;
18789                    if (r.task != null && minLayer > 0) {
18790                        final int layer = r.task.mLayerRank;
18791                        if (layer >= 0 && minLayer > layer) {
18792                            minLayer = layer;
18793                        }
18794                    }
18795                    break;
18796                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18797                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18798                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18799                        app.adjType = "pausing";
18800                    }
18801                    if (procState > PROCESS_STATE_CUR_TOP) {
18802                        procState = PROCESS_STATE_CUR_TOP;
18803                    }
18804                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18805                    app.cached = false;
18806                    app.empty = false;
18807                    foregroundActivities = true;
18808                } else if (r.state == ActivityState.STOPPING) {
18809                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18810                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18811                        app.adjType = "stopping";
18812                    }
18813                    // For the process state, we will at this point consider the
18814                    // process to be cached.  It will be cached either as an activity
18815                    // or empty depending on whether the activity is finishing.  We do
18816                    // this so that we can treat the process as cached for purposes of
18817                    // memory trimming (determing current memory level, trim command to
18818                    // send to process) since there can be an arbitrary number of stopping
18819                    // processes and they should soon all go into the cached state.
18820                    if (!r.finishing) {
18821                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18822                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18823                        }
18824                    }
18825                    app.cached = false;
18826                    app.empty = false;
18827                    foregroundActivities = true;
18828                } else {
18829                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18830                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18831                        app.adjType = "cch-act";
18832                    }
18833                }
18834            }
18835            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18836                adj += minLayer;
18837            }
18838        }
18839
18840        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18841                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18842            if (app.foregroundServices) {
18843                // The user is aware of this app, so make it visible.
18844                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18845                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18846                app.cached = false;
18847                app.adjType = "fg-service";
18848                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18849            } else if (app.forcingToForeground != null) {
18850                // The user is aware of this app, so make it visible.
18851                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18852                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18853                app.cached = false;
18854                app.adjType = "force-fg";
18855                app.adjSource = app.forcingToForeground;
18856                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18857            }
18858        }
18859
18860        if (app == mHeavyWeightProcess) {
18861            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18862                // We don't want to kill the current heavy-weight process.
18863                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18864                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18865                app.cached = false;
18866                app.adjType = "heavy";
18867            }
18868            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18869                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18870            }
18871        }
18872
18873        if (app == mHomeProcess) {
18874            if (adj > ProcessList.HOME_APP_ADJ) {
18875                // This process is hosting what we currently consider to be the
18876                // home app, so we don't want to let it go into the background.
18877                adj = ProcessList.HOME_APP_ADJ;
18878                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18879                app.cached = false;
18880                app.adjType = "home";
18881            }
18882            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18883                procState = ActivityManager.PROCESS_STATE_HOME;
18884            }
18885        }
18886
18887        if (app == mPreviousProcess && app.activities.size() > 0) {
18888            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18889                // This was the previous process that showed UI to the user.
18890                // We want to try to keep it around more aggressively, to give
18891                // a good experience around switching between two apps.
18892                adj = ProcessList.PREVIOUS_APP_ADJ;
18893                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18894                app.cached = false;
18895                app.adjType = "previous";
18896            }
18897            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18898                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18899            }
18900        }
18901
18902        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18903                + " reason=" + app.adjType);
18904
18905        // By default, we use the computed adjustment.  It may be changed if
18906        // there are applications dependent on our services or providers, but
18907        // this gives us a baseline and makes sure we don't get into an
18908        // infinite recursion.
18909        app.adjSeq = mAdjSeq;
18910        app.curRawAdj = adj;
18911        app.hasStartedServices = false;
18912
18913        if (mBackupTarget != null && app == mBackupTarget.app) {
18914            // If possible we want to avoid killing apps while they're being backed up
18915            if (adj > ProcessList.BACKUP_APP_ADJ) {
18916                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18917                adj = ProcessList.BACKUP_APP_ADJ;
18918                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18919                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18920                }
18921                app.adjType = "backup";
18922                app.cached = false;
18923            }
18924            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18925                procState = ActivityManager.PROCESS_STATE_BACKUP;
18926            }
18927        }
18928
18929        boolean mayBeTop = false;
18930
18931        for (int is = app.services.size()-1;
18932                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18933                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18934                        || procState > ActivityManager.PROCESS_STATE_TOP);
18935                is--) {
18936            ServiceRecord s = app.services.valueAt(is);
18937            if (s.startRequested) {
18938                app.hasStartedServices = true;
18939                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18940                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18941                }
18942                if (app.hasShownUi && app != mHomeProcess) {
18943                    // If this process has shown some UI, let it immediately
18944                    // go to the LRU list because it may be pretty heavy with
18945                    // UI stuff.  We'll tag it with a label just to help
18946                    // debug and understand what is going on.
18947                    if (adj > ProcessList.SERVICE_ADJ) {
18948                        app.adjType = "cch-started-ui-services";
18949                    }
18950                } else {
18951                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18952                        // This service has seen some activity within
18953                        // recent memory, so we will keep its process ahead
18954                        // of the background processes.
18955                        if (adj > ProcessList.SERVICE_ADJ) {
18956                            adj = ProcessList.SERVICE_ADJ;
18957                            app.adjType = "started-services";
18958                            app.cached = false;
18959                        }
18960                    }
18961                    // If we have let the service slide into the background
18962                    // state, still have some text describing what it is doing
18963                    // even though the service no longer has an impact.
18964                    if (adj > ProcessList.SERVICE_ADJ) {
18965                        app.adjType = "cch-started-services";
18966                    }
18967                }
18968            }
18969            for (int conni = s.connections.size()-1;
18970                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18971                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18972                            || procState > ActivityManager.PROCESS_STATE_TOP);
18973                    conni--) {
18974                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18975                for (int i = 0;
18976                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18977                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18978                                || procState > ActivityManager.PROCESS_STATE_TOP);
18979                        i++) {
18980                    // XXX should compute this based on the max of
18981                    // all connected clients.
18982                    ConnectionRecord cr = clist.get(i);
18983                    if (cr.binding.client == app) {
18984                        // Binding to ourself is not interesting.
18985                        continue;
18986                    }
18987                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18988                        ProcessRecord client = cr.binding.client;
18989                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18990                                TOP_APP, doingAll, now);
18991                        int clientProcState = client.curProcState;
18992                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18993                            // If the other app is cached for any reason, for purposes here
18994                            // we are going to consider it empty.  The specific cached state
18995                            // doesn't propagate except under certain conditions.
18996                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18997                        }
18998                        String adjType = null;
18999                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19000                            // Not doing bind OOM management, so treat
19001                            // this guy more like a started service.
19002                            if (app.hasShownUi && app != mHomeProcess) {
19003                                // If this process has shown some UI, let it immediately
19004                                // go to the LRU list because it may be pretty heavy with
19005                                // UI stuff.  We'll tag it with a label just to help
19006                                // debug and understand what is going on.
19007                                if (adj > clientAdj) {
19008                                    adjType = "cch-bound-ui-services";
19009                                }
19010                                app.cached = false;
19011                                clientAdj = adj;
19012                                clientProcState = procState;
19013                            } else {
19014                                if (now >= (s.lastActivity
19015                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19016                                    // This service has not seen activity within
19017                                    // recent memory, so allow it to drop to the
19018                                    // LRU list if there is no other reason to keep
19019                                    // it around.  We'll also tag it with a label just
19020                                    // to help debug and undertand what is going on.
19021                                    if (adj > clientAdj) {
19022                                        adjType = "cch-bound-services";
19023                                    }
19024                                    clientAdj = adj;
19025                                }
19026                            }
19027                        }
19028                        if (adj > clientAdj) {
19029                            // If this process has recently shown UI, and
19030                            // the process that is binding to it is less
19031                            // important than being visible, then we don't
19032                            // care about the binding as much as we care
19033                            // about letting this process get into the LRU
19034                            // list to be killed and restarted if needed for
19035                            // memory.
19036                            if (app.hasShownUi && app != mHomeProcess
19037                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19038                                adjType = "cch-bound-ui-services";
19039                            } else {
19040                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19041                                        |Context.BIND_IMPORTANT)) != 0) {
19042                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19043                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19044                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19045                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19046                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19047                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19048                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19049                                    adj = clientAdj;
19050                                } else {
19051                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19052                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19053                                    }
19054                                }
19055                                if (!client.cached) {
19056                                    app.cached = false;
19057                                }
19058                                adjType = "service";
19059                            }
19060                        }
19061                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19062                            // This will treat important bound services identically to
19063                            // the top app, which may behave differently than generic
19064                            // foreground work.
19065                            if (client.curSchedGroup > schedGroup) {
19066                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19067                                    schedGroup = client.curSchedGroup;
19068                                } else {
19069                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19070                                }
19071                            }
19072                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19073                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19074                                    // Special handling of clients who are in the top state.
19075                                    // We *may* want to consider this process to be in the
19076                                    // top state as well, but only if there is not another
19077                                    // reason for it to be running.  Being on the top is a
19078                                    // special state, meaning you are specifically running
19079                                    // for the current top app.  If the process is already
19080                                    // running in the background for some other reason, it
19081                                    // is more important to continue considering it to be
19082                                    // in the background state.
19083                                    mayBeTop = true;
19084                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19085                                } else {
19086                                    // Special handling for above-top states (persistent
19087                                    // processes).  These should not bring the current process
19088                                    // into the top state, since they are not on top.  Instead
19089                                    // give them the best state after that.
19090                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19091                                        clientProcState =
19092                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19093                                    } else if (mWakefulness
19094                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19095                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19096                                                    != 0) {
19097                                        clientProcState =
19098                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19099                                    } else {
19100                                        clientProcState =
19101                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19102                                    }
19103                                }
19104                            }
19105                        } else {
19106                            if (clientProcState <
19107                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19108                                clientProcState =
19109                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19110                            }
19111                        }
19112                        if (procState > clientProcState) {
19113                            procState = clientProcState;
19114                        }
19115                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19116                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19117                            app.pendingUiClean = true;
19118                        }
19119                        if (adjType != null) {
19120                            app.adjType = adjType;
19121                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19122                                    .REASON_SERVICE_IN_USE;
19123                            app.adjSource = cr.binding.client;
19124                            app.adjSourceProcState = clientProcState;
19125                            app.adjTarget = s.name;
19126                        }
19127                    }
19128                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19129                        app.treatLikeActivity = true;
19130                    }
19131                    final ActivityRecord a = cr.activity;
19132                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19133                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19134                            (a.visible || a.state == ActivityState.RESUMED ||
19135                             a.state == ActivityState.PAUSING)) {
19136                            adj = ProcessList.FOREGROUND_APP_ADJ;
19137                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19138                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19139                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19140                                } else {
19141                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19142                                }
19143                            }
19144                            app.cached = false;
19145                            app.adjType = "service";
19146                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19147                                    .REASON_SERVICE_IN_USE;
19148                            app.adjSource = a;
19149                            app.adjSourceProcState = procState;
19150                            app.adjTarget = s.name;
19151                        }
19152                    }
19153                }
19154            }
19155        }
19156
19157        for (int provi = app.pubProviders.size()-1;
19158                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19159                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19160                        || procState > ActivityManager.PROCESS_STATE_TOP);
19161                provi--) {
19162            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19163            for (int i = cpr.connections.size()-1;
19164                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19165                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19166                            || procState > ActivityManager.PROCESS_STATE_TOP);
19167                    i--) {
19168                ContentProviderConnection conn = cpr.connections.get(i);
19169                ProcessRecord client = conn.client;
19170                if (client == app) {
19171                    // Being our own client is not interesting.
19172                    continue;
19173                }
19174                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19175                int clientProcState = client.curProcState;
19176                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19177                    // If the other app is cached for any reason, for purposes here
19178                    // we are going to consider it empty.
19179                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19180                }
19181                if (adj > clientAdj) {
19182                    if (app.hasShownUi && app != mHomeProcess
19183                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19184                        app.adjType = "cch-ui-provider";
19185                    } else {
19186                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19187                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19188                        app.adjType = "provider";
19189                    }
19190                    app.cached &= client.cached;
19191                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19192                            .REASON_PROVIDER_IN_USE;
19193                    app.adjSource = client;
19194                    app.adjSourceProcState = clientProcState;
19195                    app.adjTarget = cpr.name;
19196                }
19197                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19198                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19199                        // Special handling of clients who are in the top state.
19200                        // We *may* want to consider this process to be in the
19201                        // top state as well, but only if there is not another
19202                        // reason for it to be running.  Being on the top is a
19203                        // special state, meaning you are specifically running
19204                        // for the current top app.  If the process is already
19205                        // running in the background for some other reason, it
19206                        // is more important to continue considering it to be
19207                        // in the background state.
19208                        mayBeTop = true;
19209                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19210                    } else {
19211                        // Special handling for above-top states (persistent
19212                        // processes).  These should not bring the current process
19213                        // into the top state, since they are not on top.  Instead
19214                        // give them the best state after that.
19215                        clientProcState =
19216                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19217                    }
19218                }
19219                if (procState > clientProcState) {
19220                    procState = clientProcState;
19221                }
19222                if (client.curSchedGroup > schedGroup) {
19223                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19224                }
19225            }
19226            // If the provider has external (non-framework) process
19227            // dependencies, ensure that its adjustment is at least
19228            // FOREGROUND_APP_ADJ.
19229            if (cpr.hasExternalProcessHandles()) {
19230                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19231                    adj = ProcessList.FOREGROUND_APP_ADJ;
19232                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19233                    app.cached = false;
19234                    app.adjType = "provider";
19235                    app.adjTarget = cpr.name;
19236                }
19237                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19238                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19239                }
19240            }
19241        }
19242
19243        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19244            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19245                adj = ProcessList.PREVIOUS_APP_ADJ;
19246                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19247                app.cached = false;
19248                app.adjType = "provider";
19249            }
19250            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19251                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19252            }
19253        }
19254
19255        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19256            // A client of one of our services or providers is in the top state.  We
19257            // *may* want to be in the top state, but not if we are already running in
19258            // the background for some other reason.  For the decision here, we are going
19259            // to pick out a few specific states that we want to remain in when a client
19260            // is top (states that tend to be longer-term) and otherwise allow it to go
19261            // to the top state.
19262            switch (procState) {
19263                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19264                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19265                case ActivityManager.PROCESS_STATE_SERVICE:
19266                    // These all are longer-term states, so pull them up to the top
19267                    // of the background states, but not all the way to the top state.
19268                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19269                    break;
19270                default:
19271                    // Otherwise, top is a better choice, so take it.
19272                    procState = ActivityManager.PROCESS_STATE_TOP;
19273                    break;
19274            }
19275        }
19276
19277        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19278            if (app.hasClientActivities) {
19279                // This is a cached process, but with client activities.  Mark it so.
19280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19281                app.adjType = "cch-client-act";
19282            } else if (app.treatLikeActivity) {
19283                // This is a cached process, but somebody wants us to treat it like it has
19284                // an activity, okay!
19285                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19286                app.adjType = "cch-as-act";
19287            }
19288        }
19289
19290        if (adj == ProcessList.SERVICE_ADJ) {
19291            if (doingAll) {
19292                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19293                mNewNumServiceProcs++;
19294                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19295                if (!app.serviceb) {
19296                    // This service isn't far enough down on the LRU list to
19297                    // normally be a B service, but if we are low on RAM and it
19298                    // is large we want to force it down since we would prefer to
19299                    // keep launcher over it.
19300                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19301                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19302                        app.serviceHighRam = true;
19303                        app.serviceb = true;
19304                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19305                    } else {
19306                        mNewNumAServiceProcs++;
19307                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19308                    }
19309                } else {
19310                    app.serviceHighRam = false;
19311                }
19312            }
19313            if (app.serviceb) {
19314                adj = ProcessList.SERVICE_B_ADJ;
19315            }
19316        }
19317
19318        app.curRawAdj = adj;
19319
19320        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19321        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19322        if (adj > app.maxAdj) {
19323            adj = app.maxAdj;
19324            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19325                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19326            }
19327        }
19328
19329        // Do final modification to adj.  Everything we do between here and applying
19330        // the final setAdj must be done in this function, because we will also use
19331        // it when computing the final cached adj later.  Note that we don't need to
19332        // worry about this for max adj above, since max adj will always be used to
19333        // keep it out of the cached vaues.
19334        app.curAdj = app.modifyRawOomAdj(adj);
19335        app.curSchedGroup = schedGroup;
19336        app.curProcState = procState;
19337        app.foregroundActivities = foregroundActivities;
19338
19339        return app.curRawAdj;
19340    }
19341
19342    /**
19343     * Record new PSS sample for a process.
19344     */
19345    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19346            long now) {
19347        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19348                swapPss * 1024);
19349        proc.lastPssTime = now;
19350        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19351        if (DEBUG_PSS) Slog.d(TAG_PSS,
19352                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19353                + " state=" + ProcessList.makeProcStateString(procState));
19354        if (proc.initialIdlePss == 0) {
19355            proc.initialIdlePss = pss;
19356        }
19357        proc.lastPss = pss;
19358        proc.lastSwapPss = swapPss;
19359        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19360            proc.lastCachedPss = pss;
19361            proc.lastCachedSwapPss = swapPss;
19362        }
19363
19364        final SparseArray<Pair<Long, String>> watchUids
19365                = mMemWatchProcesses.getMap().get(proc.processName);
19366        Long check = null;
19367        if (watchUids != null) {
19368            Pair<Long, String> val = watchUids.get(proc.uid);
19369            if (val == null) {
19370                val = watchUids.get(0);
19371            }
19372            if (val != null) {
19373                check = val.first;
19374            }
19375        }
19376        if (check != null) {
19377            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19378                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19379                if (!isDebuggable) {
19380                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19381                        isDebuggable = true;
19382                    }
19383                }
19384                if (isDebuggable) {
19385                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19386                    final ProcessRecord myProc = proc;
19387                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19388                    mMemWatchDumpProcName = proc.processName;
19389                    mMemWatchDumpFile = heapdumpFile.toString();
19390                    mMemWatchDumpPid = proc.pid;
19391                    mMemWatchDumpUid = proc.uid;
19392                    BackgroundThread.getHandler().post(new Runnable() {
19393                        @Override
19394                        public void run() {
19395                            revokeUriPermission(ActivityThread.currentActivityThread()
19396                                            .getApplicationThread(),
19397                                    DumpHeapActivity.JAVA_URI,
19398                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19399                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19400                                    UserHandle.myUserId());
19401                            ParcelFileDescriptor fd = null;
19402                            try {
19403                                heapdumpFile.delete();
19404                                fd = ParcelFileDescriptor.open(heapdumpFile,
19405                                        ParcelFileDescriptor.MODE_CREATE |
19406                                                ParcelFileDescriptor.MODE_TRUNCATE |
19407                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19408                                                ParcelFileDescriptor.MODE_APPEND);
19409                                IApplicationThread thread = myProc.thread;
19410                                if (thread != null) {
19411                                    try {
19412                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19413                                                "Requesting dump heap from "
19414                                                + myProc + " to " + heapdumpFile);
19415                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19416                                    } catch (RemoteException e) {
19417                                    }
19418                                }
19419                            } catch (FileNotFoundException e) {
19420                                e.printStackTrace();
19421                            } finally {
19422                                if (fd != null) {
19423                                    try {
19424                                        fd.close();
19425                                    } catch (IOException e) {
19426                                    }
19427                                }
19428                            }
19429                        }
19430                    });
19431                } else {
19432                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19433                            + ", but debugging not enabled");
19434                }
19435            }
19436        }
19437    }
19438
19439    /**
19440     * Schedule PSS collection of a process.
19441     */
19442    void requestPssLocked(ProcessRecord proc, int procState) {
19443        if (mPendingPssProcesses.contains(proc)) {
19444            return;
19445        }
19446        if (mPendingPssProcesses.size() == 0) {
19447            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19448        }
19449        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19450        proc.pssProcState = procState;
19451        mPendingPssProcesses.add(proc);
19452    }
19453
19454    /**
19455     * Schedule PSS collection of all processes.
19456     */
19457    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19458        if (!always) {
19459            if (now < (mLastFullPssTime +
19460                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19461                return;
19462            }
19463        }
19464        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19465        mLastFullPssTime = now;
19466        mFullPssPending = true;
19467        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19468        mPendingPssProcesses.clear();
19469        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19470            ProcessRecord app = mLruProcesses.get(i);
19471            if (app.thread == null
19472                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19473                continue;
19474            }
19475            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19476                app.pssProcState = app.setProcState;
19477                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19478                        mTestPssMode, isSleeping(), now);
19479                mPendingPssProcesses.add(app);
19480            }
19481        }
19482        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19483    }
19484
19485    public void setTestPssMode(boolean enabled) {
19486        synchronized (this) {
19487            mTestPssMode = enabled;
19488            if (enabled) {
19489                // Whenever we enable the mode, we want to take a snapshot all of current
19490                // process mem use.
19491                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19492            }
19493        }
19494    }
19495
19496    /**
19497     * Ask a given process to GC right now.
19498     */
19499    final void performAppGcLocked(ProcessRecord app) {
19500        try {
19501            app.lastRequestedGc = SystemClock.uptimeMillis();
19502            if (app.thread != null) {
19503                if (app.reportLowMemory) {
19504                    app.reportLowMemory = false;
19505                    app.thread.scheduleLowMemory();
19506                } else {
19507                    app.thread.processInBackground();
19508                }
19509            }
19510        } catch (Exception e) {
19511            // whatever.
19512        }
19513    }
19514
19515    /**
19516     * Returns true if things are idle enough to perform GCs.
19517     */
19518    private final boolean canGcNowLocked() {
19519        boolean processingBroadcasts = false;
19520        for (BroadcastQueue q : mBroadcastQueues) {
19521            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19522                processingBroadcasts = true;
19523            }
19524        }
19525        return !processingBroadcasts
19526                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19527    }
19528
19529    /**
19530     * Perform GCs on all processes that are waiting for it, but only
19531     * if things are idle.
19532     */
19533    final void performAppGcsLocked() {
19534        final int N = mProcessesToGc.size();
19535        if (N <= 0) {
19536            return;
19537        }
19538        if (canGcNowLocked()) {
19539            while (mProcessesToGc.size() > 0) {
19540                ProcessRecord proc = mProcessesToGc.remove(0);
19541                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19542                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19543                            <= SystemClock.uptimeMillis()) {
19544                        // To avoid spamming the system, we will GC processes one
19545                        // at a time, waiting a few seconds between each.
19546                        performAppGcLocked(proc);
19547                        scheduleAppGcsLocked();
19548                        return;
19549                    } else {
19550                        // It hasn't been long enough since we last GCed this
19551                        // process...  put it in the list to wait for its time.
19552                        addProcessToGcListLocked(proc);
19553                        break;
19554                    }
19555                }
19556            }
19557
19558            scheduleAppGcsLocked();
19559        }
19560    }
19561
19562    /**
19563     * If all looks good, perform GCs on all processes waiting for them.
19564     */
19565    final void performAppGcsIfAppropriateLocked() {
19566        if (canGcNowLocked()) {
19567            performAppGcsLocked();
19568            return;
19569        }
19570        // Still not idle, wait some more.
19571        scheduleAppGcsLocked();
19572    }
19573
19574    /**
19575     * Schedule the execution of all pending app GCs.
19576     */
19577    final void scheduleAppGcsLocked() {
19578        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19579
19580        if (mProcessesToGc.size() > 0) {
19581            // Schedule a GC for the time to the next process.
19582            ProcessRecord proc = mProcessesToGc.get(0);
19583            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19584
19585            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19586            long now = SystemClock.uptimeMillis();
19587            if (when < (now+GC_TIMEOUT)) {
19588                when = now + GC_TIMEOUT;
19589            }
19590            mHandler.sendMessageAtTime(msg, when);
19591        }
19592    }
19593
19594    /**
19595     * Add a process to the array of processes waiting to be GCed.  Keeps the
19596     * list in sorted order by the last GC time.  The process can't already be
19597     * on the list.
19598     */
19599    final void addProcessToGcListLocked(ProcessRecord proc) {
19600        boolean added = false;
19601        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19602            if (mProcessesToGc.get(i).lastRequestedGc <
19603                    proc.lastRequestedGc) {
19604                added = true;
19605                mProcessesToGc.add(i+1, proc);
19606                break;
19607            }
19608        }
19609        if (!added) {
19610            mProcessesToGc.add(0, proc);
19611        }
19612    }
19613
19614    /**
19615     * Set up to ask a process to GC itself.  This will either do it
19616     * immediately, or put it on the list of processes to gc the next
19617     * time things are idle.
19618     */
19619    final void scheduleAppGcLocked(ProcessRecord app) {
19620        long now = SystemClock.uptimeMillis();
19621        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19622            return;
19623        }
19624        if (!mProcessesToGc.contains(app)) {
19625            addProcessToGcListLocked(app);
19626            scheduleAppGcsLocked();
19627        }
19628    }
19629
19630    final void checkExcessivePowerUsageLocked(boolean doKills) {
19631        updateCpuStatsNow();
19632
19633        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19634        boolean doWakeKills = doKills;
19635        boolean doCpuKills = doKills;
19636        if (mLastPowerCheckRealtime == 0) {
19637            doWakeKills = false;
19638        }
19639        if (mLastPowerCheckUptime == 0) {
19640            doCpuKills = false;
19641        }
19642        if (stats.isScreenOn()) {
19643            doWakeKills = false;
19644        }
19645        final long curRealtime = SystemClock.elapsedRealtime();
19646        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19647        final long curUptime = SystemClock.uptimeMillis();
19648        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19649        mLastPowerCheckRealtime = curRealtime;
19650        mLastPowerCheckUptime = curUptime;
19651        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19652            doWakeKills = false;
19653        }
19654        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19655            doCpuKills = false;
19656        }
19657        int i = mLruProcesses.size();
19658        while (i > 0) {
19659            i--;
19660            ProcessRecord app = mLruProcesses.get(i);
19661            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19662                long wtime;
19663                synchronized (stats) {
19664                    wtime = stats.getProcessWakeTime(app.info.uid,
19665                            app.pid, curRealtime);
19666                }
19667                long wtimeUsed = wtime - app.lastWakeTime;
19668                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19669                if (DEBUG_POWER) {
19670                    StringBuilder sb = new StringBuilder(128);
19671                    sb.append("Wake for ");
19672                    app.toShortString(sb);
19673                    sb.append(": over ");
19674                    TimeUtils.formatDuration(realtimeSince, sb);
19675                    sb.append(" used ");
19676                    TimeUtils.formatDuration(wtimeUsed, sb);
19677                    sb.append(" (");
19678                    sb.append((wtimeUsed*100)/realtimeSince);
19679                    sb.append("%)");
19680                    Slog.i(TAG_POWER, sb.toString());
19681                    sb.setLength(0);
19682                    sb.append("CPU for ");
19683                    app.toShortString(sb);
19684                    sb.append(": over ");
19685                    TimeUtils.formatDuration(uptimeSince, sb);
19686                    sb.append(" used ");
19687                    TimeUtils.formatDuration(cputimeUsed, sb);
19688                    sb.append(" (");
19689                    sb.append((cputimeUsed*100)/uptimeSince);
19690                    sb.append("%)");
19691                    Slog.i(TAG_POWER, sb.toString());
19692                }
19693                // If a process has held a wake lock for more
19694                // than 50% of the time during this period,
19695                // that sounds bad.  Kill!
19696                if (doWakeKills && realtimeSince > 0
19697                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19698                    synchronized (stats) {
19699                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19700                                realtimeSince, wtimeUsed);
19701                    }
19702                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19703                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19704                } else if (doCpuKills && uptimeSince > 0
19705                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19706                    synchronized (stats) {
19707                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19708                                uptimeSince, cputimeUsed);
19709                    }
19710                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19711                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19712                } else {
19713                    app.lastWakeTime = wtime;
19714                    app.lastCpuTime = app.curCpuTime;
19715                }
19716            }
19717        }
19718    }
19719
19720    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19721            long nowElapsed) {
19722        boolean success = true;
19723
19724        if (app.curRawAdj != app.setRawAdj) {
19725            app.setRawAdj = app.curRawAdj;
19726        }
19727
19728        int changes = 0;
19729
19730        if (app.curAdj != app.setAdj) {
19731            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19732            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19733                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19734                    + app.adjType);
19735            app.setAdj = app.curAdj;
19736        }
19737
19738        if (app.setSchedGroup != app.curSchedGroup) {
19739            app.setSchedGroup = app.curSchedGroup;
19740            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19741                    "Setting sched group of " + app.processName
19742                    + " to " + app.curSchedGroup);
19743            if (app.waitingToKill != null && app.curReceiver == null
19744                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19745                app.kill(app.waitingToKill, true);
19746                success = false;
19747            } else {
19748                int processGroup;
19749                switch (app.curSchedGroup) {
19750                    case ProcessList.SCHED_GROUP_BACKGROUND:
19751                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19752                        break;
19753                    case ProcessList.SCHED_GROUP_TOP_APP:
19754                        processGroup = Process.THREAD_GROUP_TOP_APP;
19755                        break;
19756                    default:
19757                        processGroup = Process.THREAD_GROUP_DEFAULT;
19758                        break;
19759                }
19760                if (true) {
19761                    long oldId = Binder.clearCallingIdentity();
19762                    try {
19763                        Process.setProcessGroup(app.pid, processGroup);
19764                    } catch (Exception e) {
19765                        Slog.w(TAG, "Failed setting process group of " + app.pid
19766                                + " to " + app.curSchedGroup);
19767                        e.printStackTrace();
19768                    } finally {
19769                        Binder.restoreCallingIdentity(oldId);
19770                    }
19771                } else {
19772                    if (app.thread != null) {
19773                        try {
19774                            app.thread.setSchedulingGroup(processGroup);
19775                        } catch (RemoteException e) {
19776                        }
19777                    }
19778                }
19779            }
19780        }
19781        if (app.repForegroundActivities != app.foregroundActivities) {
19782            app.repForegroundActivities = app.foregroundActivities;
19783            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19784        }
19785        if (app.repProcState != app.curProcState) {
19786            app.repProcState = app.curProcState;
19787            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19788            if (app.thread != null) {
19789                try {
19790                    if (false) {
19791                        //RuntimeException h = new RuntimeException("here");
19792                        Slog.i(TAG, "Sending new process state " + app.repProcState
19793                                + " to " + app /*, h*/);
19794                    }
19795                    app.thread.setProcessState(app.repProcState);
19796                } catch (RemoteException e) {
19797                }
19798            }
19799        }
19800        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19801                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19802            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19803                // Experimental code to more aggressively collect pss while
19804                // running test...  the problem is that this tends to collect
19805                // the data right when a process is transitioning between process
19806                // states, which well tend to give noisy data.
19807                long start = SystemClock.uptimeMillis();
19808                long pss = Debug.getPss(app.pid, mTmpLong, null);
19809                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19810                mPendingPssProcesses.remove(app);
19811                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19812                        + " to " + app.curProcState + ": "
19813                        + (SystemClock.uptimeMillis()-start) + "ms");
19814            }
19815            app.lastStateTime = now;
19816            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19817                    mTestPssMode, isSleeping(), now);
19818            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19819                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19820                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19821                    + (app.nextPssTime-now) + ": " + app);
19822        } else {
19823            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19824                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19825                    mTestPssMode)))) {
19826                requestPssLocked(app, app.setProcState);
19827                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19828                        mTestPssMode, isSleeping(), now);
19829            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19830                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19831        }
19832        if (app.setProcState != app.curProcState) {
19833            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19834                    "Proc state change of " + app.processName
19835                            + " to " + app.curProcState);
19836            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19837            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19838            if (setImportant && !curImportant) {
19839                // This app is no longer something we consider important enough to allow to
19840                // use arbitrary amounts of battery power.  Note
19841                // its current wake lock time to later know to kill it if
19842                // it is not behaving well.
19843                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19844                synchronized (stats) {
19845                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19846                            app.pid, nowElapsed);
19847                }
19848                app.lastCpuTime = app.curCpuTime;
19849
19850            }
19851            // Inform UsageStats of important process state change
19852            // Must be called before updating setProcState
19853            maybeUpdateUsageStatsLocked(app, nowElapsed);
19854
19855            app.setProcState = app.curProcState;
19856            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19857                app.notCachedSinceIdle = false;
19858            }
19859            if (!doingAll) {
19860                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19861            } else {
19862                app.procStateChanged = true;
19863            }
19864        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19865                > USAGE_STATS_INTERACTION_INTERVAL) {
19866            // For apps that sit around for a long time in the interactive state, we need
19867            // to report this at least once a day so they don't go idle.
19868            maybeUpdateUsageStatsLocked(app, nowElapsed);
19869        }
19870
19871        if (changes != 0) {
19872            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19873                    "Changes in " + app + ": " + changes);
19874            int i = mPendingProcessChanges.size()-1;
19875            ProcessChangeItem item = null;
19876            while (i >= 0) {
19877                item = mPendingProcessChanges.get(i);
19878                if (item.pid == app.pid) {
19879                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19880                            "Re-using existing item: " + item);
19881                    break;
19882                }
19883                i--;
19884            }
19885            if (i < 0) {
19886                // No existing item in pending changes; need a new one.
19887                final int NA = mAvailProcessChanges.size();
19888                if (NA > 0) {
19889                    item = mAvailProcessChanges.remove(NA-1);
19890                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19891                            "Retrieving available item: " + item);
19892                } else {
19893                    item = new ProcessChangeItem();
19894                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19895                            "Allocating new item: " + item);
19896                }
19897                item.changes = 0;
19898                item.pid = app.pid;
19899                item.uid = app.info.uid;
19900                if (mPendingProcessChanges.size() == 0) {
19901                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19902                            "*** Enqueueing dispatch processes changed!");
19903                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19904                }
19905                mPendingProcessChanges.add(item);
19906            }
19907            item.changes |= changes;
19908            item.processState = app.repProcState;
19909            item.foregroundActivities = app.repForegroundActivities;
19910            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19911                    "Item " + Integer.toHexString(System.identityHashCode(item))
19912                    + " " + app.toShortString() + ": changes=" + item.changes
19913                    + " procState=" + item.processState
19914                    + " foreground=" + item.foregroundActivities
19915                    + " type=" + app.adjType + " source=" + app.adjSource
19916                    + " target=" + app.adjTarget);
19917        }
19918
19919        return success;
19920    }
19921
19922    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19923        final UidRecord.ChangeItem pendingChange;
19924        if (uidRec == null || uidRec.pendingChange == null) {
19925            if (mPendingUidChanges.size() == 0) {
19926                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19927                        "*** Enqueueing dispatch uid changed!");
19928                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19929            }
19930            final int NA = mAvailUidChanges.size();
19931            if (NA > 0) {
19932                pendingChange = mAvailUidChanges.remove(NA-1);
19933                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19934                        "Retrieving available item: " + pendingChange);
19935            } else {
19936                pendingChange = new UidRecord.ChangeItem();
19937                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19938                        "Allocating new item: " + pendingChange);
19939            }
19940            if (uidRec != null) {
19941                uidRec.pendingChange = pendingChange;
19942                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19943                    // If this uid is going away, and we haven't yet reported it is gone,
19944                    // then do so now.
19945                    change = UidRecord.CHANGE_GONE_IDLE;
19946                }
19947            } else if (uid < 0) {
19948                throw new IllegalArgumentException("No UidRecord or uid");
19949            }
19950            pendingChange.uidRecord = uidRec;
19951            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19952            mPendingUidChanges.add(pendingChange);
19953        } else {
19954            pendingChange = uidRec.pendingChange;
19955            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19956                change = UidRecord.CHANGE_GONE_IDLE;
19957            }
19958        }
19959        pendingChange.change = change;
19960        pendingChange.processState = uidRec != null
19961                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19962    }
19963
19964    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19965            String authority) {
19966        if (app == null) return;
19967        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19968            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19969            if (userState == null) return;
19970            final long now = SystemClock.elapsedRealtime();
19971            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19972            if (lastReported == null || lastReported < now - 60 * 1000L) {
19973                mUsageStatsService.reportContentProviderUsage(
19974                        authority, providerPkgName, app.userId);
19975                userState.mProviderLastReportedFg.put(authority, now);
19976            }
19977        }
19978    }
19979
19980    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19981        if (DEBUG_USAGE_STATS) {
19982            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19983                    + "] state changes: old = " + app.setProcState + ", new = "
19984                    + app.curProcState);
19985        }
19986        if (mUsageStatsService == null) {
19987            return;
19988        }
19989        boolean isInteraction;
19990        // To avoid some abuse patterns, we are going to be careful about what we consider
19991        // to be an app interaction.  Being the top activity doesn't count while the display
19992        // is sleeping, nor do short foreground services.
19993        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19994            isInteraction = true;
19995            app.fgInteractionTime = 0;
19996        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19997            if (app.fgInteractionTime == 0) {
19998                app.fgInteractionTime = nowElapsed;
19999                isInteraction = false;
20000            } else {
20001                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20002            }
20003        } else {
20004            isInteraction = app.curProcState
20005                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20006            app.fgInteractionTime = 0;
20007        }
20008        if (isInteraction && (!app.reportedInteraction
20009                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20010            app.interactionEventTime = nowElapsed;
20011            String[] packages = app.getPackageList();
20012            if (packages != null) {
20013                for (int i = 0; i < packages.length; i++) {
20014                    mUsageStatsService.reportEvent(packages[i], app.userId,
20015                            UsageEvents.Event.SYSTEM_INTERACTION);
20016                }
20017            }
20018        }
20019        app.reportedInteraction = isInteraction;
20020        if (!isInteraction) {
20021            app.interactionEventTime = 0;
20022        }
20023    }
20024
20025    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20026        if (proc.thread != null) {
20027            if (proc.baseProcessTracker != null) {
20028                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20029            }
20030        }
20031    }
20032
20033    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20034            ProcessRecord TOP_APP, boolean doingAll, long now) {
20035        if (app.thread == null) {
20036            return false;
20037        }
20038
20039        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20040
20041        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20042    }
20043
20044    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20045            boolean oomAdj) {
20046        if (isForeground != proc.foregroundServices) {
20047            proc.foregroundServices = isForeground;
20048            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20049                    proc.info.uid);
20050            if (isForeground) {
20051                if (curProcs == null) {
20052                    curProcs = new ArrayList<ProcessRecord>();
20053                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20054                }
20055                if (!curProcs.contains(proc)) {
20056                    curProcs.add(proc);
20057                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20058                            proc.info.packageName, proc.info.uid);
20059                }
20060            } else {
20061                if (curProcs != null) {
20062                    if (curProcs.remove(proc)) {
20063                        mBatteryStatsService.noteEvent(
20064                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20065                                proc.info.packageName, proc.info.uid);
20066                        if (curProcs.size() <= 0) {
20067                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20068                        }
20069                    }
20070                }
20071            }
20072            if (oomAdj) {
20073                updateOomAdjLocked();
20074            }
20075        }
20076    }
20077
20078    private final ActivityRecord resumedAppLocked() {
20079        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20080        String pkg;
20081        int uid;
20082        if (act != null) {
20083            pkg = act.packageName;
20084            uid = act.info.applicationInfo.uid;
20085        } else {
20086            pkg = null;
20087            uid = -1;
20088        }
20089        // Has the UID or resumed package name changed?
20090        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20091                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20092            if (mCurResumedPackage != null) {
20093                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20094                        mCurResumedPackage, mCurResumedUid);
20095            }
20096            mCurResumedPackage = pkg;
20097            mCurResumedUid = uid;
20098            if (mCurResumedPackage != null) {
20099                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20100                        mCurResumedPackage, mCurResumedUid);
20101            }
20102        }
20103        return act;
20104    }
20105
20106    final boolean updateOomAdjLocked(ProcessRecord app) {
20107        final ActivityRecord TOP_ACT = resumedAppLocked();
20108        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20109        final boolean wasCached = app.cached;
20110
20111        mAdjSeq++;
20112
20113        // This is the desired cached adjusment we want to tell it to use.
20114        // If our app is currently cached, we know it, and that is it.  Otherwise,
20115        // we don't know it yet, and it needs to now be cached we will then
20116        // need to do a complete oom adj.
20117        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20118                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20119        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20120                SystemClock.uptimeMillis());
20121        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20122            // Changed to/from cached state, so apps after it in the LRU
20123            // list may also be changed.
20124            updateOomAdjLocked();
20125        }
20126        return success;
20127    }
20128
20129    final void updateOomAdjLocked() {
20130        final ActivityRecord TOP_ACT = resumedAppLocked();
20131        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20132        final long now = SystemClock.uptimeMillis();
20133        final long nowElapsed = SystemClock.elapsedRealtime();
20134        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20135        final int N = mLruProcesses.size();
20136
20137        if (false) {
20138            RuntimeException e = new RuntimeException();
20139            e.fillInStackTrace();
20140            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20141        }
20142
20143        // Reset state in all uid records.
20144        for (int i=mActiveUids.size()-1; i>=0; i--) {
20145            final UidRecord uidRec = mActiveUids.valueAt(i);
20146            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20147                    "Starting update of " + uidRec);
20148            uidRec.reset();
20149        }
20150
20151        mStackSupervisor.rankTaskLayersIfNeeded();
20152
20153        mAdjSeq++;
20154        mNewNumServiceProcs = 0;
20155        mNewNumAServiceProcs = 0;
20156
20157        final int emptyProcessLimit;
20158        final int cachedProcessLimit;
20159        if (mProcessLimit <= 0) {
20160            emptyProcessLimit = cachedProcessLimit = 0;
20161        } else if (mProcessLimit == 1) {
20162            emptyProcessLimit = 1;
20163            cachedProcessLimit = 0;
20164        } else {
20165            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20166            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20167        }
20168
20169        // Let's determine how many processes we have running vs.
20170        // how many slots we have for background processes; we may want
20171        // to put multiple processes in a slot of there are enough of
20172        // them.
20173        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20174                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20175        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20176        if (numEmptyProcs > cachedProcessLimit) {
20177            // If there are more empty processes than our limit on cached
20178            // processes, then use the cached process limit for the factor.
20179            // This ensures that the really old empty processes get pushed
20180            // down to the bottom, so if we are running low on memory we will
20181            // have a better chance at keeping around more cached processes
20182            // instead of a gazillion empty processes.
20183            numEmptyProcs = cachedProcessLimit;
20184        }
20185        int emptyFactor = numEmptyProcs/numSlots;
20186        if (emptyFactor < 1) emptyFactor = 1;
20187        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20188        if (cachedFactor < 1) cachedFactor = 1;
20189        int stepCached = 0;
20190        int stepEmpty = 0;
20191        int numCached = 0;
20192        int numEmpty = 0;
20193        int numTrimming = 0;
20194
20195        mNumNonCachedProcs = 0;
20196        mNumCachedHiddenProcs = 0;
20197
20198        // First update the OOM adjustment for each of the
20199        // application processes based on their current state.
20200        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20201        int nextCachedAdj = curCachedAdj+1;
20202        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20203        int nextEmptyAdj = curEmptyAdj+2;
20204        for (int i=N-1; i>=0; i--) {
20205            ProcessRecord app = mLruProcesses.get(i);
20206            if (!app.killedByAm && app.thread != null) {
20207                app.procStateChanged = false;
20208                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20209
20210                // If we haven't yet assigned the final cached adj
20211                // to the process, do that now.
20212                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20213                    switch (app.curProcState) {
20214                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20215                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20216                            // This process is a cached process holding activities...
20217                            // assign it the next cached value for that type, and then
20218                            // step that cached level.
20219                            app.curRawAdj = curCachedAdj;
20220                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20221                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20222                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20223                                    + ")");
20224                            if (curCachedAdj != nextCachedAdj) {
20225                                stepCached++;
20226                                if (stepCached >= cachedFactor) {
20227                                    stepCached = 0;
20228                                    curCachedAdj = nextCachedAdj;
20229                                    nextCachedAdj += 2;
20230                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20231                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20232                                    }
20233                                }
20234                            }
20235                            break;
20236                        default:
20237                            // For everything else, assign next empty cached process
20238                            // level and bump that up.  Note that this means that
20239                            // long-running services that have dropped down to the
20240                            // cached level will be treated as empty (since their process
20241                            // state is still as a service), which is what we want.
20242                            app.curRawAdj = curEmptyAdj;
20243                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20244                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20245                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20246                                    + ")");
20247                            if (curEmptyAdj != nextEmptyAdj) {
20248                                stepEmpty++;
20249                                if (stepEmpty >= emptyFactor) {
20250                                    stepEmpty = 0;
20251                                    curEmptyAdj = nextEmptyAdj;
20252                                    nextEmptyAdj += 2;
20253                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20254                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20255                                    }
20256                                }
20257                            }
20258                            break;
20259                    }
20260                }
20261
20262                applyOomAdjLocked(app, true, now, nowElapsed);
20263
20264                // Count the number of process types.
20265                switch (app.curProcState) {
20266                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20267                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20268                        mNumCachedHiddenProcs++;
20269                        numCached++;
20270                        if (numCached > cachedProcessLimit) {
20271                            app.kill("cached #" + numCached, true);
20272                        }
20273                        break;
20274                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20275                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20276                                && app.lastActivityTime < oldTime) {
20277                            app.kill("empty for "
20278                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20279                                    / 1000) + "s", true);
20280                        } else {
20281                            numEmpty++;
20282                            if (numEmpty > emptyProcessLimit) {
20283                                app.kill("empty #" + numEmpty, true);
20284                            }
20285                        }
20286                        break;
20287                    default:
20288                        mNumNonCachedProcs++;
20289                        break;
20290                }
20291
20292                if (app.isolated && app.services.size() <= 0) {
20293                    // If this is an isolated process, and there are no
20294                    // services running in it, then the process is no longer
20295                    // needed.  We agressively kill these because we can by
20296                    // definition not re-use the same process again, and it is
20297                    // good to avoid having whatever code was running in them
20298                    // left sitting around after no longer needed.
20299                    app.kill("isolated not needed", true);
20300                } else {
20301                    // Keeping this process, update its uid.
20302                    final UidRecord uidRec = app.uidRecord;
20303                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20304                        uidRec.curProcState = app.curProcState;
20305                    }
20306                }
20307
20308                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20309                        && !app.killedByAm) {
20310                    numTrimming++;
20311                }
20312            }
20313        }
20314
20315        mNumServiceProcs = mNewNumServiceProcs;
20316
20317        // Now determine the memory trimming level of background processes.
20318        // Unfortunately we need to start at the back of the list to do this
20319        // properly.  We only do this if the number of background apps we
20320        // are managing to keep around is less than half the maximum we desire;
20321        // if we are keeping a good number around, we'll let them use whatever
20322        // memory they want.
20323        final int numCachedAndEmpty = numCached + numEmpty;
20324        int memFactor;
20325        if (numCached <= ProcessList.TRIM_CACHED_APPS
20326                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20327            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20328                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20329            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20330                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20331            } else {
20332                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20333            }
20334        } else {
20335            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20336        }
20337        // We always allow the memory level to go up (better).  We only allow it to go
20338        // down if we are in a state where that is allowed, *and* the total number of processes
20339        // has gone down since last time.
20340        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20341                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20342                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20343        if (memFactor > mLastMemoryLevel) {
20344            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20345                memFactor = mLastMemoryLevel;
20346                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20347            }
20348        }
20349        if (memFactor != mLastMemoryLevel) {
20350            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20351        }
20352        mLastMemoryLevel = memFactor;
20353        mLastNumProcesses = mLruProcesses.size();
20354        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20355        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20356        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20357            if (mLowRamStartTime == 0) {
20358                mLowRamStartTime = now;
20359            }
20360            int step = 0;
20361            int fgTrimLevel;
20362            switch (memFactor) {
20363                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20364                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20365                    break;
20366                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20367                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20368                    break;
20369                default:
20370                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20371                    break;
20372            }
20373            int factor = numTrimming/3;
20374            int minFactor = 2;
20375            if (mHomeProcess != null) minFactor++;
20376            if (mPreviousProcess != null) minFactor++;
20377            if (factor < minFactor) factor = minFactor;
20378            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20379            for (int i=N-1; i>=0; i--) {
20380                ProcessRecord app = mLruProcesses.get(i);
20381                if (allChanged || app.procStateChanged) {
20382                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20383                    app.procStateChanged = false;
20384                }
20385                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20386                        && !app.killedByAm) {
20387                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20388                        try {
20389                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20390                                    "Trimming memory of " + app.processName + " to " + curLevel);
20391                            app.thread.scheduleTrimMemory(curLevel);
20392                        } catch (RemoteException e) {
20393                        }
20394                        if (false) {
20395                            // For now we won't do this; our memory trimming seems
20396                            // to be good enough at this point that destroying
20397                            // activities causes more harm than good.
20398                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20399                                    && app != mHomeProcess && app != mPreviousProcess) {
20400                                // Need to do this on its own message because the stack may not
20401                                // be in a consistent state at this point.
20402                                // For these apps we will also finish their activities
20403                                // to help them free memory.
20404                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20405                            }
20406                        }
20407                    }
20408                    app.trimMemoryLevel = curLevel;
20409                    step++;
20410                    if (step >= factor) {
20411                        step = 0;
20412                        switch (curLevel) {
20413                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20414                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20415                                break;
20416                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20417                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20418                                break;
20419                        }
20420                    }
20421                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20422                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20423                            && app.thread != null) {
20424                        try {
20425                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20426                                    "Trimming memory of heavy-weight " + app.processName
20427                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20428                            app.thread.scheduleTrimMemory(
20429                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20430                        } catch (RemoteException e) {
20431                        }
20432                    }
20433                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20434                } else {
20435                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20436                            || app.systemNoUi) && app.pendingUiClean) {
20437                        // If this application is now in the background and it
20438                        // had done UI, then give it the special trim level to
20439                        // have it free UI resources.
20440                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20441                        if (app.trimMemoryLevel < level && app.thread != null) {
20442                            try {
20443                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20444                                        "Trimming memory of bg-ui " + app.processName
20445                                        + " to " + level);
20446                                app.thread.scheduleTrimMemory(level);
20447                            } catch (RemoteException e) {
20448                            }
20449                        }
20450                        app.pendingUiClean = false;
20451                    }
20452                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20453                        try {
20454                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20455                                    "Trimming memory of fg " + app.processName
20456                                    + " to " + fgTrimLevel);
20457                            app.thread.scheduleTrimMemory(fgTrimLevel);
20458                        } catch (RemoteException e) {
20459                        }
20460                    }
20461                    app.trimMemoryLevel = fgTrimLevel;
20462                }
20463            }
20464        } else {
20465            if (mLowRamStartTime != 0) {
20466                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20467                mLowRamStartTime = 0;
20468            }
20469            for (int i=N-1; i>=0; i--) {
20470                ProcessRecord app = mLruProcesses.get(i);
20471                if (allChanged || app.procStateChanged) {
20472                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20473                    app.procStateChanged = false;
20474                }
20475                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20476                        || app.systemNoUi) && app.pendingUiClean) {
20477                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20478                            && app.thread != null) {
20479                        try {
20480                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20481                                    "Trimming memory of ui hidden " + app.processName
20482                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20483                            app.thread.scheduleTrimMemory(
20484                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20485                        } catch (RemoteException e) {
20486                        }
20487                    }
20488                    app.pendingUiClean = false;
20489                }
20490                app.trimMemoryLevel = 0;
20491            }
20492        }
20493
20494        if (mAlwaysFinishActivities) {
20495            // Need to do this on its own message because the stack may not
20496            // be in a consistent state at this point.
20497            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20498        }
20499
20500        if (allChanged) {
20501            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20502        }
20503
20504        // Update from any uid changes.
20505        for (int i=mActiveUids.size()-1; i>=0; i--) {
20506            final UidRecord uidRec = mActiveUids.valueAt(i);
20507            int uidChange = UidRecord.CHANGE_PROCSTATE;
20508            if (uidRec.setProcState != uidRec.curProcState) {
20509                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20510                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20511                        + " to " + uidRec.curProcState);
20512                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20513                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20514                        uidRec.lastBackgroundTime = nowElapsed;
20515                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20516                            // Note: the background settle time is in elapsed realtime, while
20517                            // the handler time base is uptime.  All this means is that we may
20518                            // stop background uids later than we had intended, but that only
20519                            // happens because the device was sleeping so we are okay anyway.
20520                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20521                        }
20522                    }
20523                } else {
20524                    if (uidRec.idle) {
20525                        uidChange = UidRecord.CHANGE_ACTIVE;
20526                        uidRec.idle = false;
20527                    }
20528                    uidRec.lastBackgroundTime = 0;
20529                }
20530                uidRec.setProcState = uidRec.curProcState;
20531                enqueueUidChangeLocked(uidRec, -1, uidChange);
20532                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20533            }
20534        }
20535
20536        if (mProcessStats.shouldWriteNowLocked(now)) {
20537            mHandler.post(new Runnable() {
20538                @Override public void run() {
20539                    synchronized (ActivityManagerService.this) {
20540                        mProcessStats.writeStateAsyncLocked();
20541                    }
20542                }
20543            });
20544        }
20545
20546        if (DEBUG_OOM_ADJ) {
20547            final long duration = SystemClock.uptimeMillis() - now;
20548            if (false) {
20549                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20550                        new RuntimeException("here").fillInStackTrace());
20551            } else {
20552                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20553            }
20554        }
20555    }
20556
20557    final void idleUids() {
20558        synchronized (this) {
20559            final long nowElapsed = SystemClock.elapsedRealtime();
20560            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20561            long nextTime = 0;
20562            for (int i=mActiveUids.size()-1; i>=0; i--) {
20563                final UidRecord uidRec = mActiveUids.valueAt(i);
20564                final long bgTime = uidRec.lastBackgroundTime;
20565                if (bgTime > 0 && !uidRec.idle) {
20566                    if (bgTime <= maxBgTime) {
20567                        uidRec.idle = true;
20568                        doStopUidLocked(uidRec.uid, uidRec);
20569                    } else {
20570                        if (nextTime == 0 || nextTime > bgTime) {
20571                            nextTime = bgTime;
20572                        }
20573                    }
20574                }
20575            }
20576            if (nextTime > 0) {
20577                mHandler.removeMessages(IDLE_UIDS_MSG);
20578                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20579                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20580            }
20581        }
20582    }
20583
20584    final void runInBackgroundDisabled(int uid) {
20585        synchronized (this) {
20586            UidRecord uidRec = mActiveUids.get(uid);
20587            if (uidRec != null) {
20588                // This uid is actually running...  should it be considered background now?
20589                if (uidRec.idle) {
20590                    doStopUidLocked(uidRec.uid, uidRec);
20591                }
20592            } else {
20593                // This uid isn't actually running...  still send a report about it being "stopped".
20594                doStopUidLocked(uid, null);
20595            }
20596        }
20597    }
20598
20599    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20600        mServices.stopInBackgroundLocked(uid);
20601        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20602    }
20603
20604    final void trimApplications() {
20605        synchronized (this) {
20606            int i;
20607
20608            // First remove any unused application processes whose package
20609            // has been removed.
20610            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20611                final ProcessRecord app = mRemovedProcesses.get(i);
20612                if (app.activities.size() == 0
20613                        && app.curReceiver == null && app.services.size() == 0) {
20614                    Slog.i(
20615                        TAG, "Exiting empty application process "
20616                        + app.toShortString() + " ("
20617                        + (app.thread != null ? app.thread.asBinder() : null)
20618                        + ")\n");
20619                    if (app.pid > 0 && app.pid != MY_PID) {
20620                        app.kill("empty", false);
20621                    } else {
20622                        try {
20623                            app.thread.scheduleExit();
20624                        } catch (Exception e) {
20625                            // Ignore exceptions.
20626                        }
20627                    }
20628                    cleanUpApplicationRecordLocked(app, false, true, -1);
20629                    mRemovedProcesses.remove(i);
20630
20631                    if (app.persistent) {
20632                        addAppLocked(app.info, false, null /* ABI override */);
20633                    }
20634                }
20635            }
20636
20637            // Now update the oom adj for all processes.
20638            updateOomAdjLocked();
20639        }
20640    }
20641
20642    /** This method sends the specified signal to each of the persistent apps */
20643    public void signalPersistentProcesses(int sig) throws RemoteException {
20644        if (sig != Process.SIGNAL_USR1) {
20645            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20646        }
20647
20648        synchronized (this) {
20649            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20650                    != PackageManager.PERMISSION_GRANTED) {
20651                throw new SecurityException("Requires permission "
20652                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20653            }
20654
20655            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20656                ProcessRecord r = mLruProcesses.get(i);
20657                if (r.thread != null && r.persistent) {
20658                    Process.sendSignal(r.pid, sig);
20659                }
20660            }
20661        }
20662    }
20663
20664    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20665        if (proc == null || proc == mProfileProc) {
20666            proc = mProfileProc;
20667            profileType = mProfileType;
20668            clearProfilerLocked();
20669        }
20670        if (proc == null) {
20671            return;
20672        }
20673        try {
20674            proc.thread.profilerControl(false, null, profileType);
20675        } catch (RemoteException e) {
20676            throw new IllegalStateException("Process disappeared");
20677        }
20678    }
20679
20680    private void clearProfilerLocked() {
20681        if (mProfileFd != null) {
20682            try {
20683                mProfileFd.close();
20684            } catch (IOException e) {
20685            }
20686        }
20687        mProfileApp = null;
20688        mProfileProc = null;
20689        mProfileFile = null;
20690        mProfileType = 0;
20691        mAutoStopProfiler = false;
20692        mSamplingInterval = 0;
20693    }
20694
20695    public boolean profileControl(String process, int userId, boolean start,
20696            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20697
20698        try {
20699            synchronized (this) {
20700                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20701                // its own permission.
20702                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20703                        != PackageManager.PERMISSION_GRANTED) {
20704                    throw new SecurityException("Requires permission "
20705                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20706                }
20707
20708                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20709                    throw new IllegalArgumentException("null profile info or fd");
20710                }
20711
20712                ProcessRecord proc = null;
20713                if (process != null) {
20714                    proc = findProcessLocked(process, userId, "profileControl");
20715                }
20716
20717                if (start && (proc == null || proc.thread == null)) {
20718                    throw new IllegalArgumentException("Unknown process: " + process);
20719                }
20720
20721                if (start) {
20722                    stopProfilerLocked(null, 0);
20723                    setProfileApp(proc.info, proc.processName, profilerInfo);
20724                    mProfileProc = proc;
20725                    mProfileType = profileType;
20726                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20727                    try {
20728                        fd = fd.dup();
20729                    } catch (IOException e) {
20730                        fd = null;
20731                    }
20732                    profilerInfo.profileFd = fd;
20733                    proc.thread.profilerControl(start, profilerInfo, profileType);
20734                    fd = null;
20735                    mProfileFd = null;
20736                } else {
20737                    stopProfilerLocked(proc, profileType);
20738                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20739                        try {
20740                            profilerInfo.profileFd.close();
20741                        } catch (IOException e) {
20742                        }
20743                    }
20744                }
20745
20746                return true;
20747            }
20748        } catch (RemoteException e) {
20749            throw new IllegalStateException("Process disappeared");
20750        } finally {
20751            if (profilerInfo != null && profilerInfo.profileFd != null) {
20752                try {
20753                    profilerInfo.profileFd.close();
20754                } catch (IOException e) {
20755                }
20756            }
20757        }
20758    }
20759
20760    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20761        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20762                userId, true, ALLOW_FULL_ONLY, callName, null);
20763        ProcessRecord proc = null;
20764        try {
20765            int pid = Integer.parseInt(process);
20766            synchronized (mPidsSelfLocked) {
20767                proc = mPidsSelfLocked.get(pid);
20768            }
20769        } catch (NumberFormatException e) {
20770        }
20771
20772        if (proc == null) {
20773            ArrayMap<String, SparseArray<ProcessRecord>> all
20774                    = mProcessNames.getMap();
20775            SparseArray<ProcessRecord> procs = all.get(process);
20776            if (procs != null && procs.size() > 0) {
20777                proc = procs.valueAt(0);
20778                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20779                    for (int i=1; i<procs.size(); i++) {
20780                        ProcessRecord thisProc = procs.valueAt(i);
20781                        if (thisProc.userId == userId) {
20782                            proc = thisProc;
20783                            break;
20784                        }
20785                    }
20786                }
20787            }
20788        }
20789
20790        return proc;
20791    }
20792
20793    public boolean dumpHeap(String process, int userId, boolean managed,
20794            String path, ParcelFileDescriptor fd) throws RemoteException {
20795
20796        try {
20797            synchronized (this) {
20798                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20799                // its own permission (same as profileControl).
20800                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20801                        != PackageManager.PERMISSION_GRANTED) {
20802                    throw new SecurityException("Requires permission "
20803                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20804                }
20805
20806                if (fd == null) {
20807                    throw new IllegalArgumentException("null fd");
20808                }
20809
20810                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20811                if (proc == null || proc.thread == null) {
20812                    throw new IllegalArgumentException("Unknown process: " + process);
20813                }
20814
20815                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20816                if (!isDebuggable) {
20817                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20818                        throw new SecurityException("Process not debuggable: " + proc);
20819                    }
20820                }
20821
20822                proc.thread.dumpHeap(managed, path, fd);
20823                fd = null;
20824                return true;
20825            }
20826        } catch (RemoteException e) {
20827            throw new IllegalStateException("Process disappeared");
20828        } finally {
20829            if (fd != null) {
20830                try {
20831                    fd.close();
20832                } catch (IOException e) {
20833                }
20834            }
20835        }
20836    }
20837
20838    @Override
20839    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20840            String reportPackage) {
20841        if (processName != null) {
20842            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20843                    "setDumpHeapDebugLimit()");
20844        } else {
20845            synchronized (mPidsSelfLocked) {
20846                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20847                if (proc == null) {
20848                    throw new SecurityException("No process found for calling pid "
20849                            + Binder.getCallingPid());
20850                }
20851                if (!Build.IS_DEBUGGABLE
20852                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20853                    throw new SecurityException("Not running a debuggable build");
20854                }
20855                processName = proc.processName;
20856                uid = proc.uid;
20857                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20858                    throw new SecurityException("Package " + reportPackage + " is not running in "
20859                            + proc);
20860                }
20861            }
20862        }
20863        synchronized (this) {
20864            if (maxMemSize > 0) {
20865                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20866            } else {
20867                if (uid != 0) {
20868                    mMemWatchProcesses.remove(processName, uid);
20869                } else {
20870                    mMemWatchProcesses.getMap().remove(processName);
20871                }
20872            }
20873        }
20874    }
20875
20876    @Override
20877    public void dumpHeapFinished(String path) {
20878        synchronized (this) {
20879            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20880                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20881                        + " does not match last pid " + mMemWatchDumpPid);
20882                return;
20883            }
20884            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20885                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20886                        + " does not match last path " + mMemWatchDumpFile);
20887                return;
20888            }
20889            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20890            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20891        }
20892    }
20893
20894    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20895    public void monitor() {
20896        synchronized (this) { }
20897    }
20898
20899    void onCoreSettingsChange(Bundle settings) {
20900        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20901            ProcessRecord processRecord = mLruProcesses.get(i);
20902            try {
20903                if (processRecord.thread != null) {
20904                    processRecord.thread.setCoreSettings(settings);
20905                }
20906            } catch (RemoteException re) {
20907                /* ignore */
20908            }
20909        }
20910    }
20911
20912    // Multi-user methods
20913
20914    /**
20915     * Start user, if its not already running, but don't bring it to foreground.
20916     */
20917    @Override
20918    public boolean startUserInBackground(final int userId) {
20919        return mUserController.startUser(userId, /* foreground */ false);
20920    }
20921
20922    @Override
20923    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20924        return mUserController.unlockUser(userId, token, secret, listener);
20925    }
20926
20927    @Override
20928    public boolean switchUser(final int targetUserId) {
20929        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20930        UserInfo currentUserInfo;
20931        UserInfo targetUserInfo;
20932        synchronized (this) {
20933            int currentUserId = mUserController.getCurrentUserIdLocked();
20934            currentUserInfo = mUserController.getUserInfo(currentUserId);
20935            targetUserInfo = mUserController.getUserInfo(targetUserId);
20936            if (targetUserInfo == null) {
20937                Slog.w(TAG, "No user info for user #" + targetUserId);
20938                return false;
20939            }
20940            if (!targetUserInfo.supportsSwitchTo()) {
20941                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20942                return false;
20943            }
20944            if (targetUserInfo.isManagedProfile()) {
20945                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20946                return false;
20947            }
20948            mUserController.setTargetUserIdLocked(targetUserId);
20949        }
20950        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20951        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20952        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20953        return true;
20954    }
20955
20956    void scheduleStartProfilesLocked() {
20957        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20958            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20959                    DateUtils.SECOND_IN_MILLIS);
20960        }
20961    }
20962
20963    @Override
20964    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20965        return mUserController.stopUser(userId, force, callback);
20966    }
20967
20968    @Override
20969    public UserInfo getCurrentUser() {
20970        return mUserController.getCurrentUser();
20971    }
20972
20973    @Override
20974    public boolean isUserRunning(int userId, int flags) {
20975        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20976                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20977            String msg = "Permission Denial: isUserRunning() from pid="
20978                    + Binder.getCallingPid()
20979                    + ", uid=" + Binder.getCallingUid()
20980                    + " requires " + INTERACT_ACROSS_USERS;
20981            Slog.w(TAG, msg);
20982            throw new SecurityException(msg);
20983        }
20984        synchronized (this) {
20985            return mUserController.isUserRunningLocked(userId, flags);
20986        }
20987    }
20988
20989    @Override
20990    public int[] getRunningUserIds() {
20991        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20992                != PackageManager.PERMISSION_GRANTED) {
20993            String msg = "Permission Denial: isUserRunning() from pid="
20994                    + Binder.getCallingPid()
20995                    + ", uid=" + Binder.getCallingUid()
20996                    + " requires " + INTERACT_ACROSS_USERS;
20997            Slog.w(TAG, msg);
20998            throw new SecurityException(msg);
20999        }
21000        synchronized (this) {
21001            return mUserController.getStartedUserArrayLocked();
21002        }
21003    }
21004
21005    @Override
21006    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21007        mUserController.registerUserSwitchObserver(observer);
21008    }
21009
21010    @Override
21011    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21012        mUserController.unregisterUserSwitchObserver(observer);
21013    }
21014
21015    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21016        if (info == null) return null;
21017        ApplicationInfo newInfo = new ApplicationInfo(info);
21018        newInfo.initForUser(userId);
21019        return newInfo;
21020    }
21021
21022    public boolean isUserStopped(int userId) {
21023        synchronized (this) {
21024            return mUserController.getStartedUserStateLocked(userId) == null;
21025        }
21026    }
21027
21028    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21029        if (aInfo == null
21030                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21031            return aInfo;
21032        }
21033
21034        ActivityInfo info = new ActivityInfo(aInfo);
21035        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21036        return info;
21037    }
21038
21039    private boolean processSanityChecksLocked(ProcessRecord process) {
21040        if (process == null || process.thread == null) {
21041            return false;
21042        }
21043
21044        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21045        if (!isDebuggable) {
21046            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21047                return false;
21048            }
21049        }
21050
21051        return true;
21052    }
21053
21054    public boolean startBinderTracking() throws RemoteException {
21055        synchronized (this) {
21056            mBinderTransactionTrackingEnabled = true;
21057            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21058            // permission (same as profileControl).
21059            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21060                    != PackageManager.PERMISSION_GRANTED) {
21061                throw new SecurityException("Requires permission "
21062                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21063            }
21064
21065            for (int i = 0; i < mLruProcesses.size(); i++) {
21066                ProcessRecord process = mLruProcesses.get(i);
21067                if (!processSanityChecksLocked(process)) {
21068                    continue;
21069                }
21070                try {
21071                    process.thread.startBinderTracking();
21072                } catch (RemoteException e) {
21073                    Log.v(TAG, "Process disappared");
21074                }
21075            }
21076            return true;
21077        }
21078    }
21079
21080    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21081        try {
21082            synchronized (this) {
21083                mBinderTransactionTrackingEnabled = false;
21084                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21085                // permission (same as profileControl).
21086                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21087                        != PackageManager.PERMISSION_GRANTED) {
21088                    throw new SecurityException("Requires permission "
21089                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21090                }
21091
21092                if (fd == null) {
21093                    throw new IllegalArgumentException("null fd");
21094                }
21095
21096                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21097                pw.println("Binder transaction traces for all processes.\n");
21098                for (ProcessRecord process : mLruProcesses) {
21099                    if (!processSanityChecksLocked(process)) {
21100                        continue;
21101                    }
21102
21103                    pw.println("Traces for process: " + process.processName);
21104                    pw.flush();
21105                    try {
21106                        TransferPipe tp = new TransferPipe();
21107                        try {
21108                            process.thread.stopBinderTrackingAndDump(
21109                                    tp.getWriteFd().getFileDescriptor());
21110                            tp.go(fd.getFileDescriptor());
21111                        } finally {
21112                            tp.kill();
21113                        }
21114                    } catch (IOException e) {
21115                        pw.println("Failure while dumping IPC traces from " + process +
21116                                ".  Exception: " + e);
21117                        pw.flush();
21118                    } catch (RemoteException e) {
21119                        pw.println("Got a RemoteException while dumping IPC traces from " +
21120                                process + ".  Exception: " + e);
21121                        pw.flush();
21122                    }
21123                }
21124                fd = null;
21125                return true;
21126            }
21127        } finally {
21128            if (fd != null) {
21129                try {
21130                    fd.close();
21131                } catch (IOException e) {
21132                }
21133            }
21134        }
21135    }
21136
21137    private final class LocalService extends ActivityManagerInternal {
21138        @Override
21139        public void onWakefulnessChanged(int wakefulness) {
21140            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21141        }
21142
21143        @Override
21144        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21145                String processName, String abiOverride, int uid, Runnable crashHandler) {
21146            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21147                    processName, abiOverride, uid, crashHandler);
21148        }
21149
21150        @Override
21151        public SleepToken acquireSleepToken(String tag) {
21152            Preconditions.checkNotNull(tag);
21153
21154            synchronized (ActivityManagerService.this) {
21155                SleepTokenImpl token = new SleepTokenImpl(tag);
21156                mSleepTokens.add(token);
21157                updateSleepIfNeededLocked();
21158                applyVrModeIfNeededLocked(mFocusedActivity, false);
21159                return token;
21160            }
21161        }
21162
21163        @Override
21164        public ComponentName getHomeActivityForUser(int userId) {
21165            synchronized (ActivityManagerService.this) {
21166                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21167                return homeActivity == null ? null : homeActivity.realActivity;
21168            }
21169        }
21170
21171        @Override
21172        public void onUserRemoved(int userId) {
21173            synchronized (ActivityManagerService.this) {
21174                ActivityManagerService.this.onUserStoppedLocked(userId);
21175            }
21176        }
21177
21178        @Override
21179        public void onLocalVoiceInteractionStarted(IBinder activity,
21180                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21181            synchronized (ActivityManagerService.this) {
21182                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21183                        voiceSession, voiceInteractor);
21184            }
21185        }
21186
21187        @Override
21188        public void notifyStartingWindowDrawn() {
21189            synchronized (ActivityManagerService.this) {
21190                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21191            }
21192        }
21193
21194        @Override
21195        public void notifyAppTransitionStarting(int reason) {
21196            synchronized (ActivityManagerService.this) {
21197                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21198            }
21199        }
21200
21201        @Override
21202        public void notifyAppTransitionFinished() {
21203            synchronized (ActivityManagerService.this) {
21204                mStackSupervisor.notifyAppTransitionDone();
21205            }
21206        }
21207
21208        @Override
21209        public void notifyAppTransitionCancelled() {
21210            synchronized (ActivityManagerService.this) {
21211                mStackSupervisor.notifyAppTransitionDone();
21212            }
21213        }
21214
21215        @Override
21216        public List<IBinder> getTopVisibleActivities() {
21217            synchronized (ActivityManagerService.this) {
21218                return mStackSupervisor.getTopVisibleActivities();
21219            }
21220        }
21221
21222        @Override
21223        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21224            synchronized (ActivityManagerService.this) {
21225                mStackSupervisor.setDockedStackMinimized(minimized);
21226            }
21227        }
21228
21229        @Override
21230        public void killForegroundAppsForUser(int userHandle) {
21231            synchronized (ActivityManagerService.this) {
21232                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21233                final int NP = mProcessNames.getMap().size();
21234                for (int ip = 0; ip < NP; ip++) {
21235                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21236                    final int NA = apps.size();
21237                    for (int ia = 0; ia < NA; ia++) {
21238                        final ProcessRecord app = apps.valueAt(ia);
21239                        if (app.persistent) {
21240                            // We don't kill persistent processes.
21241                            continue;
21242                        }
21243                        if (app.removed) {
21244                            procs.add(app);
21245                        } else if (app.userId == userHandle && app.foregroundActivities) {
21246                            app.removed = true;
21247                            procs.add(app);
21248                        }
21249                    }
21250                }
21251
21252                final int N = procs.size();
21253                for (int i = 0; i < N; i++) {
21254                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21255                }
21256            }
21257        }
21258    }
21259
21260    private final class SleepTokenImpl extends SleepToken {
21261        private final String mTag;
21262        private final long mAcquireTime;
21263
21264        public SleepTokenImpl(String tag) {
21265            mTag = tag;
21266            mAcquireTime = SystemClock.uptimeMillis();
21267        }
21268
21269        @Override
21270        public void release() {
21271            synchronized (ActivityManagerService.this) {
21272                if (mSleepTokens.remove(this)) {
21273                    updateSleepIfNeededLocked();
21274                }
21275            }
21276        }
21277
21278        @Override
21279        public String toString() {
21280            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21281        }
21282    }
21283
21284    /**
21285     * An implementation of IAppTask, that allows an app to manage its own tasks via
21286     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21287     * only the process that calls getAppTasks() can call the AppTask methods.
21288     */
21289    class AppTaskImpl extends IAppTask.Stub {
21290        private int mTaskId;
21291        private int mCallingUid;
21292
21293        public AppTaskImpl(int taskId, int callingUid) {
21294            mTaskId = taskId;
21295            mCallingUid = callingUid;
21296        }
21297
21298        private void checkCaller() {
21299            if (mCallingUid != Binder.getCallingUid()) {
21300                throw new SecurityException("Caller " + mCallingUid
21301                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21302            }
21303        }
21304
21305        @Override
21306        public void finishAndRemoveTask() {
21307            checkCaller();
21308
21309            synchronized (ActivityManagerService.this) {
21310                long origId = Binder.clearCallingIdentity();
21311                try {
21312                    // We remove the task from recents to preserve backwards
21313                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21314                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21315                    }
21316                } finally {
21317                    Binder.restoreCallingIdentity(origId);
21318                }
21319            }
21320        }
21321
21322        @Override
21323        public ActivityManager.RecentTaskInfo getTaskInfo() {
21324            checkCaller();
21325
21326            synchronized (ActivityManagerService.this) {
21327                long origId = Binder.clearCallingIdentity();
21328                try {
21329                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21330                    if (tr == null) {
21331                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21332                    }
21333                    return createRecentTaskInfoFromTaskRecord(tr);
21334                } finally {
21335                    Binder.restoreCallingIdentity(origId);
21336                }
21337            }
21338        }
21339
21340        @Override
21341        public void moveToFront() {
21342            checkCaller();
21343            // Will bring task to front if it already has a root activity.
21344            final long origId = Binder.clearCallingIdentity();
21345            try {
21346                synchronized (this) {
21347                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21348                }
21349            } finally {
21350                Binder.restoreCallingIdentity(origId);
21351            }
21352        }
21353
21354        @Override
21355        public int startActivity(IBinder whoThread, String callingPackage,
21356                Intent intent, String resolvedType, Bundle bOptions) {
21357            checkCaller();
21358
21359            int callingUser = UserHandle.getCallingUserId();
21360            TaskRecord tr;
21361            IApplicationThread appThread;
21362            synchronized (ActivityManagerService.this) {
21363                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21364                if (tr == null) {
21365                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21366                }
21367                appThread = ApplicationThreadNative.asInterface(whoThread);
21368                if (appThread == null) {
21369                    throw new IllegalArgumentException("Bad app thread " + appThread);
21370                }
21371            }
21372            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21373                    resolvedType, null, null, null, null, 0, 0, null, null,
21374                    null, bOptions, false, callingUser, null, tr);
21375        }
21376
21377        @Override
21378        public void setExcludeFromRecents(boolean exclude) {
21379            checkCaller();
21380
21381            synchronized (ActivityManagerService.this) {
21382                long origId = Binder.clearCallingIdentity();
21383                try {
21384                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21385                    if (tr == null) {
21386                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21387                    }
21388                    Intent intent = tr.getBaseIntent();
21389                    if (exclude) {
21390                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21391                    } else {
21392                        intent.setFlags(intent.getFlags()
21393                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21394                    }
21395                } finally {
21396                    Binder.restoreCallingIdentity(origId);
21397                }
21398            }
21399        }
21400    }
21401
21402    /**
21403     * Kill processes for the user with id userId and that depend on the package named packageName
21404     */
21405    @Override
21406    public void killPackageDependents(String packageName, int userId) {
21407        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21408        if (packageName == null) {
21409            throw new NullPointerException(
21410                    "Cannot kill the dependents of a package without its name.");
21411        }
21412
21413        long callingId = Binder.clearCallingIdentity();
21414        IPackageManager pm = AppGlobals.getPackageManager();
21415        int pkgUid = -1;
21416        try {
21417            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21418        } catch (RemoteException e) {
21419        }
21420        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21421            throw new IllegalArgumentException(
21422                    "Cannot kill dependents of non-existing package " + packageName);
21423        }
21424        try {
21425            synchronized(this) {
21426                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21427                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21428                        "dep: " + packageName);
21429            }
21430        } finally {
21431            Binder.restoreCallingIdentity(callingId);
21432        }
21433    }
21434}
21435